원클릭으로
finalize-release
// Use after a Release Please PR has been merged to enrich the auto-generated GitHub release with author tags, highlights, and new contributors, then trigger the docs site rebuild
// Use after a Release Please PR has been merged to enrich the auto-generated GitHub release with author tags, highlights, and new contributors, then trigger the docs site rebuild
| name | finalize-release |
| description | Use after a Release Please PR has been merged to enrich the auto-generated GitHub release with author tags, highlights, and new contributors, then trigger the docs site rebuild |
Finish a GitHub release after Release Please creates it. Adds author attribution, a user-facing highlights section, and a new contributors section, then triggers the docs site rebuild.
gh release view v<VERSION>
gh release view v<RECENT_PRIOR_VERSION> # e.g. one or two versions back, for format reference
gh api repos/{owner}/{repo}/compare/v<PREV>...v<VERSION> --paginate \
--jq '.commits[] | "\(.sha[0:7]) \(.author.login // "unknown") \(.commit.message | split("\n")[0])"'
Map each changelog entry to its primary author. Add (by @username) before the commit link in every line.
Then check for co-authors — Co-Authored-By: trailers in the commit body are not in .author.login:
gh api repos/{owner}/{repo}/compare/v<PREV>...v<VERSION> --paginate \
--jq '.commits[] | select(.commit.message | test("Co-authored-by"; "i")) | {sha: .sha[0:7], primary: (.author.login // "unknown"), trailers: ([.commit.message | scan("(?im)^Co-Authored-By:\\s*(.+)$")[]])}'
For each non-AI co-author trailer (skip Claude, Copilot, etc. — credit humans only):
Name <id+username@users.noreply.github.com>. The GitHub handle is the part after the +.gh api user/<id> --jq .login and use that one.(by @primary and @coauthor) — or (by @primary, @co1, and @co2) for multiple.gh api repos/{owner}/{repo}/releases/generate-notes \
-f tag_name=v<VERSION> -f previous_tag_name=v<PREV> --jq '.body'
If the output contains a "New Contributors" section, include it verbatim. If not, omit the section entirely.
Place this between the version heading and the changelog.
Rules:
> warning callout above the highlights (see v3.14.0 for format)Present the full release body to the user for review before pushing.
gh release edit v<VERSION> --notes "$(cat <<'EOF'
...
EOF
)"
gh workflow run "<Docs CI workflow name>" --ref main
gh run watch <RUN_ID> --exit-status
Wait for it to succeed before reporting done.
## [X.Y.Z](compare-url) (YYYY-MM-DD)
> optional breaking change callout
## Highlights
* <emoji> **Short title**
<One sentence, UX-focused.>
## Changelog
### Features
* **scope:** <emoji> description (by @author) ([hash](url))
### Bug Fixes
...
### Performance Improvements
...
### Miscellaneous Chores
...
## New Contributors
* @user made their first contribution in <PR URL>
**Full Changelog**: compare-url
| Mistake | Fix |
|---|---|
Missing (by @author) on entries | Cross-reference every entry against the compare API output |
| Missing co-authors | .author.login only returns the primary. Always scan commit bodies for Co-Authored-By: trailers |
| Crediting AI co-authors | Skip Claude, Copilot, etc. — release notes credit humans |
| Stale username when account was renamed | Two trailers with the same numeric ID = same user. Resolve via gh api user/<id> |
| Guessing new contributors | Always use generate-notes API — do not infer from git history |
| Technical jargon in highlights | Rewrite from the user's perspective — what changed for them? |
| Forgetting to trigger docs CI | Always run the docs workflow as the final step |