On this page
Automated changelogs are only as useful as the release information they receive. A parser can recognize a feature prefix, but it cannot infer that a small configuration change will break a customer's deployment. Reliable automation starts with a shared meaning for commit messages and a clear boundary between generated notes and editorial judgment.
Define the message contract first
The Conventional Commits format describes a structured header, optional body, and optional footers. A basic header contains a type, optional scope, and description. Use the Regex Tester to explore a local header convention with accepted and rejected examples before adding enforcement. A regex is useful for feedback, not a replacement for a complete message parser.
For example, test whether your rule accepts a scope and a breaking-change marker, and whether it rejects an empty description. Keep the allowed types documented. The Conventional Commits specification defines the interoperable foundation; additional types and scope restrictions are team policy.
Decide what you are optimizing: release calculation, searchable history, or readable notes. Those goals overlap but are not identical. Put the contract beside other developer tooling guidance, so contributors can find it without studying an automation configuration.
Give types and breaking changes precise meaning
Use feat for a new capability and fix for a correction to existing behavior. Other common types include docs, test, refactor, build, and chore. Their names do not inherently imply a version bump under the specification; your release tool's rules decide how they contribute.
Scopes should describe stable areas such as checkout, editor, or tokens. Avoid ticket IDs as the only scope because they stop being useful after the project closes. Reference the ticket in the body or footer instead, where it can explain context without replacing the affected area.
feat(editor): add keyboard shortcuts panel
Expose the available shortcuts from the help menu.
Refs: TEAM-142
feat(config)!: require an explicit output directory
BREAKING CHANGE: builds no longer default to the current directory.
Set outputDir before upgrading existing projects.A breaking change is a compatibility decision, not a measure of code volume. Removing a public configuration default may be more disruptive than adding thousands of internal lines. Require a migration explanation whenever a breaking marker is present, even if the syntax technically permits a shorter message.
Connect these rules to Semantic Versioning: once a public API is defined, compatible fixes, compatible additions, and incompatible changes have different release implications. Pre-1.0 versions require explicit team rules; do not assume every release tool handles them identically.
Enforce the commit that actually reaches main
Local hooks provide quick feedback but can be skipped, and not every contributor uses the same environment. Use a repository check as the final gate. The object to validate depends on your merge strategy, so choose that before selecting hook packages.
With squash merging, the final squash message matters more than every temporary branch commit. Validate the pull request title if it seeds that message, then ensure the merge interface preserves the required body and breaking-change footer. A valid title cannot compensate for a migration note discarded at merge time.
With merge commits that retain individual commits, validate the relevant commit range. Exclude merge-generated messages where appropriate rather than forcing humans to disguise them as features. With rebase merging, ensure all retained commits carry meaningful types and scopes.
commitlint can enforce a shared message convention. Pin its version with the rest of your toolchain, keep its configuration in the repository, and show contributors a good replacement message when validation fails. A cryptic rejection encourages bypasses rather than better history.
For a team starting from informal commits, introduce the rule on new work only. Rewriting published history to satisfy a parser causes more disruption than the convention solves. The existing Git workflow guide provides a useful baseline for keeping individual changes focused.
Separate version calculation from release-note writing
A release pipeline usually collects commits since a release boundary, parses them, calculates a version, and renders notes. Each stage needs a documented input. Confirm the relevant tags are available and that the checkout contains enough history to discover the previous release.
Treat release boundaries as important configuration. A wrong starting tag can omit changes or republish old ones. Test initial releases, maintenance branches, and prereleases separately. Never assume the behavior observed on a simple main branch extends to all branch strategies.
Generated notes should describe observable outcomes. A message such as fix(editor): preserve selection after paste already helps users. A message such as fix(editor): adjust handler does not. Encourage authors to state the behavior and reserve implementation details for the body.
Add an editorial review before publication. Group duplicate entries, explain migrations, and remove internal maintenance noise from user-facing notes while preserving traceability. For design-system releases, link the affected token or component documentation; the design tokens guide illustrates why naming and ownership matter to consumers.
Do not claim automation removes release judgment. It removes repetitive collection work. A maintainer still decides whether the generated story accurately explains what changed and whether people can upgrade safely.
Test the policy with representative history
Create a disposable test repository or fixture history containing a fix, a feature, a breaking change, documentation-only work, and a revert. Run the proposed tooling against it without publishing packages or pushing tags. Record the expected version and note entries as acceptance criteria.
Include a feature reverted before release. Some tools recognize conventional revert messages and cancel corresponding entries; others need configuration. Verify behavior rather than assuming a revert always cancels the version bump. Also test custom scopes and multiline footers with real contributor examples.
Protect release credentials and restrict publishing permissions independently of message checks. A valid commit message is not authorization to publish. Keep dry runs available to maintainers, and make the release process rerunnable without creating duplicate tags or repeated announcements.
Finally, review the first few generated changelogs with support and documentation colleagues. If they repeatedly translate internal terminology, adjust message guidance or the rendering template. The best convention is one contributors can follow consistently and readers can use without knowing the repository layout.
Key takeaways
- Define types, scopes, and compatibility rules before enabling automation.
- Validate the message that survives your chosen merge strategy.
- Require migration guidance for breaking changes, regardless of diff size.
- Test release boundaries, reverts, and prereleases without publishing.
- Keep human review for user-facing notes and release authorization.
Reach designers & developers at work
Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.
Become a sponsor