From 100bddf4e58f8995db6b36267f32b74929725913 Mon Sep 17 00:00:00 2001 From: Sebastien Taggart Date: Wed, 25 Mar 2026 15:17:24 -0400 Subject: [PATCH 1/2] Add three-branch workflow support to Makefile.agents.mk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce STAGING_BRANCH variable (empty by default) and promote target for projects using feature → dev → staging → main workflow. Add staging branch to protected branch guards in pr, abandon, and merge targets. Update deploy-preview to push STAGING_BRANCH when set. Regenerate skill commands via sync.sh. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/qa.md | 1 - .claude/commands/release.md | 1 - .claude/commands/setup.md | 3 +-- .claude/commands/ship.md | 1 - .claude/commands/start.md | 6 +++--- .claude/commands/version.md | 3 +-- Makefile | 14 ++++++++++---- Makefile.agents.mk | 31 ++++++++++++++++++++++++++++++- skills/start.md | 4 ++-- 9 files changed, 47 insertions(+), 17 deletions(-) diff --git a/.claude/commands/qa.md b/.claude/commands/qa.md index bab055b..1dbb3d4 100644 --- a/.claude/commands/qa.md +++ b/.claude/commands/qa.md @@ -1,4 +1,3 @@ - You are executing the `/qa` skill. Your argument is: $ARGUMENTS --- diff --git a/.claude/commands/release.md b/.claude/commands/release.md index c43395c..5642a08 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -1,4 +1,3 @@ - You are executing the `/release` skill. Your argument is: $ARGUMENTS --- diff --git a/.claude/commands/setup.md b/.claude/commands/setup.md index 99d3bee..1a4b5c5 100644 --- a/.claude/commands/setup.md +++ b/.claude/commands/setup.md @@ -1,4 +1,3 @@ - You are executing the `/setup` skill. Your argument is: $ARGUMENTS --- @@ -470,4 +469,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 bd287f3..53b3351 100644 --- a/.claude/commands/ship.md +++ b/.claude/commands/ship.md @@ -1,4 +1,3 @@ - You are executing the `/ship` skill. Your argument is: $ARGUMENTS --- diff --git a/.claude/commands/start.md b/.claude/commands/start.md index cdac11e..144a6be 100644 --- a/.claude/commands/start.md +++ b/.claude/commands/start.md @@ -141,7 +141,7 @@ Show the user: `On branch feature/` Now write the code. Do NOT commit anything. -When done, say: **"The code is ready for review. Please run `make dev` and test locally. Let me know if it looks good, needs changes, or should be scrapped."** +When done, say: **"The code is ready for review. Please run `make dev` and test locally. Let me know if it looks good, needs changes, or should be scrapped. When you're happy, run `/ship` to commit, push, and open a PR."** - User says looks good → run `/ship` - User requests changes → iterate, repeat this message @@ -195,7 +195,7 @@ gh issue comment --body "Resuming work. --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `` → omit (or create if `false` is `true`). Never apply a label not in `` unless `false` is `true`. Milestone resolution order: per-invocation flag → `` config → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.claude/commands/version.md b/.claude/commands/version.md index be872a0..fa78575 100644 --- a/.claude/commands/version.md +++ b/.claude/commands/version.md @@ -1,4 +1,3 @@ - You are executing the `/version` skill. Your argument is: $ARGUMENTS --- @@ -80,4 +79,4 @@ Report based on mode: - **Trunk mode** (`dev` empty): "Tagged vX.Y.Z. Run `/release` to create the GitHub Release." - **Two-branch mode** (`dev` set, `` empty): "Tagged vX.Y.Z. Run `make deploy-preview` to deploy to preview for testing. When testing is complete, run `/release`." - **Three-branch mode** (both set): "Tagged vX.Y.Z. Run `make deploy-preview` to deploy to staging. When testing is complete, run `/release`." - + diff --git a/Makefile b/Makefile index 3a1989c..487f153 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,9 @@ +# Makefile — CodeCannon project-specific targets +# +# Workflow targets (branch, pr, abandon, merge, promote) come from Makefile.agents.mk. +# This file adds CodeCannon-specific targets: sync, versioning, and deployment. + +INTEGRATION_BRANCH = dev include Makefile.agents.mk .PHONY: check dev sync bump-patch bump-minor bump-major set-version deploy-preview deploy-prod @@ -57,10 +63,10 @@ endif git commit -m "Bump version to $(V)" git tag v$(V) -# Publish the integration branch so consumers can pick up changes via submodule update. +# Push the integration branch for preview/testing. deploy-preview: - git push origin development + git push origin $(INTEGRATION_BRANCH) -# Publish a tagged release to main. +# Publish a tagged release to production. deploy-prod: - git push origin main --tags + git push origin $(PRODUCTION_BRANCH) --tags diff --git a/Makefile.agents.mk b/Makefile.agents.mk index c846c10..0841339 100644 --- a/Makefile.agents.mk +++ b/Makefile.agents.mk @@ -10,13 +10,24 @@ # Configuration: # INTEGRATION_BRANCH — the branch PRs target (default: development) # PRODUCTION_BRANCH — the production branch (default: main) +# STAGING_BRANCH — optional staging/pre-prod branch (default: empty) # FEATURE_PREFIX — prefix for feature branches (default: feature/) +# +# Workflow modes: +# Two-branch (default): feature → INTEGRATION_BRANCH → PRODUCTION_BRANCH +# Three-branch: feature → INTEGRATION_BRANCH → STAGING_BRANCH → PRODUCTION_BRANCH +# +# Set STAGING_BRANCH to enable three-branch mode. When set: +# - `promote` target becomes available (PR: integration → staging) +# - STAGING_BRANCH is protected from direct feature work +# - `deploy-preview` pushes STAGING_BRANCH instead of INTEGRATION_BRANCH INTEGRATION_BRANCH ?= development PRODUCTION_BRANCH ?= main +STAGING_BRANCH ?= FEATURE_PREFIX ?= feature/ -.PHONY: branch pr abandon merge +.PHONY: branch pr abandon merge promote # Create a feature branch from the integration branch. # Usage: make branch name= @@ -33,6 +44,9 @@ pr: if [ "$$branch" = "$(PRODUCTION_BRANCH)" ] || [ "$$branch" = "$(INTEGRATION_BRANCH)" ]; then \ echo "Error: cannot PR from $$branch. Use a feature branch."; exit 1; \ fi; \ + if [ -n "$(STAGING_BRANCH)" ] && [ "$$branch" = "$(STAGING_BRANCH)" ]; then \ + echo "Error: cannot PR from $$branch. Use a feature branch."; exit 1; \ + fi; \ git push -u origin "$$branch" && \ gh pr create --base $(INTEGRATION_BRANCH) --fill @@ -42,6 +56,9 @@ abandon: if [ "$$branch" = "$(PRODUCTION_BRANCH)" ] || [ "$$branch" = "$(INTEGRATION_BRANCH)" ]; then \ echo "Error: cannot abandon $$branch."; exit 1; \ fi; \ + if [ -n "$(STAGING_BRANCH)" ] && [ "$$branch" = "$(STAGING_BRANCH)" ]; then \ + echo "Error: cannot abandon $$branch."; exit 1; \ + fi; \ git checkout . && \ git clean -fd && \ git checkout $(INTEGRATION_BRANCH) && \ @@ -54,6 +71,9 @@ merge: if [ "$$branch" = "$(PRODUCTION_BRANCH)" ] || [ "$$branch" = "$(INTEGRATION_BRANCH)" ]; then \ echo "Error: cannot merge from $$branch. Use a feature branch."; exit 1; \ fi; \ + if [ -n "$(STAGING_BRANCH)" ] && [ "$$branch" = "$(STAGING_BRANCH)" ]; then \ + echo "Error: cannot merge from $$branch. Use a feature branch."; exit 1; \ + fi; \ pr_url=$$(gh pr view --json url -q .url 2>/dev/null); \ if [ -z "$$pr_url" ]; then \ echo "Error: no open PR found for $$branch."; exit 1; \ @@ -66,3 +86,12 @@ merge: git checkout $(INTEGRATION_BRANCH) && \ git pull origin $(INTEGRATION_BRANCH) && \ echo "PR merged into $(INTEGRATION_BRANCH)." + +# Promote integration branch to staging. Creates a PR: INTEGRATION_BRANCH → STAGING_BRANCH. +# Only available in three-branch mode (STAGING_BRANCH is set). +promote: +ifndef STAGING_BRANCH + $(error promote requires STAGING_BRANCH to be set (three-branch mode)) +endif + gh pr create --base $(STAGING_BRANCH) --head $(INTEGRATION_BRANCH) \ + --title "Promote $(INTEGRATION_BRANCH) → $(STAGING_BRANCH)" --fill diff --git a/skills/start.md b/skills/start.md index 792e746..8bd5ae0 100644 --- a/skills/start.md +++ b/skills/start.md @@ -144,7 +144,7 @@ Show the user: `On branch feature/` Now write the code. Do NOT commit anything. -When done, say: **"The code is ready for review. Please run `{{DEV_CMD}}` and test locally. Let me know if it looks good, needs changes, or should be scrapped."** +When done, say: **"The code is ready for review. Please run `{{DEV_CMD}}` and test locally. Let me know if it looks good, needs changes, or should be scrapped. When you're happy, run `/ship` to commit, push, and open a PR."** - User says looks good → run `/ship` - User requests changes → iterate, repeat this message @@ -198,7 +198,7 @@ gh issue comment --body "Resuming work. Date: Wed, 25 Mar 2026 15:21:14 -0400 Subject: [PATCH 2/2] Remove misleading deploy-preview note from header comment The deploy-preview behavior is a consumer Makefile concern, not controlled by Makefile.agents.mk. Co-Authored-By: Claude Opus 4.6 (1M context) --- Makefile.agents.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.agents.mk b/Makefile.agents.mk index 0841339..35a3ea9 100644 --- a/Makefile.agents.mk +++ b/Makefile.agents.mk @@ -20,7 +20,6 @@ # Set STAGING_BRANCH to enable three-branch mode. When set: # - `promote` target becomes available (PR: integration → staging) # - STAGING_BRANCH is protected from direct feature work -# - `deploy-preview` pushes STAGING_BRANCH instead of INTEGRATION_BRANCH INTEGRATION_BRANCH ?= development PRODUCTION_BRANCH ?= main