Skip to content

ci(release): fall back to generated notes, and add the changelog rotation script - #237

Open
Nic-dorman wants to merge 2 commits into
mainfrom
nic/v2-1107-release-notes-fallback
Open

Nic-dorman wants to merge 2 commits into
mainfrom
nic/v2-1107-release-notes-fallback

Conversation

@Nic-dorman

@Nic-dorman Nic-dorman commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Every ant release since 0.3.6 has shipped with empty notes. #183 made the release workflow ship the CHANGELOG.md section matching the tag's base version. Since #187 (V2-1142), a missing section publishes a placeholder instead of failing. But nothing at the train cut ever rotates [Unreleased] into ## [X.Y.Z]. So all nine tags from ant-cli-v0.3.7 to today's ant-cli-v0.3.12-rc.1 (five of them stable) shipped "No changelog entry was recorded for …".

This PR fixes the process in two places. The content backfill for 0.3.7–0.3.12 is a separate PR.

1. scripts/rotate-changelog.sh X.Y.Z [date] [changelog]: the rotation step the cut tooling never had. For the RM: please wire it into the rc.1 cut, on the rc branch, before tagging. It moves the [Unreleased] entries unchanged under a new ## [X.Y.Z] - <date> and keeps an empty [Unreleased] heading above it.

  • It accepts X.Y.Z-rc.N and drops the suffix.
  • It is idempotent: an rc.2 re-cut finds [X.Y.Z] already filled and does nothing.
  • An empty hand-written ## [X.Y.Z] heading is replaced, not duplicated.
  • It never fails on an empty [Unreleased]. It warns instead, and the workflow fallback below covers that release.
  • It exits 2 only when both [X.Y.Z] and [Unreleased] have entries (entries landed after the rotation), so a human places them. Per V2-1142, the cut tooling should report that, not abort on it.

2. Workflow fallback. With no matching section, the notes are now GitHub's generated list of PRs merged since the previous stable ant-cli-v* tag (releases/generate-notes). Before, they were the placeholder. A missed rotation now ships the right list of changes rather than none. The ::warning:: annotation stays, and the placeholder remains only as the last resort if that API call fails. The previous tag is the highest stable tag below the base version, so X.Y.Z-rc.N and X.Y.Z both list the whole train. Nothing about the success path changes.

3. New AGENTS.md: user-facing PRs add entries under [Unreleased]; only the cut writes versioned headings. It lives in AGENTS.md so every coding agent sees it, not only Claude; CLAUDE.md imports it with @AGENTS.md.

Open question for reviewers: where should the changelog rule live? This PR puts it in a new root AGENTS.md, imported by CLAUDE.md, so non-Claude agents see it too. The catch is that an agent which reads AGENTS.md instead of CLAUDE.md (Codex, for example) would get only this rule and none of the build, architecture or PR guidance. Options:

  • A: no AGENTS.md. Put the rule in the README's ## Development section, which humans and agents both read, with a one-line pointer from CLAUDE.md.
  • B: keep AGENTS.md, and in a follow-up PR make it the complete guide (move CLAUDE.md into it, leaving CLAUDE.md as @AGENTS.md).
  • C: as is.

Precedent: saorsa-transport, saorsa-core and evmlib already keep a full AGENTS.md next to CLAUDE.md, the two cross-linked with the same core content (saorsa-transport also has GEMINI.md). V2-1640 documented its exemptions in both files. ant-client, ant-node and ant-protocol have only CLAUDE.md. That precedent points to B, and an AGENTS.md holding only this rule would match none of the other repos. I'll change it to whichever you pick.

Linear issue

Closes V2-1107

Risk tier

  • T0 — docs / tooling / CI / pure UX-output. Repo CI only.
  • T1 — client-only, no network-facing behavior change. CI + prod compat smoke.
  • T2 — node/client logic with behavioral surface, no protocol/format/economics change. Dev testnet + ADR.
  • T3 — protocol / storage format / payments / routing. T2 evidence + adversarial testing.

Compatibility

  • Wire: none
  • Storage: none
  • API: none. Only the release workflow's notes step, a new script, a new AGENTS.md and a one-line import in CLAUDE.md change.

Semver impact

  • breaking
  • feature
  • fix

Test evidence

New dependency

none

ADR

n/a

Mitigation / rollback

Revert. The workflow goes back to placeholder notes, and the script is unused until the cut tooling calls it.

🤖 Generated with Claude Code

Nic-dorman and others added 2 commits October 22, 2026 13:26
…tion script

The release workflow ships the CHANGELOG section matching the tag's base
version, but nothing at the train cut ever rotates `[Unreleased]` into that
section, so every tag from ant-cli-v0.3.7 to ant-cli-v0.3.12-rc.1 shipped the
"No changelog entry was recorded" placeholder.

- scripts/rotate-changelog.sh X.Y.Z moves `[Unreleased]` into
  `## [X.Y.Z] - <date>`, for the cut tooling to run on the rc branch. It is
  idempotent across rc re-cuts and never fails on an empty `[Unreleased]`.
- With no matching section, the workflow now publishes GitHub's generated list
  of PRs merged since the previous stable ant-cli tag instead of the
  placeholder, still with the `::warning::` annotation. The placeholder is kept
  only for when that API call fails.
- CLAUDE.md says where entries go and who writes the versioned heading.

Refs V2-1107.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sees it

CLAUDE.md imports it with @AGENTS.md, so Claude Code still loads it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant