release

star 261

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.

pwrdrvr By pwrdrvr schedule Updated 3/18/2026

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 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

Use this skill for repos that publish from GitHub Releases and want human-written notes instead of GitHub's generated summary.

Guardrails

  • Prefer the repo's default branch from gh repo view; do not guess.
  • Start from a clean working tree. If tracked files are dirty, stop and ask before continuing.
  • If the current branch is not the default branch, stop and ask before switching.
  • Fetch before planning: git fetch origin --tags.
  • 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 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

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:

# 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
  • .local/release/release-plan.md

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 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

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 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.

Notes And Changelog Rules

  • Do not copy PR titles verbatim into release notes.
  • 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 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.
  • Use a heading in this shape:
## v0.1.0 - 2026-03-15
  • If you make a dedicated changelog commit, use a subject like:
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.

  • Default to a minor bump: v0.1.0 -> v0.2.0.
  • 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:

  • the last release is recent
  • there are only a few meaningful commits
  • the included changes are patch-sized fix/docs/ci/chore/deps style work
  • there is no obvious feature or larger performance/restructure change

Execution Flow

  1. Prepare the repo.
git fetch origin --tags
default_branch=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')
current_branch=$(git branch --show-current)
test "$current_branch" = "$default_branch"
git pull --ff-only origin "$default_branch"
python3 .agents/skills/release/scripts/release_plan.py --output-dir .local/release

For a beta prerelease:

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

For promotion from an existing beta tag:

python3 .agents/skills/release/scripts/release_plan.py --promote-from v0.2.0-beta.2 --output-dir .local/release
  1. Read .local/release/release-plan.md and summarize the proposed release for approval.

  2. After approval:

  • 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
  1. If you updated CHANGELOG.md, commit and push the changelog commit on top of the planned source tip.
git add CHANGELOG.md
git commit -m "docs: add changelog for <tag>"
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:

release_sha=$(jq -r '.planning.baseSha' .local/release/release-plan.json)
  1. Create the release from that exact commit.

Stable:

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

Prerelease:

gh release create "<tag>" \
  --prerelease \
  --target "$release_sha" \
  --title "<tag>" \
  --notes-file .local/release/release-notes.md
  1. Verify the release and watch the publish workflow.
gh release view "<tag>"
run_id=$(gh run list --workflow publish.yml --event release --limit 10 --json databaseId,headSha,status,conclusion \
  --jq '.[] | select(.headSha == "'"$release_sha"'") | .databaseId' | head -n1)
gh run watch "$run_id"

If the publish workflow fails, inspect it yourself:

gh run view "$run_id" --log-failed

Best Practices

  • Re-read the generated notes before publishing; fix awkward wording instead of shipping raw commit text.
  • Keep release bullets user-facing and outcome-oriented, not implementation-jargon heavy.
  • 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.
Install via CLI
npx skills add https://github.com/pwrdrvr/openclaw-codex-app-server --skill release
Repository Details
star Stars 261
call_split Forks 35
navigation Branch main
article Path SKILL.md
More from Creator