Migration from go-changelog to Changie#
Summary: Migrate CHANGELOG generation from go-changelog to Changie for improved automation, better user experience, and alignment with modern development workflows.
Created: 2025-10-23
Author: @justinretzolk
Background#
The Terraform AWS Provider has historically used go-changelog for managing CHANGELOG entries. Contributors would create text-based fragment files in the .changelog/ directory with a specific format, and these would be manually compiled into the main CHANGELOG.md file during releases.
While functional, this approach had several limitations:
- Manual Process: CHANGELOG generation required manual intervention during releases
- Format Inconsistencies: The freeform text format led to inconsistent entry formatting
- Limited Metadata: Difficult to categorize entries or extract structured information
- Poor Validation: Limited ability to validate entries before merge
- Script Usage: Generation relied on running a Bash script in a GitHub Actions workflow; something GitHub generally advises against.
Proposal#
Migrate to Changie for CHANGELOG management. Changie provides a modern, YAML-based approach to CHANGELOG fragments with robust automation capabilities.
Key Benefits#
- Structured Format: YAML-based fragments with enforced schema
- Better Validation: Automated checks for required fields and formatting
- Improved UX: Interactive CLI for creating entries with validation
- Per-Version CHANGELOGs: Change fragments do not need to be kept indefinitely
- Beta/GA Workflow: Built-in support for prerelease versioning
Design Details#
Directory Structure#
.changes/
├── footer.md # Footer appended to CHANGELOG.md after each merge
└── 6.x/
├── unreleased/ # New entries created by Changie
│ └── .gitkeep # Ensures the directory is tracked by git when empty
├── beta/ # Change fragments from beta releases on release branches
├── ga/ # Change fragments from GA releases on release branches
├── 6.0.0.md # Per-version CHANGELOG
├── 6.1.0.md
└── ...
Note: Changie does not natively support appending a footer only to the CHANGELOG generated by
changie merge— it can only add footers to every per-version CHANGELOG. Because of this,footer.mdis appended toCHANGELOG.mdas a separate, explicit step in the automation workflows after eachchangie mergecall.
Entry Format#
Changie entries are YAML files with structured metadata, generated using Changie's CLI tool.
Note: During generation, Changie creates files with a specific file naming pattern that's used during CHANGELOG generation. As such, manually creating change fragments should be avoided.
kind: enhancement
time: 2024-10-23T10:30:00Z
custom:
Impact: |-
resource/aws_example
Body: Add `example_attribute` argument
PullRequest: 12345
Kinds of Entries#
Five entry types are configured:
- Breaking Change: Backward-incompatible changes
- Note: Important notices (deprecations, removals)
- Feature: New resources, data sources, ephemeral resources, functions, or list resources
- Enhancement: New attributes or arguments
- Bug: Incorrect behavior
Validation#
GitHub Actions workflows validate:
- Entry Requirement: Whether a pull request requires an entry (unless labeled
no-changelog-needed) - Direct Edits: Prevents direct modifications of the main CHANGELOG that would be overwritten on later runs of the generator
- Legacy Fragments: Detects and alerts when
go-changelogstyle change fragments are included in pull requests PullRequestKey: Ensures pull request number is included. Where missing, inline suggestions are made
Version Calculation Logic#
The provider uses main for next minor release development and release/N.x branches for major release cycles (beta/GA) and backports. Automated workflows determine the next version based on this context:
On main branch:
- Default: Next minor version (e.g.,
6.1.0→6.2.0) - Merges from
release/N.xbranches: Reuses version number fromversion/VERSION
On release/N.x branches:
- Default: Next prerelease increment (e.g.,
6.0.0-beta1→6.0.0-beta2) - When starting a new release cycle (no per-version CHANGELOGs exist yet):
- First beta of version number pulled from
version/VERSION(e.g.,6.0.0-beta1)
- First beta of version number pulled from
- When transitioning from GA back to prerelease:
- First beta of the next minor version (e.g., after
6.0.0GA →6.1.0-beta1)
- First beta of the next minor version (e.g., after
When a new major version begins, three preparatory steps are taken before development starts:
- A new subdirectory (e.g.,
7.x/) is created in.changes/ - The
changesDirin.changie.yamlis updated to point to the new directory - The footer is updated to link to the previous major version's final
CHANGELOG.md
Beta and GA Workflow#
Major releases follow a structured beta-to-GA process:
-
Beta Phase (on
release/N.xbranch): -
Change fragments moved to
beta/subdirectory after each beta release -
Per-version CHANGELOGs created for each beta (e.g.,
6.0.0-beta1.md) -
GA Release (on
release/N.xbranch): -
Change fragments moved to
ga/subdirectory - GA per-version CHANGELOG created (e.g.,
6.0.0.md) -
This CHANGELOG includes only GA changes, not beta changes
-
Merge to
mainfromrelease/N.xBranch: -
Beta and GA fragments combined with any remaining changies in
unreleased/ - Single consolidated per-version CHANGELOG generated including all changes from beta and GA in one file
- Previous beta/GA per-version CHANGELOGs removed
This approach ensures release branches maintain separate beta and GA release notes, while the main branch has a single, comprehensive CHANGELOG for the major version.
Version File Updates#
Changie's replacements feature updates lines in specified files that match a given regex pattern whenever changie merge is run. This is used to keep version/VERSION in sync with the current release version automatically — without requiring a separate workflow step or manual update:
replacements:
- path: version/VERSION
find: '[0-9]\.(?:[0-9])+\.(?:[0-9])+'
replace: "{{ .VersionNoPrefix }}"
This means every changie merge call automatically updates version/VERSION to reflect the new version.
Implementation Details#
Automation#
Three GitHub Actions workflows automate CHANGELOG management:
changelog-entries.yml- Validates entries on PRs, detects legacy fragments, provides conversion instructions, and notifies maintainers via Slack when entries are missed in merged pull requestsupdate-changelog.yml- Automatically regenerates CHANGELOG when PRs merge, and supports manual triggering for release preparationcreate-release-branch.yml- Automates major release branch creation
Tooling#
make changelog-convert- Converts go-changelog fragments to Changie formatmake changelog-misspell- Updated to check both legacy and new directoriesgenerate-changelog- Deprecated with helpful error message
Migration#
The migration is being implemented incrementally to minimize disruption:
- Phase 1: Core Infrastructure
- Changie configuration
- Set up
.changes/directory structure with version subdirectories -
Add Changie to
make toolsinstallation -
Phase 2: Automation
-
Implement GitHub Actions workflows for:
- CHANGELOG entry validation
- Automatic CHANGELOG updates when pull requests are merged
- Slack notifications for maintainers when CHANGELOG entries are missed in merged pull requests
- Release preparation automation
-
Phase 3: Developer Experience
- Update primary documentation (
docs/changelog-process.md) - Update Makefile targets (
changelog-misspell,generate-changelog) -
Update supporting documentation
-
Phase 4: Final Migration + Tooling
- Create conversion tool for legacy fragments
- Document migration process for open pull requests
- Remove ~440 existing
.changelog/fragments
Transition Period#
During the transition, both systems are supported:
- Legacy
.changelog/directory: Remains in place - New
.changes/directory: All new entries go here - Makefile targets: Updated to check both directories
- CI workflows: Watch both directory paths
This dual-support approach allows:
- Existing pull requests to merge without forced updates
- Gradual migration at maintainer discretion
- Time to develop and test conversion tooling
Rollback Plan#
If critical issues are discovered after deployment, the migration can be rolled back:
- Revert the migration PR - This restores all go-changelog tooling and workflows
- Restore
.changelog/directory - Available in git history from the reverted commit - Remove
.changes/directory - Clean up Changie artifacts - Notify contributors - Update any open PRs to use go-changelog format again