| name | publish |
| description | Use when the user invokes /evo:publish or asks to release a new version, ship a release, or publish a tag. Wraps the go-native self-healing release pipeline (`evolve release`) — pre-flight checks, auto-changelog, atomic ship, marketplace propagation poll, auto-rollback on failure. |
| argument-hint | <target-version> [--dry-run] [--no-rollback] [--skip-tests] [--max-poll-wait-s 300] |
/evo:publish
Canonical release entry point. Owns the full publish lifecycle: pre-flight → bump → changelog → ship → propagate → rollback-on-failure. NOT a synonym for "git push" — see docs/release-protocol.md for vocabulary.
What this skill does
When the user types /evo:publish 18.5.0 (or similar), invoke the go-native release pipeline with the target version. The pipeline owns every step (implementation: go/internal/releasepipeline/, journal under .evolve/release-journal/):
| Step | Operation | Failure → action |
|---|
| 1 | Pre-flight gate (evolve release-preflight) | exit non-zero; abort, no mutations |
| 2 | Auto-changelog | abort |
| 3 | Version bump (6 markers) | abort |
| 3.5 | Rebuild tracked binary go/evolve | abort |
| 4 | Consistency check (evolve release-consistency) | abort, files in working tree |
| 5 | Atomic ship | abort, nothing pushed |
| 6 | Marketplace propagation poll (up to 5 min default) | auto-rollback unless --no-rollback |
| 7 | Cache refresh | logged WARN; manual fix |
Steps 1–7 are the gh-free pipeline binary. It cannot see GitHub CI — it ends by printing a NOTE: GitHub CI is NOT verified by this pipeline advisory. CI gating is this skill's job (next section); never treat a green pipeline as a green CI.
CI gating (this skill adds what the binary cannot)
evolve release is self-contained and headless-safe, so it does not verify GitHub CI. This skill wraps the pipeline with two gh-based checks. If gh is unavailable, report "cannot verify CI — confirm manually" and stop; never silently skip.
Before invoking the pipeline — base CI must be green (catches "releasing from an already-red main", the v20.1.0 trigger):
gh run list --branch main --limit 1 --json headSha,status,conclusion,url
Require headSha == $(git rev-parse origin/main), status == "completed", conclusion == "success". Anything else → STOP with the run URL:
- in-progress → wait for it.
- failure → fix
main green first.
- stale SHA / local
main ahead of origin → you'd publish commits CI has never seen; push main and let CI run first, then release. (This is the same gate /evo:release runs; it is hoisted here so /evo:publish-direct callers are protected too.)
Also before invoking the pipeline — every LLM CLI must install AND the release binary must answer every core subcommand the installed skills shell out to. This is a deterministic, gh-free local gate (no network, no live LLM): it installs the Claude payload into a throwaway home, renders the Codex/agy projections, checks the Gemini in-repo layout, then smoke-runs each core subcommand on the running binary.
evolve release-verify-clis
Require exit 0 — every CLI row plus the binary:core-subcommands row reports OK. Anything else → STOP; the printed table names the failing target: a CLI whose install/projection broke, or a subcommand the binary no longer answers (the "installed skills silently break" regression). Fix forward before publishing. CI enforces the same matrix via the TestReleaseVerifyCLIMatrix_RealPayload e2e test (go workflow), so a red here predicts a red CI on the release commit.
After the pipeline reports success — the released commit's CI must go green AND the prebuilt binaries must publish. The release (goreleaser) workflow runs on the pushed tag, separately from the gh-free pipeline, so a goreleaser slip ships a binary-less release while evolve release reports success (the v21.1.0 trigger: 0 assets published, only caught by manual check). Watch all three workflows, then confirm the binaries actually landed:
sha=$(git rev-parse origin/main)
for wf in go CI release; do
rid=$(gh run list --commit "$sha" --workflow "$wf" --json databaseId -q '.[0].databaseId')
gh run watch "$rid" --exit-status || echo "RED: $wf on $sha"
done
gh release view --json assets -q '.assets[].name' | grep -q '\.tar\.gz$' \
|| echo "MISSING: no prebuilt binaries on the latest release — re-run: gh run rerun <release-run-id>"
- All green + binaries present → done. Report the run URLs + the published asset count (
gh release view --json assets -q '.assets | length').
go/CI red → the release is published but its CI is red. Do not auto-rollback a propagated release — fix forward: land the CI fix on main, then cut the next patch (/evo:publish <x.y.z+1>). Report the failing job + gh run view --log-failed excerpt.
release red or binaries MISSING → the release shipped without prebuilt binaries (the one-line installer keeps working via build-from-source, just slower). Fix forward: fix .goreleaser.yml/release.yml, then gh run rerun <release-run-id> if the tag is intact, else cut the next patch.
Invocation
/evo:publish 18.5.0
/evo:publish 18.5.0 --dry-run
/evo:publish 18.5.0 --skip-tests
/evo:publish 18.5.0 --no-rollback
/evo:publish 18.5.0 --max-poll-wait-s 600
The slash command translates to:
"$CLAUDE_PROJECT_DIR/go/evolve" release <args>
Optional hardening: --require-preflight runs the full-dry-run harness before any step; --strict-pass rejects WARN preflight verdicts.
When to use this skill
- Always for any version bump (patch, minor, major). The pipeline guarantees consistency, propagation, and rollback.
- Gate readiness first with
/evo:release (read-only checks: preflight, consistency, CI-green-on-main, no-WIP-commits) — it delegates here when green.
When NOT to use this skill
- Not for non-release commits. If you're committing a feature without bumping the version, use
/evo:commit (gated attestation → evolve ship --class manual). The release pipeline assumes a version bump and will fail-fast in preflight if <target> equals current.
- Not as a substitute for testing.
--skip-tests is for hot-fix scenarios where CI already verified. Routine releases must run the full preflight test suite.
Checking what /evo:publish would do (dry-run)
Operators new to the pipeline: always start with --dry-run to see the proposed changelog block, version bump diff, and lifecycle plan before mutating:
/evo:publish 18.5.0 --dry-run
The pipeline emits each step's proposed output without writing or committing.
Common failure modes
| Symptom | Likely cause | Fix |
|---|
preflight: target X not greater than current Y | Version already bumped, OR you typo'd the arg | Run cat .claude-plugin/plugin.json and confirm; pick a higher target |
preflight: most recent audit-report.md does not declare 'Verdict: PASS' | Last audit was WARN/FAIL or stale | Run a fresh audit cycle (evolve loop) or evolve subagent run auditor |
marketplace-poll: TIMEOUT after git push | Marketplace checkout didn't pull within deadline | Pipeline auto-rolls-back. Investigate: git -C ~/.claude/plugins/marketplaces/evo log --oneline | head |
SELF_SHA_TAMPERED on the next ship | Rebuilt binary pinned but not committed in the release | Known structural residue — see runtime-reference.md binary-rebuild procedure; fix tracked in the release-rebuild-binary-not-committed work package |
| Hand-curated CHANGELOG entry overwritten | (Won't happen) | Changelog step is idempotent — if ## [<version>] exists it skips |
Vocabulary refresher
If unsure what "publish" means in this project: open docs/release-protocol.md. The short version:
- push ≠ publish.
git push only moves a remote ref; publish runs the full lifecycle.
- ship is the per-commit primitive (
evolve ship --class manual|cycle); publish/release is the version lifecycle on top of it.
Implementation note
This skill is a thin wrapper over the go-native pipeline (evolve release, go/internal/releasepipeline/) plus the gh-based CI gating the binary can't do (the pipeline is intentionally gh-free so it stays headless/cron-safe). All evolve release flag semantics match the underlying command verbatim; the pre/post CI checks above are the skill's own and live only here. (History: through v8.13.x this wrapped legacy/scripts/release-pipeline.sh; the bash pipeline was deleted in the go-only consolidation and this skill now fronts its go-native successor.)