---
name: publish-release
description: Publish the currently-committed release by pushing master to origin, publishing to npm, tagging the commit with the package.json version, and pushing the tag. Use when the user asks to "publish the release", "push and publish", or invokes /publish-release. Stops immediately on any failure.
---

# Publish Release

## When to use

- After `/prepare-release` and the release commit have both been completed — this skill assumes the release commit (version bump + README entry + fix) is already `HEAD` on `master`.
- User asks to publish / ship / release to npm.
- User invokes `/publish-release`.

Run after `/prepare-release` + `/git-commit`, never in place of them. This skill does not run lint, tests, or modify any files.

## Workflow

Run steps in order. **If any step fails, stop immediately, report the failure, and do not proceed.** There is no rollback — each step is externally observable (a push, a publish, a tag on origin), so a mid-flight failure leaves the release in a partial state the user will need to reason about. Be explicit about which steps succeeded and which did not.

### 1. Pre-flight checks (parallel)

- `git rev-parse --abbrev-ref HEAD` — confirm the current branch is `master`. If not, stop and ask the user.
- `git status --short` — confirm the working tree is clean. If not, stop — the release commit must already exist as `HEAD`, with nothing else pending.
- Read the current version from `package.json` (this becomes the tag name).
- `git tag --list <version>` — confirm the tag does not already exist locally. If it does, stop.
- `git ls-remote --tags origin refs/tags/<version>` — confirm the tag does not already exist on the remote. If it does, stop.
- `git log -1 --format=%s` — capture the subject of the HEAD commit for the summary.

### 2. Push master to origin

Run `git push origin master`. **Stop on non-zero exit.** Report the output.

### 3. Publish to npm

Run `npm publish`. **Stop on non-zero exit.**

Notes:
- If the registry prompts for a one-time password (2FA OTP), relay the prompt to the user and wait for their input. Do not attempt to bypass 2FA.
- If the registry rejects with `403` or `You do not have permission`, stop and surface the full error — the user may need to `npm login` or check their credentials.
- If the registry rejects with `You cannot publish over the previously published versions`, stop — the version was not bumped correctly upstream of this skill.

### 4. Tag the release

Tags in this repo are bare version numbers (no `v` prefix) — verified against the existing tag list.

Run `git tag <version>` where `<version>` is the exact value read from `package.json` in step 1 (e.g., `3.26.2`, not `v3.26.2`).

**Stop on non-zero exit.**

### 5. Push the tag

Run `git push origin <version>`. **Stop on non-zero exit.**

### 6. Summary

Report to the user, concisely:
- The version that was published.
- Confirmation of: master pushed, npm publish succeeded, tag created, tag pushed.
- The release commit subject (from pre-flight).
- The npm package URL, if it can be derived from `package.json` name (`https://www.npmjs.com/package/<name>`).

## Things to watch for

- If step 2 (push master) succeeds but step 3 (npm publish) fails, the commit is on GitHub but not on npm. Do not tag — the user must either resolve the npm issue and re-run publish, or roll back the push.
- If step 3 (npm publish) succeeds but step 4 (tag) or step 5 (tag push) fails, the package is on npm but not tagged. Surface this clearly — the user needs to manually create / push the tag, and an un-tagged published release is a fix-it-now situation, not something to leave for later.
- Never use `--force`, `--no-verify`, or any flag that bypasses checks, even to recover from a mid-flight failure. Always ask the user.
- Never create or push tags for versions other than the one in `package.json`.
- Never run this skill on a branch other than `master` without explicit user confirmation.
