← Back to posts
comparison guide self-hosted · · 11 min read

git-cliff vs release-please vs auto: Best Self-Hosted Changelog Generator 2026

Compare the best self-hosted changelog generation tools in 2026 — git-cliff, release-please, and auto. Complete setup guides with Docker, configuration examples, and CI/CD integration.

OS
Editorial Team

Every software project needs a changelog. Whether you’re shipping open-source libraries, internal tools, or commercial products, your users and contributors expect to see what changed between releases. Manually writing release notes is tedious, error-prone, and inevitably falls behind.

Automated changelog generators solve this problem by parsing your Git history — commit messages, tags, pull requests, and labels — and producing structured, readable release notes. This guide compares three mature, self-hosted tools that take different approaches to the same problem.

Why Automate Your Changelog

A well-maintained changelog serves multiple audiences: end users want to know what’s new, developers need to understand what changed in a dependency, and release managers must track what shipped in each version. Writing these by hand creates friction in the release process and leads to inconsistent formatting.

Consistency across releases. Automated tools enforce the same structure, headings, and grouping conventions for every release. No more one release with bullet points and another with paragraphs.

Conventional Commits enforcement. Tools that parse Conventional Commit messages (feat:, fix:, breaking:) encourage better commit discipline across your team. The changelog becomes both a product and an incentive for good Git hygiene.

CI/CD pipeline integration. Running changelog generation as part of your build pipeline means release notes are produced at the same time as the release artifact. No one has to remember to update a file before tagging.

Zero maintenance overhead. Once configured, these tools require no ongoing effort. They read your Git history, apply your template rules, and produce output — every time.

Reduced release friction. When changelog generation is automated, the release process becomes a single command or pipeline step instead of a multi-step manual chore. This matters most for teams shipping frequently.

git-cliff: Highly Customizable Changelog Generator

git-cliff is a Rust-based changelog generator that emphasizes configurability. It reads a TOML configuration file that controls every aspect of output — from which commit types appear, to how breaking changes are highlighted, to the exact template format.

Stars: 11,747+ | Language: Rust | Last updated: April 2026

Key Features

  • TOML-based configuration with Jinja2-style templating
  • Conventional Commits parsing with customizable commit type mapping
  • Git tag-based release grouping with range selection
  • Breaking change detection and prominent highlighting
  • Multiple output formats: Markdown, plain text, JSON
  • Bump version detection (--bump flag)
  • Pre-commit and CI/CD integration

Installation

1
2
3
4
5
6
7
8
# Via cargo (Rust package manager)
cargo install git-cliff

# Via Homebrew (macOS/Linux)
brew install git-cliff

# Via Docker
docker run --rm -v "$(pwd):/app" -w /app ghcr.io/orhun/git-cliff:latest --help

Docker Compose Setup

Since git-cliff is a CLI tool, the typical Docker usage pattern mounts your repository into a container:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
version: "3.8"

services:
  changelog:
    image: ghcr.io/orhun/git-cliff:latest
    volumes:
      - .:/app
      - ./cliff.toml:/app/cliff.toml
    working_dir: /app
    command: git-cliff --config cliff.toml --output CHANGELOG.md
    environment:
      - GIT_CLIFF_TEMPLATE=/app/cliff.toml

Configuration Example

A typical cliff.toml configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[changelog]
header = """
# Changelog

All notable changes to this project will be documented in this file.
"""
body = """
{% if version %}\
    ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
    ## [Unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
    ### {{ group | upper_first }}
    {% for commit in commits %}
        - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message }}\
    {% endfor %}
{% endfor %}
"""
trim = true
footer = "<!-- generated by git-cliff -->"

[git]
conventional_commits = true
filter_unconventional = true
split_commits = false
commit_parsers = [
    { message = "^feat", group = "Features" },
    { message = "^fix", group = "Bug Fixes" },
    { message = "^doc", group = "Documentation" },
    { message = "^perf", group = "Performance" },
    { message = "^refactor", group = "Refactoring" },
    { message = "^style", group = "Style" },
    { message = "^test", group = "Testing" },
    { message = "^chore\\(release\\)", skip = true },
    { message = "^chore", group = "Miscellaneous" },
    { body = ".*security", group = "Security" },
]
filter_commits = true
tag_pattern = "v[0-9].*"
sort_commits = "oldest"

CI/CD Integration (GitHub Actions)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
name: Generate Changelog
on:
  push:
    tags:
      - "v*"

jobs:
  changelog:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Generate changelog
        uses: orhun/git-cliff-action@v3
        with:
          config: cliff.toml
          args: --verbose
        env:
          OUTPUT: CHANGELOG.md
      - name: Commit changelog
        run: |
          git config user.name "github-actions"
          git config user.email "actions@github.com"
          git add CHANGELOG.md
          git commit -m "chore(release): update changelog" || true
          git push

release-please: Google’s Conventional Commits Release Tool

release-please takes a different approach. Instead of just generating a changelog file, it automates the entire release workflow: it reads your commit history, determines the next semantic version, updates the changelog, and opens a release pull request for review.

Stars: 6,768+ | Language: TypeScript | Last updated: April 2026

Key Features

  • Automated semantic version bumping based on commit types
  • Release pull request workflow (review before merging)
  • Multi-package monorepo support
  • GitHub, GitLab, and Bitbucket integration
  • Conventional Commits parsing (Angular convention by default)
  • GitHub Releases creation on PR merge
  • Language-specific version bumping strategies

Installation

1
2
3
4
5
6
7
8
# Via npm
npm install -g release-please

# Via npx (no install needed)
npx release-please --help

# Via Docker
docker run --rm -v "$(pwd):/app" -w /app ghcr.io/googleapis/release-please:latest --help

Docker Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
version: "3.8"

services:
  release-please:
    image: ghcr.io/googleapis/release-please:latest
    volumes:
      - .:/app
    working_dir: /app
    command: release-please release-pr --token $GITHUB_TOKEN --repo-url your-org/your-repo
    environment:
      - GITHUB_TOKEN=${GITHUB_TOKEN}

Configuration

release-please uses a .release-please-manifest.json and release-please-config.json:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "packages": {
    ".": {
      "release-type": "node",
      "changelog-path": "CHANGELOG.md",
      "bump-minor-pre-major": false,
      "bump-patch-for-minor-pre-major": false,
      "draft": false,
      "prerelease": false,
      "packages": {
        "release-type": "node"
      }
    }
  },
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

For monorepos, you specify multiple package paths:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "packages": {
    "packages/core": {
      "release-type": "node",
      "component": "core"
    },
    "packages/cli": {
      "release-type": "node",
      "component": "cli"
    },
    "packages/web": {
      "release-type": "python",
      "component": "web"
    }
  }
}

GitHub Actions Workflow

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
name: release-please
on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - uses: googleapis/release-please-action@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          config-file: release-please-config.json
          manifest-file: .release-please-manifest.json

When commits land on main, release-please analyzes them, opens a release PR with the updated changelog and version bump, and — once you merge that PR — creates a Git tag and GitHub Release automatically.

auto (Intuit): Label-Driven Release Automation

auto by Intuit takes yet another approach. Instead of parsing commit message conventions, it uses GitHub labels on pull requests to determine what kind of release to make. Tag a PR with minor and it bumps the minor version; tag it with patch for a patch release.

Stars: 2,397+ | Language: TypeScript | Last updated: February 2026

Key Features

  • Label-based release determination (no commit message format required)
  • Pull request–centric workflow
  • Multiple plugins for different platforms (GitHub, GitLab, npm, CocoaPods)
  • Automatic changelog generation from PR titles and descriptions
  • Canary releases for testing before stable releases
  • Ship command for one-command publishing to npm and other registries

Installation

1
2
3
4
5
# Via npm
npm install -g auto

# Via npx
npx auto --help

Configuration

auto uses a .autorc file in JSON or JavaScript format:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
  "plugins": [
    "npm",
    "released",
    [
      "all-contributors",
      {
        "commitTypes": ["feat", "fix", "docs"],
        "contributorsPerLine": 7
      }
    ]
  ],
  "labels": [
    {
      "name": "major",
      "changelogTitle": "💥 Breaking Change",
      "releaseType": "major",
      "color": "#C5000B",
      "description": "Increment the major version when merged"
    },
    {
      "name": "minor",
      "changelogTitle": "🚀 Enhancement",
      "releaseType": "minor",
      "color": "#F1A60E",
      "description": "Increment the minor version when merged"
    },
    {
      "name": "patch",
      "changelogTitle": "🐛 Bug Fix",
      "releaseType": "patch",
      "color": "#870048",
      "description": "Increment the patch version when merged"
    },
    {
      "name": "skip-release",
      "description": "Preserve the current version when merged",
      "releaseType": "skip"
    }
  ]
}

CI/CD Integration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
name: Release
on:
  push:
    branches:
      - main

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install auto
        run: npm install -g auto
      - name: Create Release
        run: auto shipit
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Comparison Table

Featuregit-cliffrelease-pleaseauto
ApproachConfig file + templatesConventional Commits + release PRGitHub labels on PRs
LanguageRustTypeScriptTypeScript
Stars11,747+6,768+2,397+
Conventional Commits✅ Full support✅ Required❌ Not required
Monorepo support❌ Single project✅ Native support✅ Via plugins
Release PR workflow❌ Generates file only✅ Built-in❌ Generates file + tag
Label-based versioning✅ Core feature
Docker image✅ ghcr.io/orhun/git-cliff✅ ghcr.io/googleapis/release-please❌ npm install
Template customization✅ Jinja2-style⚠️ Limited⚠️ Limited
GitLab support✅ Via plugin
Bitbucket support
Canary/beta releases✅ Built-in
Best forTeams wanting full controlTeams wanting release automationTeams using PR labels

Which Tool Should You Choose?

Choose git-cliff if you want complete control over changelog formatting. Its TOML configuration and Jinja2-style templates let you produce changelogs in any style — from simple bullet lists to structured release notes with code diffs. It’s the best option when your team has specific formatting requirements that other tools can’t meet.

Choose release-please if you want the full release workflow automated. It doesn’t just generate a changelog — it opens release PRs, bumps versions, and creates GitHub Releases. The monorepo support is unmatched. This is ideal for teams following Conventional Commits who want “zero-touch” releases.

Choose auto if your team already uses PR labels for triage and doesn’t want to enforce commit message conventions. The label-based approach is more flexible for teams with diverse contribution styles, and the canary release feature is useful for pre-release testing.

For related reading, see our CI/CD pipeline comparison for setting up automated build pipelines, our dependency automation guide for keeping packages up to date, and our data versioning guide for versioning non-code artifacts.

FAQ

What is a changelog generator and why do I need one?

A changelog generator automatically creates release notes by reading your Git history — commits, tags, pull requests, and labels. Instead of manually writing what changed between releases, the tool parses your commit messages and produces a structured document. This saves time, ensures consistency, and integrates into your CI/CD pipeline so release notes are always up to date.

What are Conventional Commits?

Conventional Commits is a specification for formatting commit messages. Each commit starts with a type prefix like feat: (new feature), fix: (bug fix), docs: (documentation), or BREAKING CHANGE: (incompatible API change). Tools like git-cliff and release-please parse these prefixes to automatically categorize changes and determine version bumps.

Can I use these tools without Conventional Commits?

Yes, but with trade-offs. auto uses GitHub labels instead of commit message formats, so it works with any commit style. git-cliff can be configured to parse non-conventional commit patterns via custom regex rules in its commit_parsers section. release-please requires Conventional Commits as its core mechanism — it cannot determine version bumps without them.

How do I run changelog generation in a CI/CD pipeline?

All three tools support CI/CD integration. For git-cliff, use the git-cliff-action in GitHub Actions or run the Docker image in any CI system. For release-please, use the googleapis/release-please-action which handles the full release PR workflow. For auto, run auto shipit in your pipeline after setting the appropriate tokens. Each tool needs access to the full Git history, so configure your checkout step with fetch-depth: 0.

Do these tools support monorepos?

release-please has the best monorepo support natively — you configure multiple package paths in release-please-config.json and it manages independent versioning for each. auto supports monorepos via plugins and workspace configuration. git-cliff is designed for single-project repositories and does not have built-in monorepo handling.

Can I customize the output format of the changelog?

git-cliff offers the most customization through its Jinja2-style template engine in cliff.toml — you control every heading, bullet point, and section. release-please and auto produce standardized changelog formats with limited customization options. If your team needs a specific changelog style (e.g., adding contributor avatars, linking to Jira tickets, or including code diffs), git-cliff is the best choice.

Advertise here
Advertise here