# Changelog Automation Contract ## Status Snapshot Current state as of 2026-05-13: - The shared implementation is present in `internal/changelog/` and is exposed as `sow-toolkit build-changelog`. - Consumer configs exist in both `module/scripts/changelog.json` and `assets/scripts/changelog.json`. - CLI parsing and generator behavior are covered by `internal/app/app_test.go` and `internal/changelog/changelog_test.go`. - `module/scripts/release-all.sh` already stages `build/CHANGELOG.md`. Remaining work: - confirm and document the `assets/` release workflow uses the shared command in the same way as `module/` - build the deferred cross-repo NodeBB aggregation bot if combined public release posts are still desired ## Scope This contract governs release changelog generation across: - `toolkit/` as the implementation owner - `module/` as a changelog-producing consumer - `assets/` as a changelog-producing consumer The immediate goal is to produce stable per-repo `CHANGELOG.md` release artifacts that can later be merged by a NodeBB bot into one combined release post. ## Ownership Split - `toolkit/` - owns the shared changelog generator implementation - owns the CLI contract exposed through `sow-toolkit` - owns the config schema used by consumer repos - `module/` - owns its changelog section mapping under `scripts/changelog.json` - owns invoking changelog generation during its tag release flow - `assets/` - owns its changelog section mapping under `scripts/changelog.json` - owns invoking changelog generation during its tag release flow ## Shared CLI Contract The canonical generator entrypoint is: ```bash sow-toolkit build-changelog ``` Supported flags: - `--config `: repo-local JSON section config - `--output `: write rendered Markdown to a file; otherwise stdout - `--current-tag `: optional explicit current tag - `--previous-tag `: optional explicit previous tag - `--api-base-url `: optional explicit Gitea API base URL - `--token `: optional explicit Gitea API token If `--current-tag` is omitted, the generator must resolve the exact tag at `HEAD`. If `--previous-tag` is omitted, it must select the next older tag by `creatordate`. ## Config Contract Each consumer repo provides `scripts/changelog.json` with: - `repo_url`: canonical web URL for pull request and commit links - `categories[]` - `categories[].title` - `categories[].sections[]` - `categories[].sections[].title` - `categories[].sections[].paths[]` Paths are repo-relative path filters passed through to `git log`. ## Author Contract Rendered changelog entries must support both first-parent pull-request-style pushes and direct first-parent pushes between the selected tags. For pull-request-style commits that include a `(#123)` suffix, the generator must resolve author names from the Gitea pull request API rather than trusting the merge commit author field. Expected endpoint shape: - `GET /api/v1/repos/{owner}/{repo}/pulls/{index}` - prefer `user.full_name` - fall back to `user.login` only if `full_name` is empty ## Release Contract For each version-tagged release workflow: 1. generate `build/CHANGELOG.md` for the current tag; 2. upload `CHANGELOG.md` as a release asset on the versioned release; 3. keep the file name stable across repos so later automation can fetch it without repo-specific asset naming logic. The changelog is a staged build artifact, not a committed source-controlled file. This avoids detached-tag push complexity while preserving a stable artifact for later aggregation. For direct pushes without a pull number suffix, the generator must render the commit using its commit hash link and commit author without calling the pull request API. ## Output Contract The Markdown output must remain simple and merge-friendly: - title line with current tag and publish date - comparison line naming the previous tag when one exists - category headings - section headings - bullet entries in one of these forms: ```text - Title ([#123](.../pulls/123)) - From Author Name - Title ([abc1234](.../commit/)) - From Author Name ``` ## Deferred Work - add a dedicated bot that fetches `CHANGELOG.md` assets from module and assets releases, merges them, and publishes a single NodeBB release post - decide whether changelog generation should later move from shell wrappers into first-class repo-root user commands