main
md 149 lines 6.4 KB
Rendered Raw
1 ---
2 name: release
3 description: Use whenever cutting, preparing, tagging, or publishing an onde-cli release — version bumps, release branch, merges, tagging, pushing to trigger the publish pipeline, and verifying it landed. Also use when a release went wrong (wrong tag target, failed crates.io verify, development left behind main, unsigned release commits) and the repo state needs repair. Trigger even if the user only says "release vX.Y.Z", "bump the version", "tag a release", or "publish the new version".
4 user-invocable: true
5 ---
6
7 # Release skill
8
9 End-to-end release procedure for `onde-cli`. Complements the git skill (merge rules)
10 and the distribution skill (channel details) — this skill is the concrete runbook.
11
12 ## Decide the version
13
14 - Look at `git tag -l 'v*' --sort=-v:refname | head -1` for the latest release.
15 - Look at the commits since (`git log v<latest>..development --oneline`).
16 Fixes and chores only → patch bump. New user-facing features → minor bump.
17 - Check for an abandoned `release/vX.Y.Z` branch — its version is usually the
18 intended next one. If it exists, inspect it (`git log development..release/...`)
19 before deciding to reuse or delete it; do not blindly `branch -D` without looking,
20 and never reuse a branch whose commits were made unsigned or by the wrong identity.
21
22 ## Version bump surfaces
23
24 These files pin the crate version and must all move together:
25
26 - `Cargo.toml` — `version = "X.Y.Z"` in `[package]`
27 - `pub/onde_cli/pubspec.yaml` — `version: X.Y.Z`
28 - `server.json` — three occurrences: top-level `version`, and the npm and NuGet
29 `packages[].version` entries (search for the old version string to catch all)
30
31 `docs/mcp-registry.md` and `.github/workflows/release-mcp-registry.yml` mention
32 past versions only as historical examples — do not bump those.
33
34 The npm wrapper manifests are NOT bump targets: the committed `package.json` files
35 are rewritten at release time by `npm/scripts/render-*.cjs` from the tag.
36
37 After editing, run `cargo check --locked` (or let the build update `Cargo.lock`)
38 so the lockfile carries the new version, and commit it in the same bump commit.
39
40 ## Sequence
41
42 Follow the git skill's branch flow — `release/vX.Y.Z → development → main`,
43 `--no-ff` at every hop, tag on the final `main` merge commit. Concretely:
44
45 ```bash
46 git checkout development
47 git pull <remote> development # start from the pushed tip
48 git checkout -b release/vX.Y.Z
49 # ... edit the bump surfaces ...
50 git commit -am "Prepare vX.Y.Z" # signed, correct identity (see below)
51 git checkout development
52 git merge --no-ff release/vX.Y.Z -m "Merge release prep for vX.Y.Z"
53 git checkout main
54 git pull <remote> main
55 git merge --no-ff development -m "Merge development for vX.Y.Z"
56 git tag vX.Y.Z
57 git push <remote> development main vX.Y.Z
58 git branch -d release/vX.Y.Z # only after the merge lands
59 ```
60
61 The remote here is the one whose URL is the sigit.si or GitHub org repo —
62 check `git remote -v`; this repo is commonly cloned with per-account remotes
63 (`gh-setoelkahfi`, `gh-paydii`, `gh-keypair34`) rather than `origin`.
64
65 ### What a good result looks like
66
67 - The tag sits on the step-3 merge commit on `main` (`git log --graph main`
68 shows a merge commit directly above the previous release).
69 - `git log development..main` and `git log main..development` are both empty
70 after the merges — the two branches carry identical trees.
71 - Never tag a release-branch tip or a bare bump commit on `main`; if the work
72 somehow already landed on `main` linearly, follow the git skill's fallback
73 (normal commit, tag it) rather than rewriting history.
74
75 ### Post-push back-merge check
76
77 If anything reached `main` without passing through `development` first (hotfix,
78 manual push, a fast-forwarded release), bring it back immediately:
79
80 ```bash
81 git checkout development
82 git merge --no-ff main -m "Merge main for vX.Y.Z"
83 git push <remote> development
84 ```
85
86 A release is not done until the two branches contain the same tree.
87
88 ## Commits and signatures — read the git-commit-signing skill first
89
90 Release commits must be GPG-signed by the maintainer identity that GitHub can
91 verify (this repo: `Seto Elkahfi <1797197+setoelkahfi@users.noreply.github.com>`,
92 EDDSA key `2B76DF0F04014E36`). The `gh` CLI's active account is independent of
93 git config — set both, and verify before pushing:
94
95 ```bash
96 git log -1 --format='%an <%ae> sig:%G? %GK' # want sig:G and the right key
97 gh api repos/<owner>/<repo>/commits/<sha> --jq .commit.verification.verified
98 ```
99
100 Every `git commit` and `git merge` in this flow creates a commit — configure
101 signing so merges are signed too, or amend unsigned ones before pushing
102 (`git commit --amend --no-edit -S`, only on unpushed commits).
103
104 Commit trailer: end release-related commit messages with
105
106 ```
107 Co-Authored-By: siGit Code v1.6.7-acp <noreply@sigit.si>
108 ```
109
110 ## The tag push is the release
111
112 Pushing `vX.Y.Z` triggers `release-crates.yml`, which verifies the tag against
113 `Cargo.toml` and `pubspec.yaml`, publishes the crate, then dispatches the
114 wrapper workflows (GitHub Releases, npm, NuGet, PyPI, then Homebrew and pub.dev
115 after the GitHub Release assets exist). There is no separate "publish" step.
116
117 Watch it land:
118
119 ```bash
120 gh run list --branch vX.Y.Z
121 gh run watch <run-id> --exit-status
122 ```
123
124 `CI` also runs on the tag push; both should be green. If `release-crates` fails,
125 no wrapper publishes — fix the cause, move the tag only if it has not published
126 anything yet (crates.io versions are immutable; a failed verify is safe to retry,
127 a published crate is not).
128
129 ## Verify
130
131 After the pipeline finishes, spot-check the fan-out (all idempotent, safe to re-check):
132
133 - crates.io: `cargo search onde-cli --limit 1`
134 - GitHub Release: `gh release view vX.Y.Z`
135 - npm: `npm view onde-cli version`
136 - PyPI: `https://pypi.org/pypi/onde-cli/json` → `info.version`
137 - NuGet: flat container index for `onde-cli`
138 - Homebrew/pub.dev trail the GitHub Release; they may take a few extra minutes
139
140 ## Failure modes seen before
141
142 - Fast-forwarding `main` to the bump commit and tagging it — leaves no merge
143 commit, and leaves `development` behind. Back-merge `main` into `development`
144 right away and prefer merge commits next time.
145 - Deleting a leftover `release/` branch that contained unsigned bump commits and
146 redoing the bump fresh — fine, but check it first.
147 - Forgetting `Cargo.lock` in the bump commit.
148 - Pushing with the wrong `gh` account active — the push works, but PR/issue
149 actions afterwards get attributed to the wrong identity.