Skip to content

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#

  1. Structured Format: YAML-based fragments with enforced schema
  2. Better Validation: Automated checks for required fields and formatting
  3. Improved UX: Interactive CLI for creating entries with validation
  4. Per-Version CHANGELOGs: Change fragments do not need to be kept indefinitely
  5. 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.md is appended to CHANGELOG.md as a separate, explicit step in the automation workflows after each changie merge call.

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:

  1. Entry Requirement: Whether a pull request requires an entry (unless labeled no-changelog-needed)
  2. Direct Edits: Prevents direct modifications of the main CHANGELOG that would be overwritten on later runs of the generator
  3. Legacy Fragments: Detects and alerts when go-changelog style change fragments are included in pull requests
  4. PullRequest Key: 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.06.2.0)
  • Merges from release/N.x branches: Reuses version number from version/VERSION

On release/N.x branches:

  • Default: Next prerelease increment (e.g., 6.0.0-beta16.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)
  • When transitioning from GA back to prerelease:
    • First beta of the next minor version (e.g., after 6.0.0 GA → 6.1.0-beta1)

When a new major version begins, three preparatory steps are taken before development starts:

  1. A new subdirectory (e.g., 7.x/) is created in .changes/
  2. The changesDir in .changie.yaml is updated to point to the new directory
  3. 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:

  1. Beta Phase (on release/N.x branch):

  2. Change fragments moved to beta/ subdirectory after each beta release

  3. Per-version CHANGELOGs created for each beta (e.g., 6.0.0-beta1.md)

  4. GA Release (on release/N.x branch):

  5. Change fragments moved to ga/ subdirectory

  6. GA per-version CHANGELOG created (e.g., 6.0.0.md)
  7. This CHANGELOG includes only GA changes, not beta changes

  8. Merge to main from release/N.x Branch:

  9. Beta and GA fragments combined with any remaining changies in unreleased/

  10. Single consolidated per-version CHANGELOG generated including all changes from beta and GA in one file
  11. 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:

  1. 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 requests
  2. update-changelog.yml - Automatically regenerates CHANGELOG when PRs merge, and supports manual triggering for release preparation
  3. create-release-branch.yml - Automates major release branch creation

Tooling#

  • make changelog-convert - Converts go-changelog fragments to Changie format
  • make changelog-misspell - Updated to check both legacy and new directories
  • generate-changelog - Deprecated with helpful error message

Migration#

The migration is being implemented incrementally to minimize disruption:

  1. Phase 1: Core Infrastructure
  2. Changie configuration
  3. Set up .changes/ directory structure with version subdirectories
  4. Add Changie to make tools installation

  5. Phase 2: Automation

  6. 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
  7. Phase 3: Developer Experience

  8. Update primary documentation (docs/changelog-process.md)
  9. Update Makefile targets (changelog-misspell, generate-changelog)
  10. Update supporting documentation

  11. Phase 4: Final Migration + Tooling

  12. Create conversion tool for legacy fragments
  13. Document migration process for open pull requests
  14. 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:

  1. Revert the migration PR - This restores all go-changelog tooling and workflows
  2. Restore .changelog/ directory - Available in git history from the reverted commit
  3. Remove .changes/ directory - Clean up Changie artifacts
  4. Notify contributors - Update any open PRs to use go-changelog format again

References#