ffroliva/gflow-cli/skills/release/SKILL.md
release
Cut a new gflow-cli release — bump version, update CHANGELOG, tag, push, and back-merge.
- Source repository stars
- 96
- Declared platforms
- 0
- Static risk flags
- 3
- Last source update
- 2026-08-04
- Source checked
- 2026-08-04
Decision brief
What it does—and where it fits
Follow this sequence verbatim. Every step matters.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/ffroliva/gflow-cli --skill "skills/release"Inspect the Agent Skill "release" from https://github.com/ffroliva/gflow-cli/blob/c64a8d8b246f9551e8a96c7fcf363d15e045c9b2/skills/release/SKILL.md at commit c64a8d8b246f9551e8a96c7fcf363d15e045c9b2. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
doc-review version-currency fixes often also touch ROOT docs — stage them too:
git add README.md PLAN.md KNOWNISSUES.md AGENTS.md llms.txt 2/dev/null || true git status --short review EVERYTHING staged before committing git commit -m "chore(release): v" bash git tag -s v -m "v" bash git cat-file -p v | grep -c "BEGIN SSH SIGNATURE" expect 1 (or "BEGIN PGP…
Tag push triggered .github/workflows/release.yml.Watch for the release workflow.On success: PyPI publish + GitHub Release with auto-generated notes. - 02
Pipeline Continuation (Next Step Handoff)
Upon completing a Release: 1. Proactively announce: "Release v shipped to PyPI & GitHub Releases! Back-merge to develop complete. Next step: Phase 1 Triage (/gflow:issue-assessment ) for the next development cycle."
Proactively announce: "Release v shipped to PyPI & GitHub Releases! Back-merge to develop complete. Next step: Phase 1 Triage (/gflow:issue-assessment ) for the next development cycle."Upon completing a Release: 1. Proactively announce: "Release v shipped to PyPI & GitHub Releases! Back-merge to develop complete. Next step: Phase 1 Triage (/gflow:issue-assessment ) for the next development cycle." - 03
Inputs
Ask the user (if not already provided):
Version — the new version (e.g. 0.4.0, 0.4.0a3, 1.0.0rc1). Use PEP 440 prerelease suffixes (aN, bN, rcN). If they don't know, run /gflow:changelog first and propose the next bump (PATCH for fixes only, MINOR for new fea…Pre-release? — prerelease versions stay marked as GitHub prereleases. Only the user can say when a release line is ready for the stable tag.Ask the user (if not already provided): - 04
Sequence
1. Review what's queued.
Auto-injected boilerplate (e.g. a context-mode routing block appended toBuild/temp artifacts (e.g. a stray tmp.tar.gz sdist at repo root): delete them.Genuine uncommitted work: STOP and tell the user to commit or stash on the - 05
Critical reminders
ALWAYS cut the release branch from develop, not main — develop carries the work.
ALWAYS cut the release branch from develop, not main — develop carries the work.NEVER --squash the release PR into main — it destroys the integration history the branch carries. Use --merge.NEVER skip the main → develop back-merge (step 15) — skipping it guarantees conflicts at the next release.
Permission review
Static risk signals and limitations
Runs scripts
The documentation asks the agent to run terminal commands or scripts.
git status --shortRuns scripts
The documentation asks the agent to run terminal commands or scripts.
git fetch originWrites files
The documentation asks the agent to create, modify, or delete local files.
Update the link footer. Match the repo's existing convention — every prior entryNetwork access
The documentation includes network, browsing, or remote request actions.
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v<NEW_VERSION>...HEADNetwork access
The documentation includes network, browsing, or remote request actions.
[<NEW_VERSION>]: https://github.com/ffroliva/gflow-cli/compare/v<PREV_VERSION>...v<NEW_VERSION>Writes files
The documentation asks the agent to create, modify, or delete local files.
for all, create an allowed-signers file (`<your-email> ssh-rsa AAAA...`) and runEvidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 87/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 96 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- ffroliva/gflow-cli
- Skill path
- skills/release/SKILL.md
- Commit
- c64a8d8b246f9551e8a96c7fcf363d15e045c9b2
- License
- MIT
- Collected
- 2026-08-04
- Default branch
- develop
View the original SKILL.md
/gflow:release — Cut a new release
Follow this sequence verbatim. Every step matters.
Branch-protection note:
mainblocks direct pushes. The release commit travels via achore/release-vX.Y.Zbranch PR. The signed tag is pushed independently (tag pushes bypass branch protection and trigger the CI release workflow immediately).Source-branch note (read first):
developis the integration branch — it carries ALL unreleased work andmainusually lags it. The release branch is cut fromdevelop, NOTmain. The PRchore/release-vX.Y.Z → mainthen brings the full integration history ontomain. Do not expect the work to already be onmain.
Inputs
Ask the user (if not already provided):
- Version — the new version (e.g.
0.4.0,0.4.0a3,1.0.0rc1). Use PEP 440 prerelease suffixes (aN,bN,rcN). If they don't know, run/gflow:changelogfirst and propose the next bump (PATCH for fixes only, MINOR for new features, MAJOR for breaks). - Pre-release? — prerelease versions stay marked as GitHub prereleases. Only the user can say when a release line is ready for the stable tag.
Sequence
1. Review what's queued.
Run /gflow:changelog — confirm the [Unreleased] block is non-empty and accurate before proceeding.
2. Verify (or triage) a clean working tree.
git status --short
If empty, continue. If not, triage before aborting — do not blindly stop:
- Auto-injected boilerplate (e.g. a context-mode routing block appended to
CLAUDE.mdby an MCP plugin's SessionStart hook): this is plugin-injected, not project content —git restoreit. Confirm with the user if unsure. - Build/temp artifacts (e.g. a stray
tmp*.tar.gzsdist at repo root): delete them. - Genuine uncommitted work: STOP and tell the user to commit or stash on the
appropriate branch (never commit straight to
develop).
The tree must be clean before you create the release branch.
3. Verify develop is the release source and up-to-date.
The release is cut from develop, NOT main (see Source-branch note above).
Confirm direction explicitly — a backwards divergence means a prior back-merge was skipped.
git fetch origin
git rev-parse --abbrev-ref HEAD # expect "develop"
git rev-list --count HEAD..origin/develop # local behind origin — expect 0
git rev-list --count origin/main..origin/develop # develop AHEAD of main — expect > 0 (the work to release)
git rev-list --count origin/develop..origin/main # main AHEAD of develop — expect 0
If not on develop: git checkout develop && git pull origin develop.
If local is behind origin: git pull origin develop.
If main is AHEAD of develop (last count > 0): STOP. A prior release skipped its
main → develop back-merge — recover first (see the release-back-merge-gap-recovery
memory) or the release branch will hit conflicts on pyproject.toml / __init__.py / CHANGELOG.md.
4. Run quality gates.
Run /gflow:check — all gates must pass. Abort if any fail.
4b. Live-verify the release's user-facing features (REQUIRED gate).
For every new/changed user-facing feature in this release, exercise it against
live Flow (credit-free wherever possible — image gen, entity attach, upscale, and
scene/timeline ops cost no Veo credits) and write the evidence to
docs/LIVE_VERIFICATION_v<NEW_VERSION>.md using the 5-layer ledger (file count +
magic bytes + dimensions/shape + structlog invariants + a user-confirmable
artifact). Add it to the "what was live-verified" entry in docs/INDEX.md. This
doc shipped for every release v0.7.0→v0.13.0, then lapsed for v0.14.0–v0.15.1 —
which is why it is now an explicit gate. If a feature genuinely cannot be verified
this cycle, record that and the reason in the doc; never silently omit it. Stage
the doc into the release-prep commit (step 11).
5. Create a release branch off develop.
git checkout develop # ensure the base is develop, not main
git checkout -b chore/release-v<NEW_VERSION>
This branch now contains all of develop (⊇ main) plus your release prep. All
release prep commits live here; the PR into main (step 14) carries the full
integration history forward.
6. Bump the shared release version in pyproject.toml and
.codex-plugin/plugin.json:
[project]
version = "<NEW_VERSION>"
{
"version": "<NEW_VERSION>"
}
7. Bump package version in src/gflow_cli/__init__.py:
__version__ = "<NEW_VERSION>"
8. Update version assertion tests if present:
rg -n "__version__|<OLD_VERSION>|version assertion" tests src pyproject.toml .codex-plugin/plugin.json
9. Migrate CHANGELOG.
- Move all entries under
## [Unreleased]to a new## [<NEW_VERSION>] — YYYY-MM-DDsection. - Leave
## [Unreleased]empty. - Update the link footer. Match the repo's existing convention — every prior entry
uses the
compare/vPREV...vNEWform, so use that for the new version too (NOT thereleases/tag/form), or/gflow:doc-reviewwill flag the inconsistency:[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v<NEW_VERSION>...HEAD [<NEW_VERSION>]: https://github.com/ffroliva/gflow-cli/compare/v<PREV_VERSION>...v<NEW_VERSION>
10. Run the documentation review gate.
Run /gflow:doc-review — audit all version refs, INDEX completeness, evidence files, the published website/docs/ mirror (PII gate + content-drift check, §4b), code↔docs parity via git log (§4c), skill files, CHANGELOG footer, and memory files. Fix every FAIL before continuing. Fold all discovered fixes into the release prep commit — including any website/docs/ re-sync (the mirror is anonymized and hand-synced; a canonical doc change this release must be mirrored, and CHANGELOG.md must never appear under website/docs/).
Also consolidate shipped planning artifacts here: extract any durable patterns
into auto-memory, then remove the now-shipped docs/superpowers/ plan / spec /
verification files (keep only in-flight work). check_repo_hygiene.py enforces the
root-doc allowlist, so a stray review doc or session marker left at the repo root
will fail the gate.
11. Commit the release prep.
git add pyproject.toml .codex-plugin/plugin.json src/gflow_cli/__init__.py uv.lock CHANGELOG.md
git add docs/ website/docs/ skills/ .claude/commands/gflow/ # include any doc-review + mirror fixes
# doc-review version-currency fixes often also touch ROOT docs — stage them too:
git add README.md PLAN.md KNOWN_ISSUES.md AGENTS.md llms.txt 2>/dev/null || true
git status --short # review EVERYTHING staged before committing
git commit -m "chore(release): v<NEW_VERSION>"
uv.lockchanges on every version bump (the editable package version is pinned in the lockfile) — it is easy to forget and must ship in this commit..codex-plugin/plugin.jsontracks the package version so marketplace installs receive a new cache path for every release.- The release-prep commit must NOT carry a
Co-Authored-Bytrailer (see reminders).
12. Tag the release commit. Use -s for a signed annotated tag so GitHub shows "Verified" AND .github/workflows/release.yml passes the signed-tag gate (unsigned or lightweight tags are rejected by CI).
git tag -s v<NEW_VERSION> -m "v<NEW_VERSION>"
Signing requirements:
- SSH signing (preferred):
git config --global gpg.format ssh+user.signingkeypointing at your public key. - GPG: any registered GPG key works.
- Run
git config --global user.signingkeyto confirm a key is configured.
Confirm the tag actually carries a signature (this is what CI checks):
git cat-file -p v<NEW_VERSION> | grep -c "BEGIN SSH SIGNATURE" # expect 1 (or "BEGIN PGP SIGNATURE" for GPG)
Benign local-verify error:
git tag -v v<NEW_VERSION>may fail withgpg.ssh.allowedSignersFile needs to be configured. This is a local verification-config gap only — the tag IS validly signed and CI still passes (CI greps for the signature header, above). To make local verify work once and for all, create an allowed-signers file (<your-email> ssh-rsa AAAA...) and rungit config --global gpg.ssh.allowedSignersFile <path>. See therelease-signingmemory for the exact recipe. Do NOT treat this error as a signing failure.
13. Push the tag first (bypasses branch protection; triggers the CI release workflow immediately):
⚠ POINT OF NO RETURN — confirm with the user before this push. Pushing the tag immediately triggers
.github/workflows/release.yml→ PyPI publish + public GitHub Release. A pushed release tag must NOT be force-replaced (ship a PATCH instead). Get an explicit go-ahead, then push.
git push origin v<NEW_VERSION>
CI will start building the release. Watch https://github.com/ffroliva/gflow-cli/actions.
Wait for the Release run to report completed / success and confirm the GitHub
Release published before continuing (gh release view v<NEW_VERSION>).
14. Push the release branch and open the PR.
git push -u origin chore/release-v<NEW_VERSION>
gh pr create --base main --head chore/release-v<NEW_VERSION> \
--title "chore(release): v<NEW_VERSION>"
Wait for PR CI to go green (gh pr checks <N> --watch). The SonarCloud analysis
check must be green (gate passed) — not just the test matrix. If it is red or you
want the verdict, run /gflow:sonar <N> and drive it to zero before merging. Then
merge with a merge commit — never squash:
gh pr merge <N> --merge --delete-branch
NEVER
--squashthis PR. Because the branch was cut fromdevelop, the PR carries the entire batch of unreleased integration commits. A squash collapses them into one opaque commit onmainand destroys that history.--mergepreserves it. (The release workflow already ran from the tag push in step 13 — this PR is to bring the bump commit + integration history ontomain.)
15. Back-merge main into develop.
After the release PR is merged, bring the bump commit back to develop so branches stay aligned:
git checkout develop
git pull origin develop
git fetch origin main
git merge origin/main --no-ff -m "chore: back-merge main (v<NEW_VERSION>) into develop"
git push origin develop
If there are conflicts (rare — only if develop has commits that touched the same lines as the bump), resolve them, keeping develop's unreleased work and main's version bump.
16. Report.
Tell the user:
- Tag push triggered
.github/workflows/release.yml. - Watch https://github.com/ffroliva/gflow-cli/actions for the release workflow.
- On success: PyPI publish + GitHub Release with auto-generated notes.
- On failure (most common: PyPI Trusted Publishing not yet configured): point to https://pypi.org/manage/account/publishing/.
developis now synced withmain(back-merge done in step 15).- Next development cycle starts on
develop— open## [Unreleased]in CHANGELOG is ready.
Pipeline Continuation (Next Step Handoff)
Upon completing a Release:
- Proactively announce: "Release v<NEW_VERSION> shipped to PyPI & GitHub Releases! Back-merge to develop complete. Next step: Phase 1 Triage (
/gflow:issue-assessment <N>) for the next development cycle."
Critical reminders
- ALWAYS cut the release branch from
develop, notmain—developcarries the work. - NEVER
--squashthe release PR intomain— it destroys the integration history the branch carries. Use--merge. - NEVER skip the
main → developback-merge (step 15) — skipping it guarantees conflicts at the next release. - NEVER add
Co-Authored-By: Claude(or any AI co-author) to the release commit. - NEVER force-push a release tag once it's on GitHub. Ship a PATCH fix instead.
- NEVER
--no-verifypast hooks. Fix the underlying issue. - NEVER push directly to
main— branch protection will reject it. Always use a PR. - A
git tag -vallowedSignersFileerror is benign (verify-only) — the tag is still signed and CI passes. Don't treat it as a failure. - CONFIRM with the user before the step 13 tag push — it's the irreversible PyPI + public Release trigger.
- If quality gates fail at step 4, STOP. Surface the failures to the user.
- If doc-review fails at step 10, STOP. Fix before committing.
See also
- RELEASE.md — full release protocol, prerelease policy, and checklist
- README § Releases — release policy and cadence
- PLAN § Phase 5 — first-release exit criteria
Alternatives
Compare before choosing
arbiterForge/codeArbiter
release
The single permitted path to a version tag, for any target declared in the project's .codearbiter/release-targets.md. Routed to when the user invokes /release on a non-default branch with a green suite. Takes the declared target as its one argument, derives the SemVer bump from Conventional-Commits history since that target's last tag, rolls the commits into that target's CHANGELOG, writes an annotated tag in that target's namespace, and on authorization publishes it as a GitHub Release with the
arbiterForge/codeArbiter
release
The single permitted path to a version tag, for any target declared in the project's .codearbiter/release-targets.md. Routed to when the user invokes /release on a non-default branch with a green suite. Takes the declared target as its one argument, derives the SemVer bump from Conventional-Commits history since that target's last tag, rolls the commits into that target's CHANGELOG, writes an annotated tag in that target's namespace, and on authorization publishes it as a GitHub Release with the
arbiterForge/codeArbiter
release
The single permitted path to a version tag, for any target declared in the project's .codearbiter/release-targets.md. Routed to when the user invokes /release on a non-default branch with a green suite. Takes the declared target as its one argument, derives the SemVer bump from Conventional-Commits history since that target's last tag, rolls the commits into that target's CHANGELOG, writes an annotated tag in that target's namespace, and on authorization publishes it as a GitHub Release with the
arbiterForge/codeArbiter
release
The single permitted path to a version tag, for any target declared in the project's .codearbiter/release-targets.md. Routed to when the user invokes /release on a non-default branch with a green suite. Takes the declared target as its one argument, derives the SemVer bump from Conventional-Commits history since that target's last tag, rolls the commits into that target's CHANGELOG, writes an annotated tag in that target's namespace, and on authorization publishes it as a GitHub Release with the