133 lines
4.3 KiB
Markdown
133 lines
4.3 KiB
Markdown
# 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 <path>`: repo-local JSON section config
|
|
- `--output <path>`: write rendered Markdown to a file; otherwise stdout
|
|
- `--current-tag <tag>`: optional explicit current tag
|
|
- `--previous-tag <tag>`: optional explicit previous tag
|
|
- `--api-base-url <url>`: optional explicit Gitea API base URL
|
|
- `--token <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/<sha>)) - 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
|