microsoft/apm-cut-release
>- assess whether the cycle since the last tag warrants a patch or minor bump (semver discipline against the merged-since-last-tag diff), sanitize the [Unreleased] CHANGELOG block into a dated version block with one concise "so what" entry per merged PR (drop internal-only churn, consolidate duplicates), bump pyproject.toml + uv.lock, run the CI-mirror lint chain, and open the release PR. Activate on "ship a release", "cut v0.x", "release prep", "bump and PR", "open release PR", "what kind of release do we need", or any phrasing that ends in opening a release PR -- even when the user does not say "skill". Stops BEFORE tagging; tagging stays a human gate that triggers the release workflow. Refuses to bump to a major (>= 1.0.0) version without explicit operator confirmation.
This is a copy. The original lives at microsoft/cut-release.
npx skills add https://github.com/microsoft/apm --skill cut-release
This skill drives the release-cut workflow end-to-end on the current
worktree. It STOPS at "PR open"; tagging is the human-gated trigger
that fires the release workflow.
Trigger this skill on any of these intents:
Do NOT trigger on:
The skill DEPENDS on these existing primitives in the same source
tree. Do not duplicate their content; reference them.
.apm/skills/apm-strategy/SKILL.md -- versioning judgement andbreaking-change lens. Auto-loads via its own trigger on
CHANGELOG.md and release-pipeline edits. Treat it as the
authoritative lens for "is this BREAKING" and "does this
positioning change warrant a migration note".
.apm/instructions/linting.instructions.md -- canonicalCI-mirror lint chain. Reference; do not re-derive ruff / pylint
command lists in this skill.
.github/instructions/changelog.instructions.md -- Keep-a-Changelog format contract. Reference; do not redefine the
format.
Per .github/instructions/encoding.instructions.md, source files in
this bundle (SKILL.md, assets, scripts) MUST stay in printable ASCII.
The PR body and changelog entries this skill produces are also
written to repo files (CHANGELOG.md, PR body), so they MUST stay
ASCII too. Use -- for em dashes, [!] / [+] / [x] for status
markers, and so on.
Run these phases in order. Reload plan.md (the session memento)
at the start of each phase and after every tool return.
git rev-parse --abbrev-ref HEAD.The skill assumes you are on a release-prep branch (or are
willing to create one). If you are on main, STOP and ask the
operator to put you on a branch.
git describe --tags --abbrev=0.<last-tag>..HEAD.bumped beyond what the cycle warrants.
Run scripts/list-changes-since-tag.sh (no arguments). It emits
JSON on stdout: one object per merged PR with fields pr, title,
labels, author, paths_summary, is_user_facing_guess.
The script's heuristic for is_user_facing_guess is
intentionally conservative -- it flags as INTERNAL only when the
diff is fully contained in .apm/, .github/instructions/,
tests/, docs/, or matches chore(repo). Treat the field as a
HINT, not a verdict; the LLM makes the final call per
assets/entry-sanitizer.md.
DO NOT rely on training-recalled PR titles. Truth #5: pretraining
is frozen. Every PR title in the changelog must come from the
script's stdout.
Load assets/semver-rubric.md. Walk every PR from Phase 1
against the rubric. The rubric outputs PATCH, MINOR, or
ESCALATE-TO-MAJOR.
Show the operator:
If the rubric outputs ESCALATE-TO-MAJOR (>= 1.0.0), STOP and
surface the escalation per assets/semver-rubric.md "Major bump"
section. Do not bump to 1.0.0 without explicit operator
confirmation.
Wait for the operator's confirm before continuing.
Load assets/entry-sanitizer.md. For each PR classified as
user-facing in Phase 1:
Changed (behavior change in existing surface), Fixed (bug fix),
Deprecated, Removed, Security, Performance.
PR number in parentheses at the end. Preserve by @author for
external contributors.
the same PR.
the rubric in entry-sanitizer.md confirms).
BREAKING: prefix.Rewrite the CHANGELOG.md [Unreleased] block in place:
## [Unreleased]
## [X.Y.Z] - YYYY-MM-DD
### Added
...
### Changed
...
### Fixed
...
Keep an empty [Unreleased] placeholder above the new version
heading. The date is today (read from the operator's environment,
not recall).
Show the operator the unified diff against CHANGELOG.md. Wait for
confirm before continuing.
Run scripts/bump-version.sh <new-version>. The script edits
pyproject.toml (the version = "..." line in [project]) and
runs uv lock to refresh uv.lock. It prints a unified diff to
stdout for human review.
If the script exits non-zero, surface the error and STOP -- do not
continue with a partial bump.
Run scripts/verify-lint-mirror.sh. It mirrors the four CI lint
steps from .apm/instructions/linting.instructions.md verbatim
(ruff check, ruff format --check, pylint R0801, auth-signals).
If it passes (exit 0), proceed to Phase 6.
If it fails (exit 1), STOP. Surface the failures to the operator.
Common cures:
tests/ --fix and uv run --extra dev ruff format src/ tests/`.
merge main first, then re-run.
scripts/lint-auth-signals.sh output.Do NOT push or open the PR until lint is green. The PR description
will claim CI is green; that claim must hold.
git add CHANGELOG.md pyproject.toml uv.lock.git commit -m "chore: release vX.Y.Z" -m "<short body>".The body mirrors prior release commits (#1410, #1454, #1526):
one paragraph naming what was bumped and the lint-mirror
confirmation, plus the "post-merge: tag vX.Y.Z" reminder.
Include the standard Co-authored-by trailer.
git push -u origin HEAD.assets/pr-body-template.md,substituting {version} (unprefixed, e.g. 0.16.1 -- used by
CHANGELOG.md and pyproject.toml), {tag} (v-prefixed, e.g.
v0.16.1 -- used by the post-merge git tag block, since the
release workflow's stable-release regex requires the v prefix
per .github/workflows/build-release.yml), {date},
{bump_rationale}, and (if BREAKING) {breaking_summary}.
"chore: release vX.Y.Z" --body-file <tmpfile>`.
vX.Y.Z to trigger the release workflow." Do NOT tag.
Mark each plan.md todo as done. The session ends here. Tagging is
the operator's decision and lives outside this skill.
tag inside this session, decline and remind the operator that
the release workflow expects git tag vX.Y.Z && git push --tags
after PR merge.
decision. ESCALATE per assets/semver-rubric.md.
a PR title from scripts/list-changes-since-tag.sh stdout. No
recall.
sanitized changelog, lint-fail recovery). Do not ask per-PR or
per-section.
asserts green CI; pushing red breaks the contract.
trivial. The lint mirror catches code-duplication drift on the
merge commit, which is invisible to a local diff inspection.
This skill does NOT:
that by activating this skill.
apm-review-panelbefore activating this skill if a recent PR needs review).
Take microsoft/apm-cut-release from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.