Skip to content

Release workflow: curated notes support, input-handling hardening, and CLAUDE.md - #28

Merged
jfrench9 merged 5 commits into
mainfrom
chore/curated-release-notes
Aug 4, 2026
Merged

Release workflow: curated notes support, input-handling hardening, and CLAUDE.md#28
jfrench9 merged 5 commits into
mainfrom
chore/curated-release-notes

Conversation

@jfrench9

@jfrench9 jfrench9 commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

tag-release.yml builds the GitHub release body from a Claude-generated changelog of git diff <last-tag>..HEAD. That is the right default for routine patch releases, but a milestone release deserves notes written by hand.

This adds an opt-in path: if .github/release-notes/v<version>.md exists at the tagged ref, it becomes the release body verbatim.

Mechanism

  1. New step Check for curated release notes (id: curated-notes) runs right after the tag-existence check and sets found / path.
  2. Generate changelog with Claude and Call Claude API for changelog gain && steps.curated-notes.outputs.found != 'true' — when curated notes exist, no Claude API call is made at all.
  3. New step Compose release body writes /tmp/release_changelog.md (curated file or generated changelog) and /tmp/release_body.md (the full body).
  4. Create GitHub Release switches from an inline body: block to body_path: /tmp/release_body.md, and the step summary reads the changelog file instead of interpolating an output.

With curated notes present, the "📊 Release Statistics" block and the "🤖 Generated with Claude Code" footer are skipped — a hand-written milestone note shouldn't be followed by a commit-count table. The # @robosystems/report-components v<version> header and the "🔗 Links" section (npm, full changelog, all releases) are always included.

Default path is unchanged

With no curated file, the composed body is byte-for-byte identical to the current inline template — same header, changelog, stats fields (Commits / Files Changed / Components Updated / Styles Updated / Lines Added / Lines Deleted / Previous Release), links and footer. Verified by rendering main's inline body: template and the new compose script with the same inputs and diffing: identical.

Why the filename is version-specific

The file is looked up by exact version (v1.0.0.md, not latest.md), so a leftover notes file can never leak into a later release — v1.0.1 simply won't find v1.0.0.md and falls back to the generated changelog. Nothing to clean up after a milestone.

Changelog content — generated or curated — is passed to the shell through env vars and written with printf/cat, never spliced in via ${{ ... }} (same # SECURITY (H2) discipline used elsewhere in these workflows).

Test plan

  • yamllint clean apart from the file's pre-existing line-length/document-start style warnings; step graph parses with the expected if: conditions.
  • Generated mode (no curated file): composed body diffed against main's inline template with identical inputs — byte-for-byte identical, including a changelog containing shell metacharacters.
  • Curated mode: body is header + curated file + links, with the statistics block and the Claude footer omitted.
  • Local pre-commit suite (format / lint / typecheck / 109 tests) green.
  • Confirmed on the next create-release.yml dispatch (no curated file → unchanged output).

Aligns this repo with roboledger-app PR #280.

Also in this PR

  • Input handling — the changelog step in tag-release.yml now takes its git-derived values through the step's env: block.
  • CLAUDE.md at the repo root — a short orientation for agents working here: commands and the local hook gate, source layout, the adapter-seam and public-API conventions, and the release/publish flow, including the curated-notes convention this PR adds (previously documented only as a comment inside the workflow).
  • Credential and input handling — further hardening of how the release workflow passes its API key and version/tag values into shell steps.

@jfrench9 jfrench9 changed the title Support curated release notes for milestone releases Release workflow: curated notes support, input-handling hardening, and CLAUDE.md Aug 4, 2026
The curated-notes and hardening changes were written independently per
repository, which left the same logic expressed several different ways.
Normalise the shared parts so the nine copies stay diffable: identical
tag-existence test, identical curl invocation and continuation style,
one wording for the tag-selection and credential comments, and consistent
brace style. Drops an unused VERSION env entry from the analyze step.

No behaviour change; only formatting, comments, and a dead variable.
@jfrench9
jfrench9 merged commit 871e24e into main Aug 4, 2026
2 checks passed
@jfrench9
jfrench9 deleted the chore/curated-release-notes branch August 4, 2026 22:18
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