main
md 173 lines 5.8 KB
Rendered Raw
1 ---
2 name: release
3 description: Cut a release of the onde-ed Rust workspace. Covers version bumping, the release branch/PR flow, tagging, and the two tag-triggered GitHub Actions (crates.io publish and Swift XCFramework). Use when asked to create, cut, or publish a release.
4 allowed-tools: Read, Write, Edit, Glob, Grep, Bash
5 user-invocable: true
6 ---
7
8 # Skill: Release
9
10 ## What This Skill Covers
11
12 How to cut a release of the `onde-ed` Cargo workspace: bumping the version,
13 landing it through the branch/PR flow, tagging, and what the two tag-triggered
14 workflows do automatically afterwards.
15
16 ## The one-number rule
17
18 The whole workspace releases on **one version**. Every crate declares
19 `version.workspace = true`, so a release changes exactly one source of truth:
20 the root `Cargo.toml`.
21
22 ```toml
23 [workspace.package]
24 version = "X.Y.Z"
25 ```
26
27 Plus the internal path dependencies in the same file, which pin the version
28 explicitly:
29
30 ```toml
31 ed-agent = { version = "X.Y.Z", path = "crates/ed-agent" }
32 ed-mcp = { version = "X.Y.Z", path = "crates/ed-mcp" }
33 ed-acp = { version = "X.Y.Z", path = "crates/ed-acp" }
34 ed-acp-tui = { version = "X.Y.Z", path = "crates/ed-acp-tui" }
35 ed-acp-testkit = { version = "X.Y.Z", path = "crates/ed-acp-testkit" }
36 ed-onde-account = { version = "X.Y.Z", path = "crates/ed-onde-account" }
37 ```
38
39 Bump all of these together. The crate manifests under `crates/*/Cargo.toml`
40 need no edits.
41
42 ## Versioning
43
44 Semver. Given the current `X.Y.Z`:
45 - **patch** (`Z+1`) — bug fixes, internal changes, no API additions.
46 - **minor** (`Y+1`, `Z=0`) — backwards-compatible API additions.
47 - **major** (`X+1`, `Y=Z=0`) — breaking changes.
48
49 ## Step-by-step
50
51 The base branch is **`development`**; `main` is the promoted/stable branch.
52 Releases land on `development` first, get tagged, then `development` is promoted
53 to `main`.
54
55 ### 1. Branch off `development`
56
57 ```sh
58 git checkout development && git pull
59 git checkout -b release/X.Y.Z
60 ```
61
62 ### 2. Bump the version
63
64 Edit the root `Cargo.toml` (`[workspace.package] version` and the internal
65 `ed-*` path-dependency versions). A quick way, run from the repo root:
66
67 ```sh
68 sed -i '' 's/OLD\.VER\.SION/X.Y.Z/g' Cargo.toml
69 ```
70
71 ### 3. Refresh the lockfile and verify
72
73 ```sh
74 cargo check --workspace # updates Cargo.lock, catches breakage
75 ```
76
77 `cargo fmt --all -- --check`, `cargo test --locked --workspace`, and
78 `cargo clippy --locked --workspace --all-targets -- -D warnings` must all pass —
79 the release workflow re-runs them and fails the publish otherwise.
80
81 ### 4. Commit and push
82
83 ```sh
84 git add Cargo.toml Cargo.lock
85 git commit -m "Release X.Y.Z: bump the workspace"
86 git push
87 ```
88
89 Commit subject convention: `Release X.Y.Z: bump the workspace`.
90
91 ### 5. Open the release PR → `development`
92
93 ```sh
94 gh pr create --base development --head release/X.Y.Z \
95 --title "Release X.Y.Z" --body "..."
96 gh pr edit <n> --add-assignee <you> --add-reviewer <reviewer>
97 ```
98
99 ### 6. Merge, then tag the merge commit
100
101 After approval, merge the PR, update local `development`, and tag **the merge
102 commit** (this is what every historical release tag points at):
103
104 ```sh
105 gh pr merge <n> --merge
106 git checkout development && git pull
107 git tag vX.Y.Z <merge-sha>
108 git push origin vX.Y.Z
109 ```
110
111 > The tag name carries a `v` prefix (`vX.Y.Z`); the workspace version does not
112 > (`X.Y.Z`). The workflows strip the `v` when comparing, so they must match on
113 > the numeric part.
114
115 ### 7. Promote `development` → `main`
116
117 Open a second PR to bring `main` up to the tagged state:
118
119 ```sh
120 gh pr create --base main --head development --title "Merge development → main (vX.Y.Z)"
121 ```
122
123 Merging it runs `ci.yml` on `main` as a final green check.
124
125 ## What the tag triggers
126
127 Pushing a `vX.Y.Z` tag fires **two** workflows. Both start with a `preflight`
128 job that validates the tag matches the `ed-agent` version in `Cargo.toml`, then
129 runs fmt + test + clippy. If the version and tag disagree, the release fails
130 here — this is the safety net for step 6.
131
132 ### `release-sdk-rust.yml` → crates.io
133
134 - Dry-runs the workspace publish with `cargo-workspaces` (plain
135 `cargo publish --dry-run` can't resolve the inter-crate path deps post-package).
136 - Publishes crates in dependency order to crates.io.
137 - `cargo workspaces plan --skip-published` makes re-runs safe: a run that dies
138 mid-publish only publishes the crates still missing from the registry.
139
140 ### `release-sdk-swift.yml` → XCFramework + `ed-swift`
141
142 - Builds the `EdFramework.xcframework` for Apple targets (~2h20m build;
143 **not** cancel-in-progress — killing it leaves half-published state).
144 - Creates a GitHub Release with the xcframework zip + checksum as assets.
145 - Checks out `ondeinference/ed-swift`, rewrites `Package.swift` with the new
146 release URL + checksum, copies the generated `ed_agent_ffi.swift`, commits,
147 pushes to `ed-swift` `main`, and tags it `vX.Y.Z`.
148
149 ## Manual / recovery runs
150
151 Both workflows have a `workflow_dispatch` with a `publish` boolean and a
152 `release_tag` input. Use this to re-publish an existing tag if a run failed
153 after tagging — e.g. the crates.io publish succeeded but the Swift build timed
154 out. Point it at the existing `vX.Y.Z` tag; the crates.io re-run skips anything
155 already on the registry.
156
157 ## Toolchain
158
159 The Rust toolchain is pinned in `rust-toolchain.toml` (currently `1.94.0`).
160 Workflows read `channel` from it, so a toolchain bump is a normal source change,
161 not release-time config.
162
163 ## Checklist
164
165 - [ ] On a `release/X.Y.Z` branch off `development`.
166 - [ ] Root `Cargo.toml`: `[workspace.package] version` + all `ed-*` path deps bumped.
167 - [ ] `cargo check --workspace` run (Cargo.lock updated).
168 - [ ] fmt / test / clippy all green locally.
169 - [ ] Commit `Release X.Y.Z: bump the workspace`.
170 - [ ] PR → `development`, reviewed, merged.
171 - [ ] `vX.Y.Z` tag on the merge commit, pushed.
172 - [ ] `development` → `main` PR opened/merged.
173 - [ ] Both tag workflows green (crates.io + Swift).