@smbcloud / cli / commits / 052ae04

docs(release): adopt release/v{version} branch convention

Prepare every release on a `release/v<version>` branch off development, run CI on it, merge to development with --no-ff when green, delete the branch, then tag development (the tag push triggers the publish chain). - skill: document the branch convention + step-by-step workflow - Makefile: allow `make` to run on development OR release/v* (was development-only) so prep happens on the release branch Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

keypair34 committed Jun 28, 2026 at 12:59 UTC 052ae04bda7c96f9d7b0f2192a296431d933302b
2 files changed +22 -8
.agents/skills/smbcloud-cli-release/SKILL.md
+21 -7
@@ -58,21 +58,35 @@ The same applies to the Ruby gems in `sdk/gems/`. For each gem (`auth`, `model`)
58 - `ext/<gem>/Cargo.toml` — the native extension crate version AND the `smbcloud-*` dependency version constraints (e.g. `"0.3"` → `"0.4"`)
59 - Regenerate `Cargo.lock` with `cargo generate-lockfile` and `Gemfile.lock` with `bundle lock` inside the gem directory
60
61 -## Tagging discipline
61 +## Release branch convention
62
63 -Always tag releases on the `development` branch (the mainline). Never tag on a feature branch.
63 +Every release is prepared on a dedicated branch named **`release/v<version>`**, branched
64 +off `development`. Never prepare a release directly on `development`, and never tag a
65 +release on the `release/*` (or any feature) branch.
66
67 Reasoning:
68
69 +- The release-prep commits (version bump, lockfiles, generated metadata) can be reviewed
70 + and run through CI in isolation before they touch the mainline.
71 - The release commit history stays clean and linear on the default branch.
68 -- `cargo workspaces publish --allow-branch "*"` accepts any branch, but downstream workflows dispatch from the tag ref, so the tagged commit must contain all intended changes.
69 -- Tagging on a feature branch leaves `development` without the release commit and makes git history confusing.
72 +- `cargo workspaces publish --allow-branch "*"` accepts any branch, but downstream
73 + workflows dispatch from the tag ref, so the tagged commit must contain all intended changes.
74 +- Tagging on a feature branch leaves `development` without the release commit and makes git
75 + history confusing.
76
77 Workflow:
78
73 -1. Merge the feature branch into `development` with `--no-ff`.
74 -2. Tag on `development`: `git tag v<version>`.
75 -3. Push both: `git push origin development && git push origin v<version>`.
79 +1. Branch off an up-to-date `development`: `git checkout development && git pull && git checkout -b release/v<version>`.
80 +2. Prepare the release on that branch — `make patch|minor|major|custom VERSION=<version>`
81 + (see the version-sync rules above; `make` commits `Release <version>` on the branch).
82 +3. Push the branch and let CI run: `git push origin release/v<version>`.
83 +4. **Only when CI is green**, merge into `development` with `--no-ff`:
84 + `git checkout development && git merge --no-ff release/v<version>`.
85 +5. Delete the release branch (local and remote):
86 + `git branch -d release/v<version> && git push origin --delete release/v<version>`.
87 +6. Tag on `development`: `git tag v<version>`.
88 +7. Push both: `git push origin development && git push origin v<version>` — the tag push
89 + triggers `release-crate.yml` and the full publish chain.
90
91 If a tag was placed on the wrong commit (e.g. before a last-minute fix), move it:
92
Makefile
+1 -1
@@ -10,7 +10,7 @@ help:
10 release:
11 @test -n "$(BUMP)" || (echo "BUMP is required" && exit 1)
12 @if [ "$(BUMP)" = "custom" ] && [ -z "$(VERSION)" ]; then echo "VERSION is required for custom releases"; exit 1; fi
13 - @if [ "$$(git branch --show-current)" != "development" ]; then echo "Releases must be prepared on the development branch"; exit 1; fi
13 + @case "$$(git branch --show-current)" in development|release/v*) ;; *) echo "Releases must be prepared on development or a release/v<version> branch"; exit 1;; esac
14 @if [ -n "$$(git status --short --untracked-files=all)" ]; then echo "Working tree must be clean before running a release"; exit 1; fi
15 @if [ "$(BUMP)" = "custom" ]; then \
16 cargo workspaces version custom "$(VERSION)" --yes --no-git-commit --force "*"; \