Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 67 additions & 10 deletions .agents/skills/release/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: release
description: "Plan and publish a GitHub Release in a tag-driven repository. Use when a user asks to cut, prepare, or publish a software release, propose the next vX.Y.Z tag, draft better release notes from PRs and direct commits since the last release, update CHANGELOG.md, create the tag pinned to an exact commit, and watch the publish workflow."
description: "Plan and publish a GitHub Release in a tag-driven repository. Use when a user asks to cut, prepare, or publish a stable or prerelease, propose the next vX.Y.Z or vX.Y.Z-beta.N tag, draft better release notes from PRs and direct commits since the last release, update CHANGELOG.md when appropriate, create the tag pinned to an exact commit, and watch the publish workflow."
---

# Release
Expand All @@ -16,9 +16,12 @@ Use this skill for repos that publish from GitHub Releases and want human-writte
- Fast-forward the default branch before editing: `git pull --ff-only origin <default-branch>`.
- Never force-push the default branch.
- Never use GitHub generated release notes for this workflow.
- Always create the release tag with a leading `v`, for example `v0.1.0`.
- Always create the release tag with a leading `v`, for example `v0.1.0` or `v0.2.0-beta.1`.
- Always pin the release to the exact changelog commit SHA with `gh release create --target <sha>`.
- If `origin/<default-branch>` moves after planning or before pushing, stop and regenerate the release plan.
- For prereleases, use a semver prerelease tag that names the npm dist-tag you want, for example `v0.2.0-beta.1` -> npm `beta`.
- For prereleases, create the GitHub release with `--prerelease`.
- Prefer leaving `CHANGELOG.md` untouched for prereleases unless the user explicitly wants beta entries there; that keeps later promotion to stable cleaner.

## Helper Script

Expand All @@ -28,6 +31,19 @@ Use the bundled planner to gather release facts and raw note inputs:
python3 .agents/skills/release/scripts/release_plan.py --output-dir .local/release
```

Examples:

```bash
# Plan the next stable release.
python3 .agents/skills/release/scripts/release_plan.py --output-dir .local/release

# Plan the next beta prerelease for the upcoming stable line.
python3 .agents/skills/release/scripts/release_plan.py --channel beta --output-dir .local/release

# Promote an existing beta tag to a stable release from the same code base.
python3 .agents/skills/release/scripts/release_plan.py --promote-from v0.2.0-beta.2 --output-dir .local/release
```

It writes:

- `.local/release/release-plan.json`
Expand All @@ -38,9 +54,11 @@ The planner:
- finds the latest published semver release
- counts first-parent commits on the default branch since that release
- filters leaked release-housekeeping commits such as changelog-only commits
- proposes the next tag
- proposes the next stable tag, prerelease tag, or promotion target
- groups PR-backed changes separately from direct commits on `main`
- captures contributor mentions for PR-backed items
- when planning a prerelease, increments tags like `v0.2.0-beta.1`, `v0.2.0-beta.2`, and so on
- when planning a promotion, pins the plan to the exact prerelease tag commit instead of whatever is now at `origin/<default-branch>`

## Approval Prompt

Expand All @@ -49,8 +67,9 @@ Before making any changelog edit, commit, push, tag, or release, show the user:
- the last release tag
- the raw and meaningful commit counts since that release
- the suggested new tag and why
- whether the change looks like a minor release or a small emergency patch
- the exact commit SHA currently at `origin/<default-branch>`
- whether the change looks like a stable minor, a small emergency patch, a prerelease, or a prerelease promotion
- the exact commit SHA currently targeted by the release plan
- for prereleases, the npm dist-tag that will be used instead of `latest`

If the meaningful commit count is less than `3`, explicitly warn that there are not many changes in this release and ask whether they still want to proceed.

Expand All @@ -60,7 +79,7 @@ If the meaningful commit count is less than `3`, explicitly warn that there are
- Rewrite each PR-backed item into a clearer user-facing bullet.
- For direct commits on `main` with no PR, use the commit subject and body as raw input and rewrite those too.
- Add the PR author mention on the same line for PR-backed entries.
- Keep the same substance in `CHANGELOG.md` and the GitHub release notes.
- Keep the same substance in `CHANGELOG.md` and the GitHub release notes for stable releases.
- Prefer grouped sections such as `Highlights`, `Fixes`, `Performance`, `Docs`, and `Internal` when they fit the release.
- If `CHANGELOG.md` does not exist, create it with a `# Changelog` header.
- Insert the new release section at the top, directly under the file header if there is one.
Expand All @@ -76,6 +95,9 @@ If the meaningful commit count is less than `3`, explicitly warn that there are
docs: add changelog for v0.1.0
```

- For prereleases, prefer writing only `.local/release/release-notes.md` and skipping a changelog commit unless the user explicitly wants prerelease changelog entries.
- For promotion from `vX.Y.Z-beta.N` to `vX.Y.Z`, either tag the same prerelease commit for exact code parity or add only changelog/release-note edits on top before creating the stable tag.

## Versioning Heuristic

Use the planner's suggestion unless the user overrides it.
Expand All @@ -84,6 +106,9 @@ Use the planner's suggestion unless the user overrides it.
- Use a patch bump only for a small hotfix shortly after the previous release.
- Treat `v0.9.0` -> `v0.10.0` as the normal next minor bump.
- Do not jump from `v0.9.0` to `v1.0.0` unless the user explicitly asks.
- For prereleases, keep the stable base and add a channel suffix such as `v0.2.0-beta.1`.
- The prerelease channel name becomes the npm dist-tag, so `v0.2.0-beta.1` publishes to `@beta` and does not replace `@latest`.
- Promotion removes the prerelease suffix: `v0.2.0-beta.2` -> `v0.2.0`.

The bundled planner treats a patch release as the default only when all of these are true:

Expand All @@ -105,14 +130,27 @@ git pull --ff-only origin "$default_branch"
python3 .agents/skills/release/scripts/release_plan.py --output-dir .local/release
```

For a beta prerelease:

```bash
python3 .agents/skills/release/scripts/release_plan.py --channel beta --output-dir .local/release
```

For promotion from an existing beta tag:

```bash
python3 .agents/skills/release/scripts/release_plan.py --promote-from v0.2.0-beta.2 --output-dir .local/release
```

2. Read `.local/release/release-plan.md` and summarize the proposed release for approval.

3. After approval, write:
3. After approval:

- `.local/release/release-notes.md`
- `CHANGELOG.md`
- always write `.local/release/release-notes.md`
- for stable releases, update `CHANGELOG.md`
- for prereleases, skip `CHANGELOG.md` unless the user explicitly wants prerelease changelog entries

4. Commit and push the changelog commit on top of the planned branch tip.
4. If you updated `CHANGELOG.md`, commit and push the changelog commit on top of the planned source tip.

```bash
git add CHANGELOG.md
Expand All @@ -121,10 +159,28 @@ git push origin HEAD:"$default_branch"
release_sha=$(git rev-parse HEAD)
```

If you did not update `CHANGELOG.md`, release directly from the planned SHA:

```bash
release_sha=$(jq -r '.planning.baseSha' .local/release/release-plan.json)
```

5. Create the release from that exact commit.

Stable:

```bash
gh release create "<tag>" \
--target "$release_sha" \
--title "<tag>" \
--notes-file .local/release/release-notes.md
```

Prerelease:

```bash
gh release create "<tag>" \
--prerelease \
--target "$release_sha" \
--title "<tag>" \
--notes-file .local/release/release-notes.md
Expand Down Expand Up @@ -152,3 +208,4 @@ gh run view "$run_id" --log-failed
- Mention direct-to-main commits that would otherwise be invisible to GitHub's PR-based notes.
- If the approval gap was long, rerun the planner immediately before editing `CHANGELOG.md`.
- If the push to the default branch is rejected, stop and regenerate notes from the new branch tip instead of rebasing blindly.
- For prerelease promotion, do not mix new product commits into the promotion step. Either tag the exact beta commit or keep follow-up changes limited to changelog/release metadata.
2 changes: 1 addition & 1 deletion .agents/skills/release/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
interface:
display_name: "Release"
short_description: "Plan and publish a GitHub release with a real changelog"
default_prompt: "Use $release to prepare a GitHub Release, propose the next vX.Y.Z tag, draft better notes than GitHub's defaults, update CHANGELOG.md, and publish from the exact changelog commit."
default_prompt: "Use $release to prepare a GitHub release, whether stable or prerelease. Propose the next vX.Y.Z or vX.Y.Z-beta.N tag, draft better notes than GitHub's defaults, update CHANGELOG.md when appropriate, publish from the exact target commit, and preserve an upgrade path from beta to stable on the same code base."
Loading