From 5eb24a300a52a8f0fd92ed7d57e30c65e9d2d19e Mon Sep 17 00:00:00 2001 From: Sebastien Taggart Date: Thu, 26 Mar 2026 17:06:10 -0400 Subject: [PATCH] Combine version and release skills into a single deploy skill Co-Authored-By: Claude Opus 4.6 (1M context) --- .agents/skills/deploy/SKILL.md | 238 ++++++++++++++++++++++ .agents/skills/release/SKILL.md | 155 --------------- .agents/skills/setup/SKILL.md | 7 +- .agents/skills/ship/SKILL.md | 4 +- .agents/skills/version/SKILL.md | 81 -------- .claude/commands/deploy.md | 233 ++++++++++++++++++++++ .claude/commands/release.md | 150 -------------- .claude/commands/setup.md | 7 +- .claude/commands/ship.md | 4 +- .claude/commands/version.md | 76 ------- .cursor/rules/deploy.mdc | 239 ++++++++++++++++++++++ .cursor/rules/release.mdc | 156 --------------- .cursor/rules/setup.mdc | 7 +- .cursor/rules/ship.mdc | 4 +- .cursor/rules/version.mdc | 82 -------- .gemini/skills/deploy/SKILL.md | 238 ++++++++++++++++++++++ .gemini/skills/release/SKILL.md | 155 --------------- .gemini/skills/setup/SKILL.md | 7 +- .gemini/skills/ship/SKILL.md | 4 +- .gemini/skills/version/SKILL.md | 81 -------- README.md | 16 +- config.schema.yaml | 26 +-- docs/branching.md | 21 +- docs/config-reference.md | 22 +-- docs/customization.md | 4 +- docs/index.md | 9 +- docs/skills/deploy.md | 69 +++++++ docs/skills/qa.md | 2 +- docs/skills/release.md | 53 ----- docs/skills/ship.md | 4 +- docs/skills/version.md | 56 ------ skills/{release.md => deploy.md} | 326 +++++++++++++++++-------------- skills/setup.md | 5 +- skills/ship.md | 2 +- skills/version.md | 98 ---------- templates/AGENTS.md.template | 11 +- 36 files changed, 1268 insertions(+), 1384 deletions(-) create mode 100644 .agents/skills/deploy/SKILL.md delete mode 100644 .agents/skills/release/SKILL.md delete mode 100644 .agents/skills/version/SKILL.md create mode 100644 .claude/commands/deploy.md delete mode 100644 .claude/commands/release.md delete mode 100644 .claude/commands/version.md create mode 100644 .cursor/rules/deploy.mdc delete mode 100644 .cursor/rules/release.mdc delete mode 100644 .cursor/rules/version.mdc create mode 100644 .gemini/skills/deploy/SKILL.md delete mode 100644 .gemini/skills/release/SKILL.md delete mode 100644 .gemini/skills/version/SKILL.md create mode 100644 docs/skills/deploy.md delete mode 100644 docs/skills/release.md delete mode 100644 docs/skills/version.md rename skills/{release.md => deploy.md} (56%) delete mode 100644 skills/version.md diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md new file mode 100644 index 0000000..c1887ed --- /dev/null +++ b/.agents/skills/deploy/SKILL.md @@ -0,0 +1,238 @@ +--- +name: deploy +description: Bump the project version, create a GitHub Release, and promote to production — handles both versioning and releasing in one step +--- + +> **Codex CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — perform any review steps inline. + +--- + +## What `/deploy` does + +`/deploy` is the final step in the workflow. It combines version bumping and release creation into a single command: check state, optionally bump the version, then create a GitHub Release (and in multi-branch mode, promote to production). + +--- + +## Step 1 — Verify branch + +Run: +```bash +git branch --show-current +``` + +Required branch: `dev` (two-branch mode). + +If not on the required branch, abort and say: "Switch to `` before running `/deploy`." + +Pull the latest changes before proceeding: +```bash +git pull +``` + +--- + +## Step 2 — Check current state + +### Find the latest version tag + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +If no tag exists, note this is the first release. + +### Read current version + +```bash +cat VERSION +``` + +### Show commits since last tag + +If a previous tag exists, show what's on the branch since that tag: + +```bash +git log main..dev --merges --pretty=format:"%s" +``` + +Parse PR numbers from merge commit subjects (format: `Merge pull request #N from branch/name`). + +For each PR number found, retrieve the PR body: +```bash +gh pr view --json number,title,body +``` + +Extract `Issue #N` and `Closes #N` references from PR bodies. Compile: +- List of PRs included (number + title) +- List of issues linked to those PRs + +### Check for open unmerged PRs + +```bash +gh pr list --state open --json number,title,headRefName --jq '.[] | "#\(.number) \(.title) (\(.headRefName))"' +``` + +### Present the summary + +Tell the user: + +``` +Current version: X.Y.Z +Latest tag: vX.Y.Z + +Commits/PRs since last tag: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Open PRs not yet merged: + #19 — Add dark mode (feature/dark-mode) + +Would you like to bump the version before deploying? + - **patch** → X.Y.C + - **minor** → X.B.0 + - **major** → A.0.0 + - **specific** → enter a version number + - **skip** → proceed to release with the current tag +``` + +Wait for their response. + +--- + +## Step 3 — Version bump (if requested) + +If the user chose to skip, verify a version tag exists on HEAD: +```bash +git describe --exact-match --tags HEAD 2>/dev/null +``` + +If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. + +If the user chose a bump level, map their response to a command: + +| User says | Run | +|---|---| +| "patch" / anything mentioning patch | `make bump-patch` | +| "minor" | `make bump-minor` | +| "major" | `make bump-major` | +| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | + +These commands update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. + +Push the version bump: +```bash +git push +git push --tags +``` + +Both the version bump commit and the tag must be pushed. + +--- + +## Step 4 — Compute release contents + +Determine the version tag (either from the bump just performed, or from the existing HEAD tag if the user skipped bumping). + +Find the previous tag to determine the range: +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +Use the PR/issue list already computed in Step 2. If the version bump added new commits, re-fetch if needed. + +--- + +## Step 5 — HUMAN GATE + +Show the user the release summary. Example format: + +``` +Ready to release vX.Y.Z to production. + +PRs included: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Issues that will close: + #14 — Add /docs directory + #15 — Fix checkout runtime error + +Have you tested all of the above on preview? Type 'release' to confirm. +``` + +Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. + +--- + +## Step 6 — Create PR: `dev` → `main` + +```bash +gh pr create --base main --head dev \ + --title "Release vX.Y.Z" \ + --body "$(cat <<'EOF' +Release vX.Y.Z + +PRs included: +- #17 — Add /docs directory +- #18 — Fix checkout runtime error + +Closes #14 +Closes #15 +EOF +)" +``` + +Note the PR number from the output. + +The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). + +--- + +## Step 7 — Merge + +Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: + +```bash +gh pr merge --merge +``` + +--- + +## Step 8 — Create GitHub Release + +The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: + +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +If no previous tag exists, omit the "Full changelog" line. + +Create the release: + +```bash +gh release create \ + --title "" \ + --notes "$(cat <<'EOF' +## Changes + +- # (PR #) +[... one line per PR included in this release ...] + +**Full changelog:** https://github.com///compare/... +EOF +)" +``` + +Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. + +After the command runs, note the release URL from the output. + +--- + +## Step 9 — Report + +Tell the user: + +> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." + diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md deleted file mode 100644 index 9f484f3..0000000 --- a/.agents/skills/release/SKILL.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -name: release -description: Create a GitHub Release; in multi-branch mode, also promotes the pre-production branch to `main` ---- - -> **Codex CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — perform any review steps inline. - ---- - -## What `/release` does - -Creates a GitHub Release and promotes `dev` to `main`. Run this after preview testing is confirmed. - ---- - -## Step 1 — Verify state - -Check the current branch: -```bash -git branch --show-current -``` - -### Verify on `dev` with tag - -If not on `dev`, switch to it: -```bash -git checkout dev && git pull -``` - -Verify a version tag exists on HEAD: -```bash -git describe --exact-match --tags HEAD 2>/dev/null -``` - -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before promoting it." Stop unless the user explicitly says to proceed anyway. - ---- - -## Step 2 — Compute what's being promoted - -Find all merge commits in `dev` not yet in `main`: -```bash -git log main..dev --merges --pretty=format:"%s" -``` - -Parse PR numbers from the merge commit subjects. GitHub's format is: -`Merge pull request #N from branch/name` - -For each PR number found, retrieve the PR body: -```bash -gh pr view --json number,title,body -``` - -Extract `Issue #N` references from PR bodies (look for the pattern `Issue #\d+`). - -Compile: -- List of PRs being promoted (number + title) -- List of open issues linked to those PRs - ---- - -## Step 3 — HUMAN GATE - -Show the user the release summary. Example format: - -``` -Ready to release vX.Y.Z to production. - -PRs included: - #17 — Add /docs directory - #18 — Fix checkout runtime error - -Issues that will close: - #14 — Add /docs directory - #15 — Fix checkout runtime error - -Have you tested all of the above on preview? Type 'release' to confirm. -``` - -Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. - ---- - -## Step 4 — Create PR: `dev` → `main` - -```bash -gh pr create --base main --head dev \ - --title "Release vX.Y.Z" \ - --body "$(cat <<'EOF' -Release vX.Y.Z - -PRs included: -- #17 — Add /docs directory -- #18 — Fix checkout runtime error - -Closes #14 -Closes #15 -EOF -)" -``` - -Note the PR number from the output. - -The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). - ---- - -## Step 5 — Merge - -Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: - -```bash -gh pr merge --merge -``` - ---- - -## Step 6 — Create GitHub Release - -The version tag (from Step 1) and the PR/issue list (from Step 2) are already known. Find the previous tag to build the changelog link: - -```bash -git describe --abbrev=0 ^ 2>/dev/null -``` - -If no previous tag exists, omit the "Full changelog" line. - -Create the release: - -```bash -gh release create \ - --title "" \ - --notes "$(cat <<'EOF' -## Changes - -- # (PR #) -[... one line per PR included in this release ...] - -**Full changelog:** https://github.com///compare/... -EOF -)" -``` - -Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. - -After the command runs, note the release URL from the output. - ---- - -## Step 7 — Report - -Tell the user: - -> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - diff --git a/.agents/skills/setup/SKILL.md b/.agents/skills/setup/SKILL.md index 00daa2c..92f45c7 100644 --- a/.agents/skills/setup/SKILL.md +++ b/.agents/skills/setup/SKILL.md @@ -61,8 +61,7 @@ List the available skills: | `/start` | Creates a GitHub issue, feature branch, and writes code | | `/ship` | Checks, commits, opens PR, spawns review agent, merges | | `/review` | Standalone code review on any PR | -| `/version` | Bumps semver, tags, pushes | -| `/release` | Promotes integration branch to main, closes issues | +| `/deploy` | Bumps version, creates GitHub Release, promotes to production | | `/status` | Snapshot of open PRs and issues for the team | | `/setup` | This skill — configures Code Cannon in a project | @@ -131,7 +130,7 @@ Cannot proceed without it. Stop. gh repo view --json name ``` -If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/release`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. +If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/deploy`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. ### Check 5 — .codecannon.yaml present @@ -476,4 +475,4 @@ Add a note: `/start` can be used to create well-formed GitHub issues without wri - Never fetch more than 100 labels in a single command. `gh label list --limit 100` is the ceiling. - Do not skip any human gate in Phase 2 or Phase 3 — each write requires confirmation. - If the user skips a config value, do not ask again. Move on. - + diff --git a/.agents/skills/ship/SKILL.md b/.agents/skills/ship/SKILL.md index d91120f..98026de 100644 --- a/.agents/skills/ship/SKILL.md +++ b/.agents/skills/ship/SKILL.md @@ -105,7 +105,7 @@ If the output is non-empty, inform the user: "CODEOWNERS file detected — GitHu PR target branch: `dev` -Use `Issue #` as the issue reference — the issue stays open until `/release` promotes to `main`. +Use `Issue #` as the issue reference — the issue stays open until `/deploy` promotes to `main`. Then create the PR with explicit title and body (never use an interactive editor): ``` @@ -203,4 +203,4 @@ Report success based on mode: - When `ai` is `"off"`, skip the review agent entirely — merge immediately after checks pass. - `/ship` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - + diff --git a/.agents/skills/version/SKILL.md b/.agents/skills/version/SKILL.md deleted file mode 100644 index e77f712..0000000 --- a/.agents/skills/version/SKILL.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -name: version -description: Bump the project version, tag, and push — run before deploying to preview ---- - -> **Codex CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — perform any review steps inline. - ---- - -## Step 1 — Verify branch - -Run: -```bash -git branch --show-current -``` - -Required branch: `dev` (two-branch mode). - -If not on the required branch, abort and say: "Switch to `` before running `/version`." - -Pull the latest changes before proceeding: -```bash -git pull -``` - ---- - -## Step 2 — Read current version - -```bash -cat VERSION -``` - ---- - -## Step 3 — Ask the user - -Tell the user (filling in the actual computed values): - -> "You are on version X.Y.Z. Do you want to bump: -> - **major** → A.0.0 -> - **minor** → X.B.0 -> - **patch** → X.Y.C -> - or set a specific version?" - -Wait for their response. - ---- - -## Step 4 — Interpret and run - -Map the user's natural language response to a command: - -| User says | Run | -|---|---| -| "patch" / anything mentioning patch | `make bump-patch` | -| "minor" | `make bump-minor` | -| "major" | `make bump-major` | -| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | - -These targets update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. - ---- - -## Step 5 — Push - -```bash -git push -git push --tags -``` - -Both the version bump commit and the tag must be pushed. - ---- - -## Step 6 — Report - -Tell the user the new version and tag: - -"Tagged vX.Y.Z. Run `make deploy-preview` to deploy to preview for testing. When testing is complete, run `/release`." - diff --git a/.claude/commands/deploy.md b/.claude/commands/deploy.md new file mode 100644 index 0000000..f53cac1 --- /dev/null +++ b/.claude/commands/deploy.md @@ -0,0 +1,233 @@ +Bump the project version, create a GitHub Release, and promote to production — handles both versioning and releasing in one step + +--- + +## What `/deploy` does + +`/deploy` is the final step in the workflow. It combines version bumping and release creation into a single command: check state, optionally bump the version, then create a GitHub Release (and in multi-branch mode, promote to production). + +--- + +## Step 1 — Verify branch + +Run: +```bash +git branch --show-current +``` + +Required branch: `dev` (two-branch mode). + +If not on the required branch, abort and say: "Switch to `` before running `/deploy`." + +Pull the latest changes before proceeding: +```bash +git pull +``` + +--- + +## Step 2 — Check current state + +### Find the latest version tag + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +If no tag exists, note this is the first release. + +### Read current version + +```bash +cat VERSION +``` + +### Show commits since last tag + +If a previous tag exists, show what's on the branch since that tag: + +```bash +git log main..dev --merges --pretty=format:"%s" +``` + +Parse PR numbers from merge commit subjects (format: `Merge pull request #N from branch/name`). + +For each PR number found, retrieve the PR body: +```bash +gh pr view --json number,title,body +``` + +Extract `Issue #N` and `Closes #N` references from PR bodies. Compile: +- List of PRs included (number + title) +- List of issues linked to those PRs + +### Check for open unmerged PRs + +```bash +gh pr list --state open --json number,title,headRefName --jq '.[] | "#\(.number) \(.title) (\(.headRefName))"' +``` + +### Present the summary + +Tell the user: + +``` +Current version: X.Y.Z +Latest tag: vX.Y.Z + +Commits/PRs since last tag: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Open PRs not yet merged: + #19 — Add dark mode (feature/dark-mode) + +Would you like to bump the version before deploying? + - **patch** → X.Y.C + - **minor** → X.B.0 + - **major** → A.0.0 + - **specific** → enter a version number + - **skip** → proceed to release with the current tag +``` + +Wait for their response. + +--- + +## Step 3 — Version bump (if requested) + +If the user chose to skip, verify a version tag exists on HEAD: +```bash +git describe --exact-match --tags HEAD 2>/dev/null +``` + +If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. + +If the user chose a bump level, map their response to a command: + +| User says | Run | +|---|---| +| "patch" / anything mentioning patch | `make bump-patch` | +| "minor" | `make bump-minor` | +| "major" | `make bump-major` | +| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | + +These commands update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. + +Push the version bump: +```bash +git push +git push --tags +``` + +Both the version bump commit and the tag must be pushed. + +--- + +## Step 4 — Compute release contents + +Determine the version tag (either from the bump just performed, or from the existing HEAD tag if the user skipped bumping). + +Find the previous tag to determine the range: +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +Use the PR/issue list already computed in Step 2. If the version bump added new commits, re-fetch if needed. + +--- + +## Step 5 — HUMAN GATE + +Show the user the release summary. Example format: + +``` +Ready to release vX.Y.Z to production. + +PRs included: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Issues that will close: + #14 — Add /docs directory + #15 — Fix checkout runtime error + +Have you tested all of the above on preview? Type 'release' to confirm. +``` + +Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. + +--- + +## Step 6 — Create PR: `dev` → `main` + +```bash +gh pr create --base main --head dev \ + --title "Release vX.Y.Z" \ + --body "$(cat <<'EOF' +Release vX.Y.Z + +PRs included: +- #17 — Add /docs directory +- #18 — Fix checkout runtime error + +Closes #14 +Closes #15 +EOF +)" +``` + +Note the PR number from the output. + +The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). + +--- + +## Step 7 — Merge + +Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: + +```bash +gh pr merge --merge +``` + +--- + +## Step 8 — Create GitHub Release + +The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: + +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +If no previous tag exists, omit the "Full changelog" line. + +Create the release: + +```bash +gh release create \ + --title "" \ + --notes "$(cat <<'EOF' +## Changes + +- # (PR #) +[... one line per PR included in this release ...] + +**Full changelog:** https://github.com///compare/... +EOF +)" +``` + +Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. + +After the command runs, note the release URL from the output. + +--- + +## Step 9 — Report + +Tell the user: + +> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." + diff --git a/.claude/commands/release.md b/.claude/commands/release.md deleted file mode 100644 index a637ec0..0000000 --- a/.claude/commands/release.md +++ /dev/null @@ -1,150 +0,0 @@ -Create a GitHub Release; in multi-branch mode, also promotes the pre-production branch to `main` - ---- - -## What `/release` does - -Creates a GitHub Release and promotes `dev` to `main`. Run this after preview testing is confirmed. - ---- - -## Step 1 — Verify state - -Check the current branch: -```bash -git branch --show-current -``` - -### Verify on `dev` with tag - -If not on `dev`, switch to it: -```bash -git checkout dev && git pull -``` - -Verify a version tag exists on HEAD: -```bash -git describe --exact-match --tags HEAD 2>/dev/null -``` - -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before promoting it." Stop unless the user explicitly says to proceed anyway. - ---- - -## Step 2 — Compute what's being promoted - -Find all merge commits in `dev` not yet in `main`: -```bash -git log main..dev --merges --pretty=format:"%s" -``` - -Parse PR numbers from the merge commit subjects. GitHub's format is: -`Merge pull request #N from branch/name` - -For each PR number found, retrieve the PR body: -```bash -gh pr view --json number,title,body -``` - -Extract `Issue #N` references from PR bodies (look for the pattern `Issue #\d+`). - -Compile: -- List of PRs being promoted (number + title) -- List of open issues linked to those PRs - ---- - -## Step 3 — HUMAN GATE - -Show the user the release summary. Example format: - -``` -Ready to release vX.Y.Z to production. - -PRs included: - #17 — Add /docs directory - #18 — Fix checkout runtime error - -Issues that will close: - #14 — Add /docs directory - #15 — Fix checkout runtime error - -Have you tested all of the above on preview? Type 'release' to confirm. -``` - -Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. - ---- - -## Step 4 — Create PR: `dev` → `main` - -```bash -gh pr create --base main --head dev \ - --title "Release vX.Y.Z" \ - --body "$(cat <<'EOF' -Release vX.Y.Z - -PRs included: -- #17 — Add /docs directory -- #18 — Fix checkout runtime error - -Closes #14 -Closes #15 -EOF -)" -``` - -Note the PR number from the output. - -The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). - ---- - -## Step 5 — Merge - -Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: - -```bash -gh pr merge --merge -``` - ---- - -## Step 6 — Create GitHub Release - -The version tag (from Step 1) and the PR/issue list (from Step 2) are already known. Find the previous tag to build the changelog link: - -```bash -git describe --abbrev=0 ^ 2>/dev/null -``` - -If no previous tag exists, omit the "Full changelog" line. - -Create the release: - -```bash -gh release create \ - --title "" \ - --notes "$(cat <<'EOF' -## Changes - -- # (PR #) -[... one line per PR included in this release ...] - -**Full changelog:** https://github.com///compare/... -EOF -)" -``` - -Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. - -After the command runs, note the release URL from the output. - ---- - -## Step 7 — Report - -Tell the user: - -> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - diff --git a/.claude/commands/setup.md b/.claude/commands/setup.md index 1f0b664..ba2edf7 100644 --- a/.claude/commands/setup.md +++ b/.claude/commands/setup.md @@ -56,8 +56,7 @@ List the available skills: | `/start` | Creates a GitHub issue, feature branch, and writes code | | `/ship` | Checks, commits, opens PR, spawns review agent, merges | | `/review` | Standalone code review on any PR | -| `/version` | Bumps semver, tags, pushes | -| `/release` | Promotes integration branch to main, closes issues | +| `/deploy` | Bumps version, creates GitHub Release, promotes to production | | `/status` | Snapshot of open PRs and issues for the team | | `/setup` | This skill — configures Code Cannon in a project | @@ -126,7 +125,7 @@ Cannot proceed without it. Stop. gh repo view --json name ``` -If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/release`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. +If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/deploy`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. ### Check 5 — .codecannon.yaml present @@ -471,4 +470,4 @@ Add a note: `/start` can be used to create well-formed GitHub issues without wri - Never fetch more than 100 labels in a single command. `gh label list --limit 100` is the ceiling. - Do not skip any human gate in Phase 2 or Phase 3 — each write requires confirmation. - If the user skips a config value, do not ask again. Move on. - + diff --git a/.claude/commands/ship.md b/.claude/commands/ship.md index 8e4de3a..2be406e 100644 --- a/.claude/commands/ship.md +++ b/.claude/commands/ship.md @@ -100,7 +100,7 @@ If the output is non-empty, inform the user: "CODEOWNERS file detected — GitHu PR target branch: `dev` -Use `Issue #` as the issue reference — the issue stays open until `/release` promotes to `main`. +Use `Issue #` as the issue reference — the issue stays open until `/deploy` promotes to `main`. Then create the PR with explicit title and body (never use an interactive editor): ``` @@ -198,4 +198,4 @@ Report success based on mode: - When `ai` is `"off"`, skip the review agent entirely — merge immediately after checks pass. - `/ship` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - + diff --git a/.claude/commands/version.md b/.claude/commands/version.md deleted file mode 100644 index ccd65f4..0000000 --- a/.claude/commands/version.md +++ /dev/null @@ -1,76 +0,0 @@ -Bump the project version, tag, and push — run before deploying to preview - ---- - -## Step 1 — Verify branch - -Run: -```bash -git branch --show-current -``` - -Required branch: `dev` (two-branch mode). - -If not on the required branch, abort and say: "Switch to `` before running `/version`." - -Pull the latest changes before proceeding: -```bash -git pull -``` - ---- - -## Step 2 — Read current version - -```bash -cat VERSION -``` - ---- - -## Step 3 — Ask the user - -Tell the user (filling in the actual computed values): - -> "You are on version X.Y.Z. Do you want to bump: -> - **major** → A.0.0 -> - **minor** → X.B.0 -> - **patch** → X.Y.C -> - or set a specific version?" - -Wait for their response. - ---- - -## Step 4 — Interpret and run - -Map the user's natural language response to a command: - -| User says | Run | -|---|---| -| "patch" / anything mentioning patch | `make bump-patch` | -| "minor" | `make bump-minor` | -| "major" | `make bump-major` | -| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | - -These targets update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. - ---- - -## Step 5 — Push - -```bash -git push -git push --tags -``` - -Both the version bump commit and the tag must be pushed. - ---- - -## Step 6 — Report - -Tell the user the new version and tag: - -"Tagged vX.Y.Z. Run `make deploy-preview` to deploy to preview for testing. When testing is complete, run `/release`." - diff --git a/.cursor/rules/deploy.mdc b/.cursor/rules/deploy.mdc new file mode 100644 index 0000000..973a1a1 --- /dev/null +++ b/.cursor/rules/deploy.mdc @@ -0,0 +1,239 @@ +--- +description: Bump the project version, create a GitHub Release, and promote to production — handles both versioning and releasing in one step +globs: +alwaysApply: false +--- + +> **Cursor:** Trigger this skill via `@deploy` in Agent mode. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/ship` must be done manually using the review-agent prompt. + +--- + +## What `/deploy` does + +`/deploy` is the final step in the workflow. It combines version bumping and release creation into a single command: check state, optionally bump the version, then create a GitHub Release (and in multi-branch mode, promote to production). + +--- + +## Step 1 — Verify branch + +Run: +```bash +git branch --show-current +``` + +Required branch: `dev` (two-branch mode). + +If not on the required branch, abort and say: "Switch to `` before running `/deploy`." + +Pull the latest changes before proceeding: +```bash +git pull +``` + +--- + +## Step 2 — Check current state + +### Find the latest version tag + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +If no tag exists, note this is the first release. + +### Read current version + +```bash +cat VERSION +``` + +### Show commits since last tag + +If a previous tag exists, show what's on the branch since that tag: + +```bash +git log main..dev --merges --pretty=format:"%s" +``` + +Parse PR numbers from merge commit subjects (format: `Merge pull request #N from branch/name`). + +For each PR number found, retrieve the PR body: +```bash +gh pr view --json number,title,body +``` + +Extract `Issue #N` and `Closes #N` references from PR bodies. Compile: +- List of PRs included (number + title) +- List of issues linked to those PRs + +### Check for open unmerged PRs + +```bash +gh pr list --state open --json number,title,headRefName --jq '.[] | "#\(.number) \(.title) (\(.headRefName))"' +``` + +### Present the summary + +Tell the user: + +``` +Current version: X.Y.Z +Latest tag: vX.Y.Z + +Commits/PRs since last tag: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Open PRs not yet merged: + #19 — Add dark mode (feature/dark-mode) + +Would you like to bump the version before deploying? + - **patch** → X.Y.C + - **minor** → X.B.0 + - **major** → A.0.0 + - **specific** → enter a version number + - **skip** → proceed to release with the current tag +``` + +Wait for their response. + +--- + +## Step 3 — Version bump (if requested) + +If the user chose to skip, verify a version tag exists on HEAD: +```bash +git describe --exact-match --tags HEAD 2>/dev/null +``` + +If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. + +If the user chose a bump level, map their response to a command: + +| User says | Run | +|---|---| +| "patch" / anything mentioning patch | `make bump-patch` | +| "minor" | `make bump-minor` | +| "major" | `make bump-major` | +| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | + +These commands update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. + +Push the version bump: +```bash +git push +git push --tags +``` + +Both the version bump commit and the tag must be pushed. + +--- + +## Step 4 — Compute release contents + +Determine the version tag (either from the bump just performed, or from the existing HEAD tag if the user skipped bumping). + +Find the previous tag to determine the range: +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +Use the PR/issue list already computed in Step 2. If the version bump added new commits, re-fetch if needed. + +--- + +## Step 5 — HUMAN GATE + +Show the user the release summary. Example format: + +``` +Ready to release vX.Y.Z to production. + +PRs included: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Issues that will close: + #14 — Add /docs directory + #15 — Fix checkout runtime error + +Have you tested all of the above on preview? Type 'release' to confirm. +``` + +Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. + +--- + +## Step 6 — Create PR: `dev` → `main` + +```bash +gh pr create --base main --head dev \ + --title "Release vX.Y.Z" \ + --body "$(cat <<'EOF' +Release vX.Y.Z + +PRs included: +- #17 — Add /docs directory +- #18 — Fix checkout runtime error + +Closes #14 +Closes #15 +EOF +)" +``` + +Note the PR number from the output. + +The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). + +--- + +## Step 7 — Merge + +Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: + +```bash +gh pr merge --merge +``` + +--- + +## Step 8 — Create GitHub Release + +The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: + +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +If no previous tag exists, omit the "Full changelog" line. + +Create the release: + +```bash +gh release create \ + --title "" \ + --notes "$(cat <<'EOF' +## Changes + +- # (PR #) +[... one line per PR included in this release ...] + +**Full changelog:** https://github.com///compare/... +EOF +)" +``` + +Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. + +After the command runs, note the release URL from the output. + +--- + +## Step 9 — Report + +Tell the user: + +> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." + diff --git a/.cursor/rules/release.mdc b/.cursor/rules/release.mdc deleted file mode 100644 index 850fbc9..0000000 --- a/.cursor/rules/release.mdc +++ /dev/null @@ -1,156 +0,0 @@ ---- -description: Create a GitHub Release; in multi-branch mode, also promotes the pre-production branch to `main` -globs: -alwaysApply: false ---- - -> **Cursor:** Trigger this skill via `@release` in Agent mode. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/ship` must be done manually using the review-agent prompt. - ---- - -## What `/release` does - -Creates a GitHub Release and promotes `dev` to `main`. Run this after preview testing is confirmed. - ---- - -## Step 1 — Verify state - -Check the current branch: -```bash -git branch --show-current -``` - -### Verify on `dev` with tag - -If not on `dev`, switch to it: -```bash -git checkout dev && git pull -``` - -Verify a version tag exists on HEAD: -```bash -git describe --exact-match --tags HEAD 2>/dev/null -``` - -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before promoting it." Stop unless the user explicitly says to proceed anyway. - ---- - -## Step 2 — Compute what's being promoted - -Find all merge commits in `dev` not yet in `main`: -```bash -git log main..dev --merges --pretty=format:"%s" -``` - -Parse PR numbers from the merge commit subjects. GitHub's format is: -`Merge pull request #N from branch/name` - -For each PR number found, retrieve the PR body: -```bash -gh pr view --json number,title,body -``` - -Extract `Issue #N` references from PR bodies (look for the pattern `Issue #\d+`). - -Compile: -- List of PRs being promoted (number + title) -- List of open issues linked to those PRs - ---- - -## Step 3 — HUMAN GATE - -Show the user the release summary. Example format: - -``` -Ready to release vX.Y.Z to production. - -PRs included: - #17 — Add /docs directory - #18 — Fix checkout runtime error - -Issues that will close: - #14 — Add /docs directory - #15 — Fix checkout runtime error - -Have you tested all of the above on preview? Type 'release' to confirm. -``` - -Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. - ---- - -## Step 4 — Create PR: `dev` → `main` - -```bash -gh pr create --base main --head dev \ - --title "Release vX.Y.Z" \ - --body "$(cat <<'EOF' -Release vX.Y.Z - -PRs included: -- #17 — Add /docs directory -- #18 — Fix checkout runtime error - -Closes #14 -Closes #15 -EOF -)" -``` - -Note the PR number from the output. - -The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). - ---- - -## Step 5 — Merge - -Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: - -```bash -gh pr merge --merge -``` - ---- - -## Step 6 — Create GitHub Release - -The version tag (from Step 1) and the PR/issue list (from Step 2) are already known. Find the previous tag to build the changelog link: - -```bash -git describe --abbrev=0 ^ 2>/dev/null -``` - -If no previous tag exists, omit the "Full changelog" line. - -Create the release: - -```bash -gh release create \ - --title "" \ - --notes "$(cat <<'EOF' -## Changes - -- # (PR #) -[... one line per PR included in this release ...] - -**Full changelog:** https://github.com///compare/... -EOF -)" -``` - -Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. - -After the command runs, note the release URL from the output. - ---- - -## Step 7 — Report - -Tell the user: - -> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - diff --git a/.cursor/rules/setup.mdc b/.cursor/rules/setup.mdc index 7ad5739..6251a67 100644 --- a/.cursor/rules/setup.mdc +++ b/.cursor/rules/setup.mdc @@ -62,8 +62,7 @@ List the available skills: | `/start` | Creates a GitHub issue, feature branch, and writes code | | `/ship` | Checks, commits, opens PR, spawns review agent, merges | | `/review` | Standalone code review on any PR | -| `/version` | Bumps semver, tags, pushes | -| `/release` | Promotes integration branch to main, closes issues | +| `/deploy` | Bumps version, creates GitHub Release, promotes to production | | `/status` | Snapshot of open PRs and issues for the team | | `/setup` | This skill — configures Code Cannon in a project | @@ -132,7 +131,7 @@ Cannot proceed without it. Stop. gh repo view --json name ``` -If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/release`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. +If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/deploy`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. ### Check 5 — .codecannon.yaml present @@ -477,4 +476,4 @@ Add a note: `/start` can be used to create well-formed GitHub issues without wri - Never fetch more than 100 labels in a single command. `gh label list --limit 100` is the ceiling. - Do not skip any human gate in Phase 2 or Phase 3 — each write requires confirmation. - If the user skips a config value, do not ask again. Move on. - + diff --git a/.cursor/rules/ship.mdc b/.cursor/rules/ship.mdc index c8264fd..86d0b9d 100644 --- a/.cursor/rules/ship.mdc +++ b/.cursor/rules/ship.mdc @@ -106,7 +106,7 @@ If the output is non-empty, inform the user: "CODEOWNERS file detected — GitHu PR target branch: `dev` -Use `Issue #` as the issue reference — the issue stays open until `/release` promotes to `main`. +Use `Issue #` as the issue reference — the issue stays open until `/deploy` promotes to `main`. Then create the PR with explicit title and body (never use an interactive editor): ``` @@ -204,4 +204,4 @@ Report success based on mode: - When `ai` is `"off"`, skip the review agent entirely — merge immediately after checks pass. - `/ship` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - + diff --git a/.cursor/rules/version.mdc b/.cursor/rules/version.mdc deleted file mode 100644 index 290af5d..0000000 --- a/.cursor/rules/version.mdc +++ /dev/null @@ -1,82 +0,0 @@ ---- -description: Bump the project version, tag, and push — run before deploying to preview -globs: -alwaysApply: false ---- - -> **Cursor:** Trigger this skill via `@version` in Agent mode. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/ship` must be done manually using the review-agent prompt. - ---- - -## Step 1 — Verify branch - -Run: -```bash -git branch --show-current -``` - -Required branch: `dev` (two-branch mode). - -If not on the required branch, abort and say: "Switch to `` before running `/version`." - -Pull the latest changes before proceeding: -```bash -git pull -``` - ---- - -## Step 2 — Read current version - -```bash -cat VERSION -``` - ---- - -## Step 3 — Ask the user - -Tell the user (filling in the actual computed values): - -> "You are on version X.Y.Z. Do you want to bump: -> - **major** → A.0.0 -> - **minor** → X.B.0 -> - **patch** → X.Y.C -> - or set a specific version?" - -Wait for their response. - ---- - -## Step 4 — Interpret and run - -Map the user's natural language response to a command: - -| User says | Run | -|---|---| -| "patch" / anything mentioning patch | `make bump-patch` | -| "minor" | `make bump-minor` | -| "major" | `make bump-major` | -| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | - -These targets update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. - ---- - -## Step 5 — Push - -```bash -git push -git push --tags -``` - -Both the version bump commit and the tag must be pushed. - ---- - -## Step 6 — Report - -Tell the user the new version and tag: - -"Tagged vX.Y.Z. Run `make deploy-preview` to deploy to preview for testing. When testing is complete, run `/release`." - diff --git a/.gemini/skills/deploy/SKILL.md b/.gemini/skills/deploy/SKILL.md new file mode 100644 index 0000000..fe44e6f --- /dev/null +++ b/.gemini/skills/deploy/SKILL.md @@ -0,0 +1,238 @@ +--- +name: deploy +description: Bump the project version, create a GitHub Release, and promote to production — handles both versioning and releasing in one step +--- + +> **Gemini CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/ship` must be done manually using the review-agent prompt in a separate session. + +--- + +## What `/deploy` does + +`/deploy` is the final step in the workflow. It combines version bumping and release creation into a single command: check state, optionally bump the version, then create a GitHub Release (and in multi-branch mode, promote to production). + +--- + +## Step 1 — Verify branch + +Run: +```bash +git branch --show-current +``` + +Required branch: `dev` (two-branch mode). + +If not on the required branch, abort and say: "Switch to `` before running `/deploy`." + +Pull the latest changes before proceeding: +```bash +git pull +``` + +--- + +## Step 2 — Check current state + +### Find the latest version tag + +```bash +git describe --tags --abbrev=0 2>/dev/null +``` + +If no tag exists, note this is the first release. + +### Read current version + +```bash +cat VERSION +``` + +### Show commits since last tag + +If a previous tag exists, show what's on the branch since that tag: + +```bash +git log main..dev --merges --pretty=format:"%s" +``` + +Parse PR numbers from merge commit subjects (format: `Merge pull request #N from branch/name`). + +For each PR number found, retrieve the PR body: +```bash +gh pr view --json number,title,body +``` + +Extract `Issue #N` and `Closes #N` references from PR bodies. Compile: +- List of PRs included (number + title) +- List of issues linked to those PRs + +### Check for open unmerged PRs + +```bash +gh pr list --state open --json number,title,headRefName --jq '.[] | "#\(.number) \(.title) (\(.headRefName))"' +``` + +### Present the summary + +Tell the user: + +``` +Current version: X.Y.Z +Latest tag: vX.Y.Z + +Commits/PRs since last tag: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Open PRs not yet merged: + #19 — Add dark mode (feature/dark-mode) + +Would you like to bump the version before deploying? + - **patch** → X.Y.C + - **minor** → X.B.0 + - **major** → A.0.0 + - **specific** → enter a version number + - **skip** → proceed to release with the current tag +``` + +Wait for their response. + +--- + +## Step 3 — Version bump (if requested) + +If the user chose to skip, verify a version tag exists on HEAD: +```bash +git describe --exact-match --tags HEAD 2>/dev/null +``` + +If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. + +If the user chose a bump level, map their response to a command: + +| User says | Run | +|---|---| +| "patch" / anything mentioning patch | `make bump-patch` | +| "minor" | `make bump-minor` | +| "major" | `make bump-major` | +| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | + +These commands update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. + +Push the version bump: +```bash +git push +git push --tags +``` + +Both the version bump commit and the tag must be pushed. + +--- + +## Step 4 — Compute release contents + +Determine the version tag (either from the bump just performed, or from the existing HEAD tag if the user skipped bumping). + +Find the previous tag to determine the range: +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +Use the PR/issue list already computed in Step 2. If the version bump added new commits, re-fetch if needed. + +--- + +## Step 5 — HUMAN GATE + +Show the user the release summary. Example format: + +``` +Ready to release vX.Y.Z to production. + +PRs included: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Issues that will close: + #14 — Add /docs directory + #15 — Fix checkout runtime error + +Have you tested all of the above on preview? Type 'release' to confirm. +``` + +Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. + +--- + +## Step 6 — Create PR: `dev` → `main` + +```bash +gh pr create --base main --head dev \ + --title "Release vX.Y.Z" \ + --body "$(cat <<'EOF' +Release vX.Y.Z + +PRs included: +- #17 — Add /docs directory +- #18 — Fix checkout runtime error + +Closes #14 +Closes #15 +EOF +)" +``` + +Note the PR number from the output. + +The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). + +--- + +## Step 7 — Merge + +Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: + +```bash +gh pr merge --merge +``` + +--- + +## Step 8 — Create GitHub Release + +The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: + +```bash +git describe --abbrev=0 ^ 2>/dev/null +``` + +If no previous tag exists, omit the "Full changelog" line. + +Create the release: + +```bash +gh release create \ + --title "" \ + --notes "$(cat <<'EOF' +## Changes + +- # (PR #) +[... one line per PR included in this release ...] + +**Full changelog:** https://github.com///compare/... +EOF +)" +``` + +Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. + +After the command runs, note the release URL from the output. + +--- + +## Step 9 — Report + +Tell the user: + +> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." + diff --git a/.gemini/skills/release/SKILL.md b/.gemini/skills/release/SKILL.md deleted file mode 100644 index e35a255..0000000 --- a/.gemini/skills/release/SKILL.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -name: release -description: Create a GitHub Release; in multi-branch mode, also promotes the pre-production branch to `main` ---- - -> **Gemini CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/ship` must be done manually using the review-agent prompt in a separate session. - ---- - -## What `/release` does - -Creates a GitHub Release and promotes `dev` to `main`. Run this after preview testing is confirmed. - ---- - -## Step 1 — Verify state - -Check the current branch: -```bash -git branch --show-current -``` - -### Verify on `dev` with tag - -If not on `dev`, switch to it: -```bash -git checkout dev && git pull -``` - -Verify a version tag exists on HEAD: -```bash -git describe --exact-match --tags HEAD 2>/dev/null -``` - -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before promoting it." Stop unless the user explicitly says to proceed anyway. - ---- - -## Step 2 — Compute what's being promoted - -Find all merge commits in `dev` not yet in `main`: -```bash -git log main..dev --merges --pretty=format:"%s" -``` - -Parse PR numbers from the merge commit subjects. GitHub's format is: -`Merge pull request #N from branch/name` - -For each PR number found, retrieve the PR body: -```bash -gh pr view --json number,title,body -``` - -Extract `Issue #N` references from PR bodies (look for the pattern `Issue #\d+`). - -Compile: -- List of PRs being promoted (number + title) -- List of open issues linked to those PRs - ---- - -## Step 3 — HUMAN GATE - -Show the user the release summary. Example format: - -``` -Ready to release vX.Y.Z to production. - -PRs included: - #17 — Add /docs directory - #18 — Fix checkout runtime error - -Issues that will close: - #14 — Add /docs directory - #15 — Fix checkout runtime error - -Have you tested all of the above on preview? Type 'release' to confirm. -``` - -Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. - ---- - -## Step 4 — Create PR: `dev` → `main` - -```bash -gh pr create --base main --head dev \ - --title "Release vX.Y.Z" \ - --body "$(cat <<'EOF' -Release vX.Y.Z - -PRs included: -- #17 — Add /docs directory -- #18 — Fix checkout runtime error - -Closes #14 -Closes #15 -EOF -)" -``` - -Note the PR number from the output. - -The `Closes #N` lines will auto-close the linked issues because this PR merges into `main` (the default branch). - ---- - -## Step 5 — Merge - -Do NOT use `make merge` — it refuses PRs targeting `main`. Use `gh pr merge` directly: - -```bash -gh pr merge --merge -``` - ---- - -## Step 6 — Create GitHub Release - -The version tag (from Step 1) and the PR/issue list (from Step 2) are already known. Find the previous tag to build the changelog link: - -```bash -git describe --abbrev=0 ^ 2>/dev/null -``` - -If no previous tag exists, omit the "Full changelog" line. - -Create the release: - -```bash -gh release create \ - --title "" \ - --notes "$(cat <<'EOF' -## Changes - -- # (PR #) -[... one line per PR included in this release ...] - -**Full changelog:** https://github.com///compare/... -EOF -)" -``` - -Format each PR line as `- # (PR #)`. If a PR had no linked issue, omit the `#` prefix and use just the PR title. - -After the command runs, note the release URL from the output. - ---- - -## Step 7 — Report - -Tell the user: - -> "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - diff --git a/.gemini/skills/setup/SKILL.md b/.gemini/skills/setup/SKILL.md index 16ee702..0b7a0cc 100644 --- a/.gemini/skills/setup/SKILL.md +++ b/.gemini/skills/setup/SKILL.md @@ -61,8 +61,7 @@ List the available skills: | `/start` | Creates a GitHub issue, feature branch, and writes code | | `/ship` | Checks, commits, opens PR, spawns review agent, merges | | `/review` | Standalone code review on any PR | -| `/version` | Bumps semver, tags, pushes | -| `/release` | Promotes integration branch to main, closes issues | +| `/deploy` | Bumps version, creates GitHub Release, promotes to production | | `/status` | Snapshot of open PRs and issues for the team | | `/setup` | This skill — configures Code Cannon in a project | @@ -131,7 +130,7 @@ Cannot proceed without it. Stop. gh repo view --json name ``` -If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/release`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. +If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/deploy`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. ### Check 5 — .codecannon.yaml present @@ -476,4 +475,4 @@ Add a note: `/start` can be used to create well-formed GitHub issues without wri - Never fetch more than 100 labels in a single command. `gh label list --limit 100` is the ceiling. - Do not skip any human gate in Phase 2 or Phase 3 — each write requires confirmation. - If the user skips a config value, do not ask again. Move on. - + diff --git a/.gemini/skills/ship/SKILL.md b/.gemini/skills/ship/SKILL.md index 8a257e2..37882a2 100644 --- a/.gemini/skills/ship/SKILL.md +++ b/.gemini/skills/ship/SKILL.md @@ -105,7 +105,7 @@ If the output is non-empty, inform the user: "CODEOWNERS file detected — GitHu PR target branch: `dev` -Use `Issue #` as the issue reference — the issue stays open until `/release` promotes to `main`. +Use `Issue #` as the issue reference — the issue stays open until `/deploy` promotes to `main`. Then create the PR with explicit title and body (never use an interactive editor): ``` @@ -203,4 +203,4 @@ Report success based on mode: - When `ai` is `"off"`, skip the review agent entirely — merge immediately after checks pass. - `/ship` merges only to `dev` — never directly to `main`. - If `make merge` fails for any reason, report it and stop — do not attempt workarounds. - + diff --git a/.gemini/skills/version/SKILL.md b/.gemini/skills/version/SKILL.md deleted file mode 100644 index 102b7a9..0000000 --- a/.gemini/skills/version/SKILL.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -name: version -description: Bump the project version, tag, and push — run before deploying to preview ---- - -> **Gemini CLI:** This skill is triggered by description matching. State any arguments in your message. Sub-agent spawning is not supported — the automated review step in `/ship` must be done manually using the review-agent prompt in a separate session. - ---- - -## Step 1 — Verify branch - -Run: -```bash -git branch --show-current -``` - -Required branch: `dev` (two-branch mode). - -If not on the required branch, abort and say: "Switch to `` before running `/version`." - -Pull the latest changes before proceeding: -```bash -git pull -``` - ---- - -## Step 2 — Read current version - -```bash -cat VERSION -``` - ---- - -## Step 3 — Ask the user - -Tell the user (filling in the actual computed values): - -> "You are on version X.Y.Z. Do you want to bump: -> - **major** → A.0.0 -> - **minor** → X.B.0 -> - **patch** → X.Y.C -> - or set a specific version?" - -Wait for their response. - ---- - -## Step 4 — Interpret and run - -Map the user's natural language response to a command: - -| User says | Run | -|---|---| -| "patch" / anything mentioning patch | `make bump-patch` | -| "minor" | `make bump-minor` | -| "major" | `make bump-major` | -| A specific version e.g. "2.4.5" | `make set-version V= 2.4.5` | - -These targets update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. - ---- - -## Step 5 — Push - -```bash -git push -git push --tags -``` - -Both the version bump commit and the tag must be pushed. - ---- - -## Step 6 — Report - -Tell the user the new version and tag: - -"Tagged vX.Y.Z. Run `make deploy-preview` to deploy to preview for testing. When testing is complete, run `/release`." - diff --git a/README.md b/README.md index 177d684..c9d5121 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ # Code Cannon -A portable agent workflow skill library. Write your team's development workflow once — start, ship, review, version, release — and sync it to Claude Code, Cursor, and other AI coding agents across all your projects. +A portable agent workflow skill library. Write your team's development workflow once — start, ship, review, deploy — and sync it to Claude Code, Cursor, and other AI coding agents across all your projects. Repository: [github.com/LightbridgeLab/CodeCannon](https://github.com/LightbridgeLab/CodeCannon) ## The problem -AI coding agents are powerful, but every project reinvents the same workflows: how to create issues, open PRs, run reviews, bump versions, cut releases. These instructions live in scattered prompt files, maintained per-project, per-agent, with no consistency and no reuse. +AI coding agents are powerful, but every project reinvents the same workflows: how to create issues, open PRs, run reviews, bump versions, deploy releases. These instructions live in scattered prompt files, maintained per-project, per-agent, with no consistency and no reuse. ## The solution @@ -23,24 +23,23 @@ One source of truth. Every project. Every agent. ## What you get -**A complete development workflow in six commands:** +**A complete development workflow in five commands:** ``` -/start → [code + test] → /ship → [QA] → /version → /release +/start → [code + test] → /ship → [QA] → /deploy ``` - `/start` — creates a GitHub issue, feature branch, and writes code (with human approval before any work begins) - `/ship` — checks, commits, opens PR, runs AI review, merges - `/review` — standalone code review on any PR -- `/version` — bumps semver, tags, pushes -- `/release` — promotes to production, creates a GitHub Release +- `/deploy` — bumps version, creates a GitHub Release, promotes to production - `/status` — standup-ready snapshot of PRs, issues, and progress Plus `/qa` for structured QA workflows and `/setup` for guided onboarding. ## Philosophy -**Humans stay in the loop.** The agent proposes; you approve. `/start` waits for your sign-off before creating anything. `/release` requires explicit confirmation. The agent commits; you test. +**Humans stay in the loop.** The agent proposes; you approve. `/start` waits for your sign-off before creating anything. `/deploy` requires explicit confirmation. The agent commits; you test. **Every change has a ticket.** There is no path for code without an issue. The issue is the unit of work — branch, PR, and release all link back to it. @@ -99,8 +98,7 @@ Or run `/setup` for a guided walkthrough that detects your project state and con | `/start` | [docs](docs/skills/start.md) | Create a GitHub issue, branch, and write code | | `/ship` | [docs](docs/skills/ship.md) | Check, commit, open PR, review, merge | | `/review` | [docs](docs/skills/review.md) | Standalone code review on a PR | -| `/version` | [docs](docs/skills/version.md) | Bump version, tag, push | -| `/release` | [docs](docs/skills/release.md) | Promote to production, create GitHub Release | +| `/deploy` | [docs](docs/skills/deploy.md) | Bump version, create GitHub Release, promote to production | | `/qa` | [docs](docs/skills/qa.md) | QA queue and structured review workflow | | `/status` | [docs](docs/skills/status.md) | Snapshot of PRs, issues, and progress | | `/setup` | [docs](docs/skills/setup.md) | Guided onboarding and configuration | diff --git a/config.schema.yaml b/config.schema.yaml index c8d3677..d52fbab 100644 --- a/config.schema.yaml +++ b/config.schema.yaml @@ -21,7 +21,7 @@ placeholders: a different name (e.g. "master", "prod"). All release promotion targets this branch. default: "main" category: branches - used_in: [ship, release, version] + used_in: [ship, deploy] BRANCH_DEV: description: > @@ -29,18 +29,18 @@ placeholders: Set to enable two-branch mode (feature → BRANCH_DEV → BRANCH_PROD). Common values: "development", "dev", "staging". default: "" category: branches - used_in: [ship, release, version, qa, review-agent] + used_in: [ship, deploy, qa, review-agent] BRANCH_TEST: description: > Test/staging branch for three-branch workflows (feature → BRANCH_DEV → BRANCH_TEST → BRANCH_PROD). Leave empty unless your team has a distinct test environment between dev and production. - Requires BRANCH_DEV to be set. When set, /version runs from this branch and /release promotes - this branch to BRANCH_PROD. The BRANCH_DEV → BRANCH_TEST promotion step is a manual PR + Requires BRANCH_DEV to be set. When set, /deploy runs from this branch and promotes + it to BRANCH_PROD. The BRANCH_DEV → BRANCH_TEST promotion step is a manual PR or future /promote skill. default: "" category: branches - used_in: [version, release] + used_in: [deploy] # ── Workflow commands ────────────────────────────────────────────────────── @@ -76,19 +76,19 @@ placeholders: description: "Merge the current feature PR into the integration branch" default: "make merge" category: workflow - used_in: [ship, release] + used_in: [ship, deploy] DEPLOY_PREVIEW_CMD: description: "Deploy to the pre-production environment (BRANCH_DEV in two-branch mode, BRANCH_TEST in three-branch mode). Not used by /ship in trunk mode." default: "make deploy-preview" category: workflow - used_in: [version] + used_in: [deploy] DEPLOY_PROD_CMD: description: "Build and deploy to production environment" default: "make deploy-prod" category: workflow - used_in: [release] + used_in: [deploy] # ── Version bumping ──────────────────────────────────────────────────────── @@ -96,31 +96,31 @@ placeholders: description: "Command that prints the current version string" default: "node -p \"require('./package.json').version\"" category: version - used_in: [version] + used_in: [deploy] BUMP_PATCH_CMD: description: "Bump patch version, commit, and tag" default: "make bump-patch" category: version - used_in: [version] + used_in: [deploy] BUMP_MINOR_CMD: description: "Bump minor version, commit, and tag" default: "make bump-minor" category: version - used_in: [version] + used_in: [deploy] BUMP_MAJOR_CMD: description: "Bump major version, commit, and tag" default: "make bump-major" category: version - used_in: [version] + used_in: [deploy] SET_VERSION_CMD: description: "Set an arbitrary version (value appended as argument by the skill)" default: "make set-version V=" category: version - used_in: [version] + used_in: [deploy] # ── Paths ────────────────────────────────────────────────────────────────── diff --git a/docs/branching.md b/docs/branching.md index 25d18b8..db86f8d 100644 --- a/docs/branching.md +++ b/docs/branching.md @@ -9,7 +9,7 @@ Code Cannon supports three branching models. Set `BRANCH_DEV` and `BRANCH_TEST` ``` feature/ → main /start /ship merges here - /version and /release run here + /deploy runs here ``` The simplest model. Feature branches are created from and merged directly into `BRANCH_PROD` (default: `main`). `/ship` opens a PR targeting `main` with `Closes #N` — issues auto-close on merge. @@ -18,8 +18,7 @@ The simplest model. Feature branches are created from and merged directly into ` **Skill behavior in trunk mode:** - `/ship` targets `BRANCH_PROD` directly -- `/version` runs from `BRANCH_PROD` -- `/release` creates a GitHub Release from `BRANCH_PROD` (no promotion PR needed) +- `/deploy` runs from `BRANCH_PROD` — bumps version and creates a GitHub Release (no promotion PR needed) - QA labels are not applied automatically ## Two-branch development @@ -28,20 +27,19 @@ The simplest model. Feature branches are created from and merged directly into ` ``` feature/ → BRANCH_DEV → BRANCH_PROD - /start /ship /release + /start /ship /deploy ``` -Feature PRs target `BRANCH_DEV`. Issues deliberately stay open through the feature merge — `Closes #N` is not used on feature PRs because they don't land in the default branch. Issues only auto-close when `/release` promotes `BRANCH_DEV` to `BRANCH_PROD`. +Feature PRs target `BRANCH_DEV`. Issues deliberately stay open through the feature merge — `Closes #N` is not used on feature PRs because they don't land in the default branch. Issues only auto-close when `/deploy` promotes `BRANCH_DEV` to `BRANCH_PROD`. -This supports a QA gate between merging code and shipping to production. After `/ship` merges a feature, you deploy the integration branch to a preview environment, test it, then run `/release` when satisfied. +This supports a QA gate between merging code and shipping to production. After `/ship` merges a feature, you deploy the integration branch to a preview environment, test it, then run `/deploy` when satisfied. **When to use:** Teams that want a review/QA gate before production. The most common model for teams with a staging or preview environment. **Skill behavior in two-branch mode:** - `/ship` targets `BRANCH_DEV` and uses `Issue #N` (not `Closes`) - `/ship` applies `QA_READY_LABEL` to the linked issue (if configured) -- `/version` runs from `BRANCH_DEV` -- `/release` opens a promotion PR from `BRANCH_DEV` to `BRANCH_PROD` with `Closes #N` to auto-close issues +- `/deploy` runs from `BRANCH_DEV` — bumps version, opens a promotion PR from `BRANCH_DEV` to `BRANCH_PROD` with `Closes #N` to auto-close issues ## Three-branch development @@ -49,7 +47,7 @@ This supports a QA gate between merging code and shipping to production. After ` ``` feature/ → BRANCH_DEV → BRANCH_TEST → BRANCH_PROD - /start /ship manual/future /release + /start /ship manual/future /deploy /promote ``` @@ -59,8 +57,7 @@ Adds a dedicated test/staging branch between integration and production. Feature **Skill behavior in three-branch mode:** - `/ship` targets `BRANCH_DEV` (same as two-branch) -- `/version` runs from `BRANCH_TEST` -- `/release` promotes `BRANCH_TEST` to `BRANCH_PROD` +- `/deploy` runs from `BRANCH_TEST` — bumps version and promotes `BRANCH_TEST` to `BRANCH_PROD` - The `BRANCH_DEV` to `BRANCH_TEST` step is outside Code Cannon's current scope ## Choosing your model @@ -78,7 +75,7 @@ These aren't rigid modes — they're starting points. Every setting is independe Code Cannon enforces branch rules at the skill level: - `/ship` aborts if run from any protected branch (`BRANCH_PROD`, `BRANCH_DEV`, or `BRANCH_TEST` when set). It must be run from a `feature/*` branch. -- `/version` aborts if not on the required pre-production branch (determined by mode). +- `/deploy` aborts if not on the required pre-production branch (determined by mode). - `/start` always creates `feature/*` branches via `gh issue develop`, ensuring every branch is linked to an issue. The agent will not proceed past these checks. There is no override flag — if you're on the wrong branch, switch first. diff --git a/docs/config-reference.md b/docs/config-reference.md index a10cc3e..1a1c74f 100644 --- a/docs/config-reference.md +++ b/docs/config-reference.md @@ -8,9 +8,9 @@ For the canonical source, see [`config.schema.yaml`](../config.schema.yaml). | Key | Default | Used in | Description | |---|---|---|---| -| `BRANCH_PROD` | `main` | ship, release, version | Production branch. All release promotion targets this branch. | -| `BRANCH_DEV` | *(empty)* | ship, release, version, qa, review-agent | Development/integration branch. Leave empty for trunk-based development. Set to enable two-branch mode. | -| `BRANCH_TEST` | *(empty)* | version, release | Test/staging branch for three-branch workflows. Requires `BRANCH_DEV` to be set. | +| `BRANCH_PROD` | `main` | ship, deploy | Production branch. All release promotion targets this branch. | +| `BRANCH_DEV` | *(empty)* | ship, deploy, qa, review-agent | Development/integration branch. Leave empty for trunk-based development. Set to enable two-branch mode. | +| `BRANCH_TEST` | *(empty)* | deploy | Test/staging branch for three-branch workflows. Requires `BRANCH_DEV` to be set. | See [branching models](branching.md) for how these values change skill behavior. @@ -21,20 +21,20 @@ See [branching models](branching.md) for how these values change skill behavior. | `CHECK_CMD` | `make check` | ship | Type-check / lint gate that must pass before shipping. | | `DEV_CMD` | `make dev` | start | Start the local development server. Suggested to user after `/start` writes code. | | `ABANDON_CMD` | `make abandon` | start | Discard all changes and delete the current feature branch. | -| `MERGE_CMD` | `make merge` | ship, release | Merge the current feature PR into the integration branch. | -| `DEPLOY_PREVIEW_CMD` | `make deploy-preview` | version | Deploy to the pre-production environment. | -| `DEPLOY_PROD_CMD` | `make deploy-prod` | release | Deploy to production. | +| `MERGE_CMD` | `make merge` | ship, deploy | Merge the current feature PR into the integration branch. | +| `DEPLOY_PREVIEW_CMD` | `make deploy-preview` | deploy | Deploy to the pre-production environment. | +| `DEPLOY_PROD_CMD` | `make deploy-prod` | deploy | Deploy to production. | | `REVIEW_GATE` | `ai` | ship, review | Controls AI review in `/ship`. Values: `ai` (blocks on critical findings), `advisory` (posts but doesn't block), `off` (no review). | ## Version bumping | Key | Default | Used in | Description | |---|---|---|---| -| `VERSION_READ_CMD` | `node -p "require('./package.json').version"` | version | Command that prints the current version string. | -| `BUMP_PATCH_CMD` | `make bump-patch` | version | Bump patch version, commit, and tag. | -| `BUMP_MINOR_CMD` | `make bump-minor` | version | Bump minor version, commit, and tag. | -| `BUMP_MAJOR_CMD` | `make bump-major` | version | Bump major version, commit, and tag. | -| `SET_VERSION_CMD` | `make set-version V=` | version | Set an arbitrary version (value appended as argument). | +| `VERSION_READ_CMD` | `node -p "require('./package.json').version"` | deploy | Command that prints the current version string. | +| `BUMP_PATCH_CMD` | `make bump-patch` | deploy | Bump patch version, commit, and tag. | +| `BUMP_MINOR_CMD` | `make bump-minor` | deploy | Bump minor version, commit, and tag. | +| `BUMP_MAJOR_CMD` | `make bump-major` | deploy | Bump major version, commit, and tag. | +| `SET_VERSION_CMD` | `make set-version V=` | deploy | Set an arbitrary version (value appended as argument). | ## Paths diff --git a/docs/customization.md b/docs/customization.md index 8b5bf2c..aa27fa8 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -153,7 +153,7 @@ Options: ## Version commands -The version-related placeholders control how `/version` reads and bumps versions: +The version-related placeholders control how `/deploy` reads and bumps versions: ```yaml VERSION_READ_CMD: "cat VERSION" # prints current version @@ -163,4 +163,4 @@ BUMP_MAJOR_CMD: make bump-major SET_VERSION_CMD: "make set-version V=" # arbitrary version (value appended) ``` -These commands are expected to handle the commit and tag creation themselves. `/version` calls them and then pushes. +These commands are expected to handle the commit and tag creation themselves. `/deploy` calls them and then pushes. diff --git a/docs/index.md b/docs/index.md index f508987..cea7281 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # Code Cannon Documentation -Code Cannon is a portable agent workflow skill library. Write your team's development workflow once — start, ship, review, version, release — and sync it to Claude Code, Cursor, and other AI coding agents across all your projects. +Code Cannon is a portable agent workflow skill library. Write your team's development workflow once — start, ship, review, deploy — and sync it to Claude Code, Cursor, and other AI coding agents across all your projects. ## How it works @@ -13,14 +13,13 @@ Code Cannon is a portable agent workflow skill library. Write your team's develo The intended sequence for a complete change: ``` -/start → [code + local test] → /ship → [QA on preview] → /version → /release +/start → [code + local test] → /ship → [QA on preview] → /deploy ``` - [`/start`](skills/start.md) — reads code, proposes an approach, **waits for human approval**, then creates the issue, branch, and writes code - [`/ship`](skills/ship.md) — runs checks, commits everything, pushes, opens the PR, spawns an agent review, merges if approved - [`/review`](skills/review.md) — standalone review on any PR; also called internally by `/ship` -- [`/version`](skills/version.md) — bumps semver, tags, pushes -- [`/release`](skills/release.md) — promotes to production, creates a GitHub Release, closes issues +- [`/deploy`](skills/deploy.md) — bumps version, creates a GitHub Release, promotes to production - [`/status`](skills/status.md) — read-only snapshot of open PRs, merged work, and open issues - [`/qa`](skills/qa.md) — view the QA queue or record findings on a specific issue - [`/setup`](skills/setup.md) — first-run onboarding: check config, labels, and milestone setup @@ -30,7 +29,7 @@ The intended sequence for a complete change: Code Cannon is opinionated about where humans stay in the loop: - `/start` pauses before creating the issue to confirm the implementation approach. -- `/release` requires an explicit "release" confirmation before promoting to production. +- `/deploy` requires an explicit "release" confirmation before promoting to production. - `/qa` shows the review comment and waits for approval before posting. - Everything else runs unattended. diff --git a/docs/skills/deploy.md b/docs/skills/deploy.md new file mode 100644 index 0000000..a4fae68 --- /dev/null +++ b/docs/skills/deploy.md @@ -0,0 +1,69 @@ +# /deploy + +Bump the project version, create a GitHub Release, and promote to production. + +**Source prompt:** [`../../skills/deploy.md`](../../skills/deploy.md) + +## What it does + +`/deploy` is the final step in the workflow. It combines version bumping and release creation into a single command. Its behavior varies by branching model: + +- **Trunk mode:** Optionally bumps the version, then creates a GitHub Release from `BRANCH_PROD` using the version tag. +- **Two-branch mode:** Optionally bumps the version, opens a promotion PR from `BRANCH_DEV` to `BRANCH_PROD`, merges it (which auto-closes linked issues), and creates a GitHub Release. +- **Three-branch mode:** Same as two-branch but promotes from `BRANCH_TEST` to `BRANCH_PROD`. + +## Usage + +``` +/deploy +``` + +No arguments. Must be run from the correct branch (determined by your branching model). + +## Step-by-step + +1. **Verify branch** — checks that you're on the required pre-production branch: + - **Trunk mode:** `BRANCH_PROD` + - **Two-branch mode:** `BRANCH_DEV` + - **Three-branch mode:** `BRANCH_TEST` + + Aborts if on the wrong branch. + +2. **Check current state** — finds the latest version tag, reads the current version, shows commits/PRs since the last tag, and lists any open unmerged PRs. + +3. **Ask about version bump** — presents bump options with computed values: + - **major** (e.g. 1.2.3 -> 2.0.0) + - **minor** (e.g. 1.2.3 -> 1.3.0) + - **patch** (e.g. 1.2.3 -> 1.2.4) + - set a specific version + - or skip (proceed with existing tag) + +4. **Version bump** (if requested) — runs the appropriate bump command (`BUMP_PATCH_CMD`, `BUMP_MINOR_CMD`, `BUMP_MAJOR_CMD`, or `SET_VERSION_CMD`), then pushes the commit and tag. + +5. **Compute release contents** — finds merge commits since the previous tag, extracts linked PRs and issues. + +6. **Human gate** — shows a release summary and waits for you to type "release". + +7. **Create GitHub Release** (trunk mode) or **Create promotion PR, merge, then create GitHub Release** (multi-branch modes). + +## Why it's built this way + +**Version bump and release in one flow.** Previously these were separate `/version` and `/release` commands. Combining them reduces the workflow from six commands to five and eliminates the possibility of bumping a version but forgetting to release, or vice versa. The version bump step is optional — if you've already tagged, you can skip straight to release. + +**Human gate is mandatory.** The "type release to confirm" gate exists because promoting to production is irreversible in practice. The summary gives you one last chance to verify that the right changes are going out. + +**Issues close on release, not on feature merge.** In multi-branch modes, feature PRs use `Issue #N` instead of `Closes #N`. Issues only auto-close when the promotion PR merges to `BRANCH_PROD`. This means issues stay open through the QA/staging phase, giving you visibility into what's deployed where. + +**State check surfaces surprises early.** Showing open unmerged PRs at the start prevents accidental releases that miss in-flight work. + +**Bump commands are external.** Code Cannon doesn't implement version bumping itself — it delegates to your project's Makefile or scripts. This keeps the skill generic across different version file formats (package.json, VERSION file, setup.py, etc.). + +## Config keys used + +- `VERSION_READ_CMD` — prints the current version +- `BUMP_PATCH_CMD`, `BUMP_MINOR_CMD`, `BUMP_MAJOR_CMD` — semver bump commands +- `SET_VERSION_CMD` — set an arbitrary version +- `DEPLOY_PREVIEW_CMD` — suggested for deploying to preview after version bump +- `DEPLOY_PROD_CMD` — suggested after release for deploying to production +- `BRANCH_PROD`, `BRANCH_DEV`, `BRANCH_TEST` — determine mode and promotion path +- `MERGE_CMD` — NOT used for promotion merges (uses `gh pr merge` directly) diff --git a/docs/skills/qa.md b/docs/skills/qa.md index 44ef854..611a8b5 100644 --- a/docs/skills/qa.md +++ b/docs/skills/qa.md @@ -46,7 +46,7 @@ Queries GitHub for all open issues with the `QA_READY_LABEL` and displays them a **Human gate on posting.** The comment is shown to the QA person before posting. This prevents accidental verdicts and gives a chance to edit findings. -**Never closes issues.** `/qa` records the verdict but never closes the issue. Closure happens when `/release` promotes to production and the `Closes #N` reference triggers GitHub's auto-close. QA verdict and issue closure are separate concerns. +**Never closes issues.** `/qa` records the verdict but never closes the issue. Closure happens when `/deploy` promotes to production and the `Closes #N` reference triggers GitHub's auto-close. QA verdict and issue closure are separate concerns. ## Config keys used diff --git a/docs/skills/release.md b/docs/skills/release.md deleted file mode 100644 index 0364903..0000000 --- a/docs/skills/release.md +++ /dev/null @@ -1,53 +0,0 @@ -# /release - -Create a GitHub Release and promote to production. - -**Source prompt:** [`../../skills/release.md`](../../skills/release.md) - -## What it does - -`/release` is the final step in the workflow. Its behavior varies by branching model: - -- **Trunk mode:** Creates a GitHub Release from `BRANCH_PROD` using the latest version tag. No promotion PR needed since features already merged to `BRANCH_PROD`. -- **Two-branch mode:** Opens a promotion PR from `BRANCH_DEV` to `BRANCH_PROD`, merges it (which auto-closes linked issues), and creates a GitHub Release. -- **Three-branch mode:** Same as two-branch but promotes from `BRANCH_TEST` to `BRANCH_PROD`. - -## Usage - -``` -/release -``` - -No arguments. Run after `/version` has tagged the release. - -## Step-by-step (trunk mode) - -1. **Verify state** — switches to `BRANCH_PROD` if needed, verifies a version tag exists on HEAD. -2. **Compute release contents** — finds merge commits since the previous tag, extracts linked PRs and issues. -3. **Human gate** — shows a release summary and waits for you to type "release". -4. **Create GitHub Release** — creates a release with a changelog listing all included PRs and issues. - -## Step-by-step (two-branch and three-branch mode) - -1. **Verify state** — switches to the pre-production branch, verifies a version tag exists on HEAD. -2. **Compute what's being promoted** — finds merge commits in the pre-production branch not yet in `BRANCH_PROD`, extracts linked PRs and issues. -3. **Human gate** — shows a release summary with all included PRs and issues that will close. Waits for you to type "release". -4. **Create promotion PR** — opens a PR from the pre-production branch to `BRANCH_PROD` with `Closes #N` references so issues auto-close on merge. -5. **Merge** — merges the promotion PR directly (does not use `MERGE_CMD`, which may refuse `BRANCH_PROD` targets). -6. **Create GitHub Release** — creates a release with a changelog and full comparison link. - -## Why it's built this way - -**Human gate is mandatory.** The "type release to confirm" gate exists because promoting to production is irreversible in practice. The summary gives you one last chance to verify that the right changes are going out. - -**Issues close on release, not on feature merge.** In multi-branch modes, feature PRs use `Issue #N` instead of `Closes #N`. Issues only auto-close when the promotion PR merges to `BRANCH_PROD`. This means issues stay open through the QA/staging phase, giving you visibility into what's deployed where. - -**Promotion PR bypasses MERGE_CMD.** `MERGE_CMD` typically includes safeguards that prevent direct merges to `BRANCH_PROD`. `/release` uses `gh pr merge` directly because this is the one intentional case where merging to production is correct. - -**Changelog is computed from git history.** The release notes are built from merge commits and their linked PRs/issues, not from manual input. This ensures the changelog matches what actually shipped. - -## Config keys used - -- `BRANCH_PROD`, `BRANCH_DEV`, `BRANCH_TEST` — determine mode and promotion path -- `MERGE_CMD` — NOT used for promotion merges (uses `gh pr merge` directly) -- `DEPLOY_PROD_CMD` — suggested after release for deploying to production diff --git a/docs/skills/ship.md b/docs/skills/ship.md index 1aa56c3..a2834d9 100644 --- a/docs/skills/ship.md +++ b/docs/skills/ship.md @@ -30,7 +30,7 @@ No arguments. `/ship` operates on the current branch. 5. **Push and open PR** — pushes the branch and creates a PR targeting the correct branch based on your branching model: - **Trunk mode:** targets `BRANCH_PROD`, uses `Closes #N` - - **Two/three-branch mode:** targets `BRANCH_DEV`, uses `Issue #N` (issue stays open until `/release`) + - **Two/three-branch mode:** targets `BRANCH_DEV`, uses `Issue #N` (issue stays open until `/deploy`) 6. **Review** (conditional) — behavior depends on `REVIEW_GATE`: - `ai` (default): spawns a review agent, waits for verdict @@ -64,7 +64,7 @@ The agent never infers reviewers from git history, blame, or team membership. **Mandatory check gate.** `CHECK_CMD` must pass before anything is committed or pushed. This prevents known-broken code from ever reaching a PR. -**Issue linking varies by mode.** In trunk mode, `Closes #N` auto-closes issues on merge because the PR targets the default branch. In multi-branch mode, `Issue #N` keeps issues open until `/release` promotes to production — this supports QA workflows where you want to track issues through the staging environment. +**Issue linking varies by mode.** In trunk mode, `Closes #N` auto-closes issues on merge because the PR targets the default branch. In multi-branch mode, `Issue #N` keeps issues open until `/deploy` promotes to production — this supports QA workflows where you want to track issues through the staging environment. **QA label automation.** In two-branch mode, `/ship` applies `QA_READY_LABEL` to signal that a feature is ready for testing on the preview environment. This feeds into the `/qa` skill's queue view. diff --git a/docs/skills/version.md b/docs/skills/version.md deleted file mode 100644 index eb570fd..0000000 --- a/docs/skills/version.md +++ /dev/null @@ -1,56 +0,0 @@ -# /version - -Bump the project version, tag, and push. - -**Source prompt:** [`../../skills/version.md`](../../skills/version.md) - -## What it does - -`/version` reads the current version, asks what kind of bump you want, runs the appropriate bump command, and pushes both the commit and the tag. Run it after features are merged and before deploying. - -## Usage - -``` -/version -``` - -No arguments. Must be run from the correct branch (determined by your branching model). - -## Step-by-step - -1. **Verify branch** — checks that you're on the required pre-production branch: - - **Trunk mode:** `BRANCH_PROD` - - **Two-branch mode:** `BRANCH_DEV` - - **Three-branch mode:** `BRANCH_TEST` - - Aborts if on the wrong branch. - -2. **Read current version** — runs `VERSION_READ_CMD` to display the current version. - -3. **Ask the user** — presents bump options with computed values: - - **major** (e.g. 1.2.3 -> 2.0.0) - - **minor** (e.g. 1.2.3 -> 1.3.0) - - **patch** (e.g. 1.2.3 -> 1.2.4) - - or set a specific version - -4. **Run bump command** — maps your choice to the appropriate command (`BUMP_PATCH_CMD`, `BUMP_MINOR_CMD`, `BUMP_MAJOR_CMD`, or `SET_VERSION_CMD`). These commands are expected to update the version file, create a commit, and create a tag. - -5. **Push** — pushes the commit and the tag to the remote. - -6. **Report** — tells you the new version and next steps based on your branching model. - -## Why it's built this way - -**Separate from /release.** Version bumping and release promotion are distinct steps. You might bump the version and deploy to a preview environment for testing before deciding to promote to production. Keeping them separate supports this QA workflow. - -**Branch enforcement.** `/version` runs from the pre-production branch, not from a feature branch. This ensures the version bump happens after features are merged and the integration branch is stable. - -**Bump commands are external.** Code Cannon doesn't implement version bumping itself — it delegates to your project's Makefile or scripts. This keeps the skill generic across different version file formats (package.json, VERSION file, setup.py, etc.). - -## Config keys used - -- `VERSION_READ_CMD` — prints the current version -- `BUMP_PATCH_CMD`, `BUMP_MINOR_CMD`, `BUMP_MAJOR_CMD` — semver bump commands -- `SET_VERSION_CMD` — set an arbitrary version -- `DEPLOY_PREVIEW_CMD` — suggested for deploying to preview after version bump -- `BRANCH_PROD`, `BRANCH_DEV`, `BRANCH_TEST` — determine which branch `/version` must run from diff --git a/skills/release.md b/skills/deploy.md similarity index 56% rename from skills/release.md rename to skills/deploy.md index d20526a..33dfb51 100644 --- a/skills/release.md +++ b/skills/deploy.md @@ -1,57 +1,175 @@ --- -skill: release +skill: deploy type: skill -description: "Create a GitHub Release; in multi-branch mode, also promotes the pre-production branch to `{{BRANCH_PROD}}`" +description: "Bump the project version, create a GitHub Release, and promote to production — handles both versioning and releasing in one step" args: none --- -## What `/release` does +## What `/deploy` does -{{#if !BRANCH_DEV}} -Creates a GitHub Release from `{{BRANCH_PROD}}`. Run this after `/version` has tagged the release. +`/deploy` is the final step in the workflow. It combines version bumping and release creation into a single command: check state, optionally bump the version, then create a GitHub Release (and in multi-branch mode, promote to production). + +--- + +## Step 1 — Verify branch + +Run: +```bash +git branch --show-current +``` + +{{#if BRANCH_TEST}} +Required branch: `{{BRANCH_TEST}}` (three-branch mode). {{/if}} -{{#if BRANCH_DEV}} {{#if !BRANCH_TEST}} -Creates a GitHub Release and promotes `{{BRANCH_DEV}}` to `{{BRANCH_PROD}}`. Run this after preview testing is confirmed. +{{#if BRANCH_DEV}} +Required branch: `{{BRANCH_DEV}}` (two-branch mode). {{/if}} -{{#if BRANCH_TEST}} -Creates a GitHub Release and promotes `{{BRANCH_TEST}}` to `{{BRANCH_PROD}}`. Run this after staging testing is confirmed. +{{#if !BRANCH_DEV}} +Required branch: `{{BRANCH_PROD}}` (trunk mode). {{/if}} {{/if}} +If not on the required branch, abort and say: "Switch to `` before running `/deploy`." + +Pull the latest changes before proceeding: +```bash +git pull +``` + --- -## Step 1 — Verify state +## Step 2 — Check current state + +### Find the latest version tag -Check the current branch: ```bash -git branch --show-current +git describe --tags --abbrev=0 2>/dev/null ``` +If no tag exists, note this is the first release. + +### Read current version + +```bash +{{VERSION_READ_CMD}} +``` + +### Show commits since last tag + +If a previous tag exists, show what's on the branch since that tag: + {{#if !BRANCH_DEV}} -### Verify on `{{BRANCH_PROD}}` with tag +```bash +git log ..HEAD --merges --pretty=format:"%s" +``` -If not on `{{BRANCH_PROD}}`, switch to it: +Parse PR numbers from merge commit subjects (format: `Merge pull request #N from branch/name`). +{{/if}} +{{#if BRANCH_DEV}} +{{#if !BRANCH_TEST}} +```bash +git log {{BRANCH_PROD}}..{{BRANCH_DEV}} --merges --pretty=format:"%s" +``` + +Parse PR numbers from merge commit subjects (format: `Merge pull request #N from branch/name`). +{{/if}} +{{#if BRANCH_TEST}} ```bash -git checkout {{BRANCH_PROD}} && git pull +git log {{BRANCH_PROD}}..{{BRANCH_TEST}} --merges --pretty=format:"%s" ``` -Verify a version tag exists on HEAD (i.e., `/version` was run before this): +Parse PR numbers from merge commit subjects. Note: some merge commits here may be promotion merges from `{{BRANCH_DEV}}` — these are identifiable by subjects matching "Merge ... from `{{BRANCH_DEV}}`". Include them in the list but note they are promotion merges; extract the original feature PRs from their PR bodies when possible. +{{/if}} +{{/if}} + +For each PR number found, retrieve the PR body: +```bash +gh pr view --json number,title,body +``` + +{{#if !BRANCH_DEV}} +Extract `Closes #N` references from PR bodies. Compile: +{{/if}} +{{#if BRANCH_DEV}} +Extract `Issue #N` and `Closes #N` references from PR bodies. Compile: +{{/if}} +- List of PRs included (number + title) +- List of issues linked to those PRs + +### Check for open unmerged PRs + +```bash +gh pr list --state open --json number,title,headRefName --jq '.[] | "#\(.number) \(.title) (\(.headRefName))"' +``` + +### Present the summary + +Tell the user: + +``` +Current version: X.Y.Z +Latest tag: vX.Y.Z + +Commits/PRs since last tag: + #17 — Add /docs directory + #18 — Fix checkout runtime error + +Open PRs not yet merged: + #19 — Add dark mode (feature/dark-mode) + +Would you like to bump the version before deploying? + - **patch** → X.Y.C + - **minor** → X.B.0 + - **major** → A.0.0 + - **specific** → enter a version number + - **skip** → proceed to release with the current tag +``` + +Wait for their response. + +--- + +## Step 3 — Version bump (if requested) + +If the user chose to skip, verify a version tag exists on HEAD: ```bash git describe --exact-match --tags HEAD 2>/dev/null ``` -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before running `/release`." Stop unless the user explicitly says to proceed anyway. +If no tag is found when skipping, warn: "No version tag found on HEAD. You must bump the version before deploying." Return to the version bump prompt. + +If the user chose a bump level, map their response to a command: + +| User says | Run | +|---|---| +| "patch" / anything mentioning patch | `{{BUMP_PATCH_CMD}}` | +| "minor" | `{{BUMP_MINOR_CMD}}` | +| "major" | `{{BUMP_MAJOR_CMD}}` | +| A specific version e.g. "2.4.5" | `{{SET_VERSION_CMD}} 2.4.5` | + +These commands update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. + +Push the version bump: +```bash +git push +git push --tags +``` + +Both the version bump commit and the tag must be pushed. --- -## Step 2 — Compute release contents +## Step 4 — Compute release contents + +Determine the version tag (either from the bump just performed, or from the existing HEAD tag if the user skipped bumping). Find the previous tag to determine the range: ```bash git describe --abbrev=0 ^ 2>/dev/null ``` +{{#if !BRANCH_DEV}} Find all merge commits since the previous tag: ```bash git log ..HEAD --merges --pretty=format:"%s" @@ -67,10 +185,19 @@ gh pr view --json number,title,body Extract `Closes #N` references from PR bodies (trunk PRs use `Closes #N`). Compile: - List of PRs included (number + title) - List of issues linked via `Closes #N` +{{/if}} +{{#if BRANCH_DEV}} +{{#if !BRANCH_TEST}} +Use the PR/issue list already computed in Step 2. If the version bump added new commits, re-fetch if needed. +{{/if}} +{{#if BRANCH_TEST}} +Use the PR/issue list already computed in Step 2. If the version bump added new commits, re-fetch if needed. +{{/if}} +{{/if}} --- -## Step 3 — HUMAN GATE +## Step 5 — HUMAN GATE Show the user the release summary. Example format: @@ -81,18 +208,34 @@ PRs included: #17 — Add /docs directory #18 — Fix checkout runtime error +{{#if !BRANCH_DEV}} Issues that will be referenced: +{{/if}} +{{#if BRANCH_DEV}} +Issues that will close: +{{/if}} #14 — Add /docs directory #15 — Fix checkout runtime error +{{#if !BRANCH_DEV}} Have you confirmed everything above is ready for production? Type 'release' to confirm. +{{/if}} +{{#if BRANCH_DEV}} +{{#if !BRANCH_TEST}} +Have you tested all of the above on preview? Type 'release' to confirm. +{{/if}} +{{#if BRANCH_TEST}} +Have you tested all of the above on the {{BRANCH_TEST}} environment? Type 'release' to confirm. +{{/if}} +{{/if}} ``` Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. --- -## Step 4 — Create GitHub Release +{{#if !BRANCH_DEV}} +## Step 6 — Create GitHub Release The version tag and PR/issue list are already known. If no previous tag exists, omit the "Full changelog" line. @@ -116,7 +259,7 @@ After the command runs, note the release URL from the output. --- -## Step 5 — Report +## Step 7 — Report Tell the user: @@ -124,68 +267,7 @@ Tell the user: {{/if}} {{#if BRANCH_DEV}} {{#if !BRANCH_TEST}} -### Verify on `{{BRANCH_DEV}}` with tag - -If not on `{{BRANCH_DEV}}`, switch to it: -```bash -git checkout {{BRANCH_DEV}} && git pull -``` - -Verify a version tag exists on HEAD: -```bash -git describe --exact-match --tags HEAD 2>/dev/null -``` - -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before promoting it." Stop unless the user explicitly says to proceed anyway. - ---- - -## Step 2 — Compute what's being promoted - -Find all merge commits in `{{BRANCH_DEV}}` not yet in `{{BRANCH_PROD}}`: -```bash -git log {{BRANCH_PROD}}..{{BRANCH_DEV}} --merges --pretty=format:"%s" -``` - -Parse PR numbers from the merge commit subjects. GitHub's format is: -`Merge pull request #N from branch/name` - -For each PR number found, retrieve the PR body: -```bash -gh pr view --json number,title,body -``` - -Extract `Issue #N` references from PR bodies (look for the pattern `Issue #\d+`). - -Compile: -- List of PRs being promoted (number + title) -- List of open issues linked to those PRs - ---- - -## Step 3 — HUMAN GATE - -Show the user the release summary. Example format: - -``` -Ready to release vX.Y.Z to production. - -PRs included: - #17 — Add /docs directory - #18 — Fix checkout runtime error - -Issues that will close: - #14 — Add /docs directory - #15 — Fix checkout runtime error - -Have you tested all of the above on preview? Type 'release' to confirm. -``` - -Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. - ---- - -## Step 4 — Create PR: `{{BRANCH_DEV}}` → `{{BRANCH_PROD}}` +## Step 6 — Create PR: `{{BRANCH_DEV}}` → `{{BRANCH_PROD}}` ```bash gh pr create --base {{BRANCH_PROD}} --head {{BRANCH_DEV}} \ @@ -209,7 +291,7 @@ The `Closes #N` lines will auto-close the linked issues because this PR merges i --- -## Step 5 — Merge +## Step 7 — Merge Do NOT use `{{MERGE_CMD}}` — it refuses PRs targeting `{{BRANCH_PROD}}`. Use `gh pr merge` directly: @@ -219,9 +301,9 @@ gh pr merge --merge --- -## Step 6 — Create GitHub Release +## Step 8 — Create GitHub Release -The version tag (from Step 1) and the PR/issue list (from Step 2) are already known. Find the previous tag to build the changelog link: +The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash git describe --abbrev=0 ^ 2>/dev/null @@ -251,74 +333,14 @@ After the command runs, note the release URL from the output. --- -## Step 7 — Report +## Step 9 — Report Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `{{DEPLOY_PROD_CMD}}` to ship to production." {{/if}} {{#if BRANCH_TEST}} -### Verify on `{{BRANCH_TEST}}` with tag - -If not on `{{BRANCH_TEST}}`, switch to it: -```bash -git checkout {{BRANCH_TEST}} && git pull -``` - -Verify a version tag exists on HEAD: -```bash -git describe --exact-match --tags HEAD 2>/dev/null -``` - -If no tag is found, warn: "No version tag found on HEAD. Run `/version` first to tag this release before promoting it." Stop unless the user explicitly says to proceed anyway. - ---- - -## Step 2 — Compute what's being promoted - -Find all merge commits in `{{BRANCH_TEST}}` not yet in `{{BRANCH_PROD}}`: -```bash -git log {{BRANCH_PROD}}..{{BRANCH_TEST}} --merges --pretty=format:"%s" -``` - -Parse PR numbers from the merge commit subjects. Note: some merge commits here may be promotion merges from `{{BRANCH_DEV}}` — these are identifiable by subjects matching "Merge ... from `{{BRANCH_DEV}}`". Include them in the list but note they are promotion merges; extract the original feature PRs from their PR bodies when possible. - -For each PR number found, retrieve the PR body: -```bash -gh pr view --json number,title,body -``` - -Extract `Issue #N` and `Closes #N` references from PR bodies. - -Compile (best-effort): -- List of PRs being promoted (number + title) -- List of open issues linked to those PRs - ---- - -## Step 3 — HUMAN GATE - -Show the user the release summary. Example format: - -``` -Ready to release vX.Y.Z to production. - -PRs included: - #17 — Add /docs directory - #18 — Fix checkout runtime error - -Issues that will close: - #14 — Add /docs directory - #15 — Fix checkout runtime error - -Have you tested all of the above on the {{BRANCH_TEST}} environment? Type 'release' to confirm. -``` - -Wait for the user to type "release" or an explicit confirmation. Any other response → stop and ask what they'd like to change. - ---- - -## Step 4 — Create PR: `{{BRANCH_TEST}}` → `{{BRANCH_PROD}}` +## Step 6 — Create PR: `{{BRANCH_TEST}}` → `{{BRANCH_PROD}}` ```bash gh pr create --base {{BRANCH_PROD}} --head {{BRANCH_TEST}} \ @@ -342,7 +364,7 @@ The `Closes #N` lines will auto-close the linked issues because this PR merges i --- -## Step 5 — Merge +## Step 7 — Merge Do NOT use `{{MERGE_CMD}}` — it refuses PRs targeting `{{BRANCH_PROD}}`. Use `gh pr merge` directly: @@ -352,9 +374,9 @@ gh pr merge --merge --- -## Step 6 — Create GitHub Release +## Step 8 — Create GitHub Release -The version tag (from Step 1) and the PR/issue list (from Step 2) are already known. Find the previous tag to build the changelog link: +The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash git describe --abbrev=0 ^ 2>/dev/null @@ -384,7 +406,7 @@ After the command runs, note the release URL from the output. --- -## Step 7 — Report +## Step 9 — Report Tell the user: diff --git a/skills/setup.md b/skills/setup.md index 72204af..f4f282b 100644 --- a/skills/setup.md +++ b/skills/setup.md @@ -59,8 +59,7 @@ List the available skills: | `/start` | Creates a GitHub issue, feature branch, and writes code | | `/ship` | Checks, commits, opens PR, spawns review agent, merges | | `/review` | Standalone code review on any PR | -| `/version` | Bumps semver, tags, pushes | -| `/release` | Promotes integration branch to main, closes issues | +| `/deploy` | Bumps version, creates GitHub Release, promotes to production | | `/status` | Snapshot of open PRs and issues for the team | | `/setup` | This skill — configures Code Cannon in a project | @@ -129,7 +128,7 @@ Cannot proceed without it. Stop. gh repo view --json name ``` -If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/release`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. +If exit code is non-zero: warn that most skills require a GitHub remote. Skills can be read and configured, but `/start`, `/ship`, `/review`, `/deploy`, and `/status` will fail without one. This is not a hard stop — ask if the user wants to continue configuring anyway. ### Check 5 — .codecannon.yaml present diff --git a/skills/ship.md b/skills/ship.md index f638aad..e1b15c6 100644 --- a/skills/ship.md +++ b/skills/ship.md @@ -116,7 +116,7 @@ If the output is non-empty, inform the user: "CODEOWNERS file detected — GitHu {{#if BRANCH_DEV}} PR target branch: `{{BRANCH_DEV}}` -Use `Issue #` as the issue reference — the issue stays open until `/release` promotes to `{{BRANCH_PROD}}`. +Use `Issue #` as the issue reference — the issue stays open until `/deploy` promotes to `{{BRANCH_PROD}}`. {{/if}} {{#if !BRANCH_DEV}} PR target branch: `{{BRANCH_PROD}}` (trunk mode) diff --git a/skills/version.md b/skills/version.md deleted file mode 100644 index 7446fc4..0000000 --- a/skills/version.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -skill: version -type: skill -description: Bump the project version, tag, and push — run before deploying to preview -args: none ---- - -## Step 1 — Verify branch - -Run: -```bash -git branch --show-current -``` - -{{#if BRANCH_TEST}} -Required branch: `{{BRANCH_TEST}}` (three-branch mode). -{{/if}} -{{#if !BRANCH_TEST}} -{{#if BRANCH_DEV}} -Required branch: `{{BRANCH_DEV}}` (two-branch mode). -{{/if}} -{{#if !BRANCH_DEV}} -Required branch: `{{BRANCH_PROD}}` (trunk mode). -{{/if}} -{{/if}} - -If not on the required branch, abort and say: "Switch to `` before running `/version`." - -Pull the latest changes before proceeding: -```bash -git pull -``` - ---- - -## Step 2 — Read current version - -```bash -{{VERSION_READ_CMD}} -``` - ---- - -## Step 3 — Ask the user - -Tell the user (filling in the actual computed values): - -> "You are on version X.Y.Z. Do you want to bump: -> - **major** → A.0.0 -> - **minor** → X.B.0 -> - **patch** → X.Y.C -> - or set a specific version?" - -Wait for their response. - ---- - -## Step 4 — Interpret and run - -Map the user's natural language response to a command: - -| User says | Run | -|---|---| -| "patch" / anything mentioning patch | `{{BUMP_PATCH_CMD}}` | -| "minor" | `{{BUMP_MINOR_CMD}}` | -| "major" | `{{BUMP_MAJOR_CMD}}` | -| A specific version e.g. "2.4.5" | `{{SET_VERSION_CMD}} 2.4.5` | - -These targets update the version manifest, create a git commit, and create a git tag. Do not create commits or tags manually. - ---- - -## Step 5 — Push - -```bash -git push -git push --tags -``` - -Both the version bump commit and the tag must be pushed. - ---- - -## Step 6 — Report - -Tell the user the new version and tag: - -{{#if !BRANCH_DEV}} -"Tagged vX.Y.Z. Run `/release` to create the GitHub Release." -{{/if}} -{{#if BRANCH_DEV}} -{{#if !BRANCH_TEST}} -"Tagged vX.Y.Z. Run `{{DEPLOY_PREVIEW_CMD}}` to deploy to preview for testing. When testing is complete, run `/release`." -{{/if}} -{{#if BRANCH_TEST}} -"Tagged vX.Y.Z. Run `{{DEPLOY_PREVIEW_CMD}}` to deploy to staging. When testing is complete, run `/release`." -{{/if}} -{{/if}} diff --git a/templates/AGENTS.md.template b/templates/AGENTS.md.template index 140cd3a..7a274f4 100644 --- a/templates/AGENTS.md.template +++ b/templates/AGENTS.md.template @@ -12,7 +12,7 @@ feature/* → main -->