by Changelog AI (LX AI)
Last updated: 2026-09-16
Grouped changelogs from commits (not raw git log)
Raw commit dumps are noisy. Grouping by feature/fix/improvement matches how readers scan release notes.
Why grouping commits matters
When a reader opens a release note they look for what changed that affects them. A long list of raw commit SHA‑1s and short messages forces the eye to jump around and miss the point. By clustering commits into logical buckets you give the reader a quick map of new features, bug fixes, and internal improvements. This map matches the way people skim: they first see headings, then decide if they need the details underneath.
Reader expectations
- Feature sections answer “what can I do now?”
- Fix sections answer “what problem was solved?”
- Improvement sections answer “what got better without changing behavior?”
Signal vs noise
- Raw logs contain merge commits, typo fixes, and refactoring noise.
- Grouped logs surface only the intent that matters to users or downstream teams.
- Noise reduction cuts the time needed to assess a release from minutes to seconds.
Mapping conventional commits to groups
The conventional commits specification gives a predictable prefix that signals intent. By reading the prefix you can decide which bucket a commit belongs to without parsing the full message.
Tag prefixes
feat: → feature bucket
fix: → bug‑fix bucket
perf:, refactor:, style: → improvement bucket
docs: → documentation bucket (often omitted from user‑facing notes)
test: → internal quality bucket
Custom tags
- Teams can add
security: to highlight patches that address vulnerabilities.
breaking: can be used to flag API changes that require migration.
- Any extra prefix should be documented in the project’s contributing guide so the generator knows where to place it.
Algorithm: clustering commits by semantic tags
Our generator follows a three‑step pipeline that turns a git log into a set of ready‑to‑review groups. The steps are deterministic, so the same input always yields the same output.
Step 1: parse commit messages
- Run
git log --pretty=format:%s to get the subject line of each commit in the range.
- Split the subject at the first colon to isolate the prefix and the description.
- If no colon is present, treat the commit as
chore: and place it in an internal bucket that is hidden from the public changelog.
Step 2: bucket by prefix
- Maintain a map from known prefixes (feat, fix, perf, refactor, style, docs, test, security, breaking) to a list of commits.
- Append each commit to the list that matches its prefix.
- Preserve the original commit order inside each list so that later steps can show a chronological view.
Step 3: resolve overlaps
- Some teams use combined prefixes like
feat(parser):. We strip the parentheses and treat the left part as the main bucket.
- If a commit matches more than one bucket (rare, but possible with custom aliases) we assign it to the first matching bucket in the priority list: breaking > security > feat > fix > perf > refactor > style > docs > test > chore.
- The final output is an ordered array of buckets, each containing its commits.
| Step |
Input |
Output |
| 1 |
git log subjects |
prefix + description pairs |
| 2 |
prefix + description pairs |
buckets of commits |
| 3 |
buckets of commits |
ordered, deduplicated buckets ready for display |
To see how the algorithm works in practice, you can try it on any repository that follows the conventional commits format. The generator will surface the same groups you would create by hand, but in a fraction of the time.
Review UI: preview and edit groups
After the algorithm produces the buckets, the user sees a preview where each bucket is a collapsible section. The goal is to let the author verify that the automatic grouping matches intent before the changelog is published.
Inline editing
- Clicking a commit description turns it into an editable text field.
- Changes are saved locally and can be used to re‑assign a commit to a different bucket by dragging the edited line.
- Edited descriptions are stored as overrides so future runs of the generator keep the human‑chosen wording.
Drag‑and‑drop reordering
- Entire buckets can be moved up or down to reflect the desired release narrative.
- Inside a bucket, individual commits can be reordered to highlight the most important change first.
- The UI emits a JSON patch that records the new order; this patch can be committed alongside the changelog for audit purposes.
What this is NOT
It is important to be clear about the limits of the tool so that teams set realistic expectations.
No guarantee of completeness
- The generator only sees what is in the commit range you provide.
- If a change is made outside of version control (e.g., a manual server config tweak) it will not appear.
- We do not scan issue trackers, design docs, or external communication channels.
Not a replacement for manual review
- Automatic grouping can misplace a commit if the prefix is ambiguous or missing.
- Authors should still skim the generated notes to catch any mis‑categorized items.
- The tool is meant to reduce effort, not to eliminate the need for a human gate.
CI/CD integration
To keep changelogs up to date you can run the generator as part of your pipeline. The step produces a markdown file that can be uploaded as an artifact or used to create a GitHub Release.
GitHub Action example
Add a step to your workflow that checks out the code, sets up Node, runs the generator, and then creates a release with the generated changelog.
- uses: actions/checkout@v4
- run: npm ci
- run: npx ai-changelog-generator --from ${{ github.event.before }} --to ${{ github.sha }} --output CHANGELOG.md
- uses: softprops/action-gh-release@v2
- with:
- tag_name: ${{ github.ref_name }}
- name: Release ${{ github.ref_name }}
- body_path: CHANGELOG.md
GitLab CI snippet
In .gitlab-ci.yml add a job that runs the generator and stores the changelog as a job artifact.
- image: node:20
- variables:
- script:
- npm ci
- npx ai-changelog-generator --from $CI_COMMIT_BEFORE_SHA --to $CI_COMMIT_SHA --output CHANGELOG.md
- artifacts:
Both examples use the public OWASP LLM Top 10 document as a reference for security‑related commits and the NIST AI Risk Management Framework for commits that touch model safety. You can see them referenced inline:
Best practices for maintaining grouped changelogs
Even with automation, a few habits keep the output useful over the life of a project.
Commit hygiene
- Always start a commit message with a conventional prefix.
- If a commit touches multiple areas, split it into separate commits so each has a clear intent.
- Include a short description after the colon that explains the user‑visible impact.
Regular group review
- Before each release, open the generated changelog and verify that each bucket contains the expected commits.
- If you see a commit in the wrong bucket, edit the description or add a custom prefix to steer the generator.
- Make a habit of updating the contributing guide whenever you add a new custom prefix so future contributors know the convention.
Operator checklist for Grouped changelogs from commits (not raw git log)
I keep a written checklist next to every release that touches this topic. The list is boring on purpose: name the owner, name the evidence artifact, and name the rollback. If a step cannot produce a file, a ticket, or a log line, it is not a step — it is a wish.
Before you change production
- Freeze the branch or config revision you will measure against.
- Record the current failure mode with one concrete input and one concrete output.
- Confirm which identity the job runs as, and whether that identity can reach data it should not.
- Open the primary references you will cite: https://owasp.org/www-project-top-10-for-large-language-model-applications, https://www.nist.gov/itl/ai-risk-management-framework.
While you run the check
- Prefer one reproducible path over ten anecdotal screenshots.
- Write the expected safe outcome before you trigger the tool or query.
- Capture the exact command, prompt, schema, or regex under test — not a paraphrase.
- If the system can act (send, write, delete, transfer), require a confirmation boundary in the same pass.
After you finish
- File residual risk with an owner and a date, even when the scan is clean.
- Do not convert a green check into sales language that claims completeness.
- Re-run the same checklist when the model, tool schema, or validation rules change.
| Signal | What to record | Stop-ship? |
| Unexpected write or send | Tool name, args, identity | Yes until gated |
| Missing confirmation on destructive action | Call path and bypass | Yes |
| Untrusted text treated as instruction | Source surface and resulting action | Yes for agent reach |
| Scanner clean, judgment open | Deferred items + owner | Only if core path safe |
ai-changelog-generator helps with the measurable first pass. Architecture choices, legal sign-off, and customer-facing claims still need a human owner. Treat every checklist row as decision support, not a certificate.
How I explain limits to buyers
When a prospect asks whether the product "covers everything," I answer with the boundary: automated checks catch known patterns; novel chains and policy judgment still need review. That honesty keeps support load down and keeps the blog aligned with what the product actually does.
If you need a second opinion, pair this write-up with the references below and with your own staging reproduction. Do not skip the reproduction step just because a model wrote a confident summary.
References