Generating Changelogs Automatically From Commits With Claude
AI generated
Claude
>_
Claude AI · Release Automation · Git
Generating Changelogs From Commits
Categorized release notes instead of raw commit lists

A raw list of commit messages is not a changelog anyone wants to read. Claude can categorize, summarize, and structure a commit history between two releases into something users and developers actually understand. This article shows the practical workflow, the distinction from tools like semantic-release, and the quality control it needs.

11 min read Changelog Conventional Commits Release Notes CI/CD

1. Conventional Commits as the foundation

Any automated changelog generation stands or falls with the quality of the underlying commit messages. The Conventional Commits convention structures every message into a type like feat, fix, refactor, or chore, an optional scope in parentheses, and a short description, plus an optional body and footer for breaking changes. This structure makes commits machine-parseable, because a type like fix can be mapped unambiguously to a category in the changelog without needing to interpret free text.

Without this convention, both classic tools and Claude are left interpreting free-text commits, which produces noticeably worse results with an inconsistent team style. Teams that have not yet established a convention should set one up before introducing changelog automation, for example through a commit-msg hook that rejects badly formatted commits locally.


# Examples of Conventional Commits messages
feat(checkout): allow guest checkout without an account
fix(cart): fix duplicate shipping cost on multiple addresses
refactor(api): decouple ProductRepository from legacy class
chore(deps): bump guzzlehttp/guzzle to 7.9

BREAKING CHANGE: the /api/v1/cart endpoint now returns an
array instead of a single object.

2. Why pure parsing hits its limits

Classic tools like semantic-release or conventional-changelog reliably parse commit types and mechanically generate a grouped list from them, usually one to one following the pattern type, scope, description. That works well for a technical rough draft but rarely delivers a text a product manager or end customer would want to read without rework, because related commits are not recognized and redundant or contradictory entries are not cleaned up.

Claude fills exactly that gap: instead of listing every commit individually, the model can condense several related commits, say a feature implementation followed by three bug fix commits for the same feature, into a single, understandable changelog entry. That is a semantic task pure pattern matching cannot handle, because it requires understanding context across several commits.

3. Workflow: collecting commits between two releases

The first step in any changelog generation is purely mechanical: git log retrieves all commits between two tags or branches, ideally including commit hash, author, and the full message, so Claude can access the body and footer if needed. It is important to filter out merge commits with no content value of their own, so they do not needlessly inflate the later summary.

This raw data forms the sole input for the next step. That way Claude only receives information actually present in the repository and does not invent features that were never committed, as long as the prompt clearly points to the delivered commit list as the only source.


# Collect all commits between two tags, excluding merge commits
git log v2.3.0..v2.4.0 --no-merges \
  --pretty=format:'%H|%an|%s%n%b%n---' > commits-v2.4.0.txt

wc -l commits-v2.4.0.txt

4. Categorization and summarization by Claude

Once the commit list is ready, Claude handles two tasks at once: categorizing by type, say new features, bug fixes, and breaking changes, and linguistically condensing technical commit messages into sentences understandable even without knowledge of the codebase. A commit like fix(cart): fix race condition on concurrent addItem turns into a user-facing phrasing such as A rare bug that could occur when adding several items to the cart at the same time has been fixed.

What matters most for quality is a clearly structured prompt that specifies the desired categorization, the target audience of the changelog, and the desired level of detail. Without these constraints, the model tends to phrase things either too technically for end users or too superficially for a technical development team.

5. Practical example: prompt and output for a release

In practice, a two-stage prompt has proven effective: first Claude is asked to assign each commit to a category and group thematically related commits, then a second pass turns that grouping into the final, human-readable changelog text. This separation improves traceability, because the intermediate categorization can be reviewed separately before the final text is generated.

For a team releasing monthly, a single prompt pass per release is usually enough, while teams with several releases per week benefit from an automated script that triggers the two-stage prompt on every tag push and stores the result as a draft in a pull request description.


from anthropic import Anthropic

client = Anthropic()

with open("commits-v2.4.0.txt", encoding="utf-8") as f:
    commits = f.read()

prompt = f'''Categorize the following commits into New Features,
Bug Fixes, Breaking Changes, and Other. Condense thematically
related commits into a single sentence understandable by end
users. Do not invent features that do not appear in the commits.

Commits:
{commits}'''

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=2048,
    messages=[{"role": "user", "content": prompt}],
)
print(response.content[0].text)

6. Integration into the CI/CD pipeline

For a durable solution, it pays off to embed this into the existing release pipeline: a job runs when a new tag is set, collects the commits since the last tag, calls the Claude API with the prompt outlined above, and stores the result as a draft in a file or as a comment on the associated release pull request. It is important not to publish the generated text automatically and unchecked, but to treat it as a suggestion a human confirms.

In GitLab CI, such a job can easily be set up as its own stage after the build but before the actual deployment, so the changelog draft exists before the new version is actually rolled out. That gives the team a chance to still adjust the text before publishing.


# .gitlab-ci.yml (excerpt)
generate-changelog:
  stage: pre-deploy
  image: python:3.12-slim
  rules:
    - if: '$CI_COMMIT_TAG'
  script:
    - pip install anthropic
    - git fetch --tags
    - PREV_TAG=$(git describe --tags --abbrev=0 "$CI_COMMIT_TAG^")
    - git log "$PREV_TAG..$CI_COMMIT_TAG" --no-merges
        --pretty=format:'%H|%an|%s%n%b%n---' > commits.txt
    - python scripts/generate_changelog.py commits.txt > CHANGELOG_DRAFT.md
  artifacts:
    paths: [CHANGELOG_DRAFT.md]

7. Quality control of the generated text

An automatically generated changelog draft does not replace human review, especially since Claude occasionally merges two thematically similar but substantively different commits incorrectly, or chooses a phrasing that is technically imprecise. A short review step before publishing, where a developer checks the draft against the actual commits, therefore remains a fixed part of the process, even if it only takes a few minutes.

This review is non-negotiable especially for breaking changes, because an imprecise or incomplete description of a breaking change can lead users into faulty upgrades. The prompt should therefore explicitly instruct that breaking changes be described separately, in detail, and with a concrete migration hint, rather than letting them get lost in the general summary.

8. Limits and common pitfalls

The biggest source of error remains input quality: poorly phrased or inconsistent commit messages like Fix or WIP give Claude no sufficient basis for meaningful categorization, no matter how well the prompt is written. In such cases, only better commit discipline on the team helps, not a more elaborate prompt.

Another pitfall is mixing several unrelated changes into a single commit, which forces Claude to artificially split one message across several changelog categories, which easily leads to inaccuracies. Smaller, thematically focused commits therefore improve not just code review quality but directly the quality of the automatically generated changelogs as well.

9. Best practices for team adoption

Anyone wanting to adopt changelog generation with Claude for the long run should first enforce the commit convention through an automated hook, then clearly phrase the prompt for the changelog's target audience, and finally plan a mandatory, short review step before every publication. These three building blocks together deliver noticeably more consistent results than a one-off, unstructured request to the model.

It also pays off to version the prompt itself and store it in the repository, so changes to the categorization logic stay traceable and can be discussed on the team instead of getting lost in a single chat session. That turns the prompt into a genuine part of the project infrastructure rather than a one-off experiment.

Approach Categorization Linguistic condensation Typical use
semantic-release / conventional-changelog Mechanical, by commit type None, lists commits one to one Automated versioning without rework
Claude (single-stage prompt) Semantic, recognizes relationships Simple rephrasing per commit Small teams with a manageable commit count
Claude (two-stage prompt) Semantic, with separate grouping Condenses several commits into one entry Larger releases with many related commits
Manual writing Fully human Highest quality, but time-consuming Very small, rare releases
Hybrid (Claude draft + review) Semantic, human-reviewed AI draft, edited by a developer Recommended default for most teams

Mironsoft

AI-assisted development, agent workflows, and team processes

Using Claude or other AI tools on the team, but without a clear workflow?

We set up AI-assisted development workflows for teams, from CLAUDE.md conventions to subagent strategies to code review processes that combine human oversight with AI speed.

Workflow Setup

Cleanly set up CLAUDE.md, project conventions, and tool permissions for the team.

Agent Strategy

Build subagent and automation workflows for recurring development tasks.

Team Onboarding

Train developers in productive, safe use of AI coding assistants.

10. Summary

Generating Changelogs From Commits: The Essentials

What

Claude categorizes and condenses commit histories between two releases into a readable changelog.

Prerequisite

Consistent Conventional Commits messages, otherwise Claude lacks the basis for meaningful categorization.

Distinction

semantic-release parses mechanically, Claude adds semantic understanding and linguistic condensation.

Practical tip

Always treat generated text as a draft and check it against the commits before publishing.

11. FAQ: Generating Changelogs From Commits: The Essentials

1Is a simple commit list enough as input for Claude?
Yes, as long as the commits are clearly phrased and ideally follow the Conventional Commits convention. Extra context like body and footer further improves categorization quality.
2What is the difference to semantic-release?
semantic-release parses commit types mechanically and generates a structured but uncondensed list from them. Claude adds semantic understanding, groups related commits, and phrases user-facing sentences.
3Can Claude reliably recognize breaking changes?
If breaking changes are clearly marked in the commit footer, Claude recognizes them reliably. Without that marker, detection depends on the quality of the commit description and should be checked manually.
4Should the generated changelog be published unchecked?
No. A short review step before publishing is recommended, because commits can occasionally be grouped incorrectly or phrasing can turn out technically imprecise.
5Is integrating this into a CI pipeline worth it?
For teams with regular releases, yes, because the changelog draft can then be generated automatically on every new tag and only needs review instead of being written from scratch.
6How does Claude handle poorly phrased commit messages?
With messages like Fix or WIP, Claude lacks the substance for meaningful categorization. Only better commit discipline on the team helps here, not a more elaborate prompt.
7Can Claude merge several commits into a single changelog entry?
Yes, that is one of the key advantages over mechanical parsing. Related commits, say a feature with subsequent bug fixes, can be condensed into a single, understandable entry.
8Do you need a particularly capable model for changelog generation?
Usually not. The task is repetitive and well structured, so a faster, cheaper model is sufficient for most teams, provided commit quality is high.
9How many commits can Claude process in a single pass?
That depends on the available context window; in practice several hundred commits can easily be processed in a single prompt before a split into multiple requests becomes necessary.
10Does an automatically generated release description replace documentation?
No. A changelog briefly summarizes changes but does not replace detailed documentation of new features, especially not for complex features that need explanation.