Publish the play crate from release-crates.yml

frontend and cli depend on smbcloud-ascapi-play, but the release workflow never published it, so a tag push would stop at frontend. Publish play after reports, check it builds alone in both CI and the release verify job, and list it in the release skill's tag and publisher counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Seto Elkahfi committed Oct 25, 2026 at 18:00 UTC 1e84a417a330b250b60417c75214d3b7d529b1f1
3 files changed +18 -9
.agents/skills/ascapi-release/SKILL.md
+13 -7
@@ -88,8 +88,8 @@ cargo workspaces version custom 0.3.0 \
88 - `--force '*'` bumps every crate to the shared version even if cargo-workspaces
89 thinks some are unchanged (single-version workspace).
90
91 -This creates the `Release X.Y.Z` commit, the `vX.Y.Z` tag, and **8 per-crate
92 -tags** `smbcloud-ascapi-{aso,cli,core,frontend,mcp,pricing,reports,signing}@X.Y.Z`,
91 +This creates the `Release X.Y.Z` commit, the `vX.Y.Z` tag, and **9 per-crate
92 +tags** `smbcloud-ascapi-{aso,cli,core,frontend,mcp,play,pricing,reports,signing}@X.Y.Z`,
93 all pointing at the Release commit.
94
95 ## Step 3 — sync `server.json`
@@ -111,7 +111,8 @@ NEW=$(git rev-parse HEAD)
111 for t in \
112 smbcloud-ascapi-aso@X.Y.Z smbcloud-ascapi-cli@X.Y.Z \
113 smbcloud-ascapi-core@X.Y.Z smbcloud-ascapi-frontend@X.Y.Z \
114 - smbcloud-ascapi-mcp@X.Y.Z smbcloud-ascapi-pricing@X.Y.Z \
114 + smbcloud-ascapi-mcp@X.Y.Z smbcloud-ascapi-play@X.Y.Z \
115 + smbcloud-ascapi-pricing@X.Y.Z \
116 smbcloud-ascapi-reports@X.Y.Z smbcloud-ascapi-signing@X.Y.Z \
117 vX.Y.Z; do
118 git tag -f "$t" "$NEW"
@@ -123,7 +124,7 @@ changes the hash again. After all amends settle, re-point the tags to the final
124 HEAD and verify they all land on one commit:
125
126 ```sh
126 -git tag --points-at HEAD # must list all 9 tags
127 +git tag --points-at HEAD # must list all 10 tags
128 git log -1 --format='sig=%G? key=%GK' # must be sig=G key=2B76DF0F04014E36
129 ```
130
@@ -156,9 +157,9 @@ they don't start extra runs. Three jobs run in order:
157 1. **`verify`** fails the run if the tag differs from the workspace version in
158 `Cargo.toml`, then runs `cargo fmt --check`, clippy with `-D warnings`,
159 `cargo test --workspace --locked`, and `cargo check` on `core`, `aso`,
159 - `pricing`, `signing` and `reports` on their own.
160 + `pricing`, `signing`, `reports` and `play` on their own.
161 2. **`publish`** (environment `crates-io`) publishes `core`, `aso`, `pricing`,
161 - `signing`, `reports`, `frontend`, `mcp`, `cli`, in that order, with
162 + `signing`, `reports`, `play`, `frontend`, `mcp`, `cli`, in that order, with
163 `cargo publish -p <crate> --locked`. Authentication is crates.io trusted
164 publishing: the job exchanges its GitHub OIDC token through
165 `rust-lang/crates-io-auth-action`, so there is no registry token secret.
@@ -180,10 +181,15 @@ gh run watch <run-id>
181
182 ### One-time setup it depends on
183
183 -- Each of the eight crates has a trusted publisher on crates.io for repository
184 +- Each of the nine crates has a trusted publisher on crates.io for repository
185 `smbcloudXYZ/smbcloud-ascapi` and workflow `release-crates.yml`. If a crate
186 is missing one, `cargo publish` fails for that crate and the later crates are
187 not published. Add the publisher and re-run.
188 +- A brand-new crate can't get a trusted publisher until it exists on
189 + crates.io, so its first version goes up by hand with a token
190 + (`cargo publish -p <crate>`), then the publisher is added. `play` went
191 + through this at 0.3.0. Add any new crate to the `crates=(...)` list in
192 + `release-crates.yml` in dependency order before tagging.
193 - If a trusted publisher names an environment, it must be `crates-io`, which
194 is the environment the `publish` job runs in.
195
.github/workflows/ci.yml
+1
@@ -72,6 +72,7 @@ jobs:
72 cargo check --package smbcloud-ascapi-core --locked
73 cargo check --package smbcloud-ascapi-aso --locked
74 cargo check --package smbcloud-ascapi-signing --locked
75 + cargo check --package smbcloud-ascapi-play --locked
76
77 - name: Build docs
78 # Intra-doc links are load-bearing in this crate: the certificate
.github/workflows/release-crates.yml
+4 -2
@@ -92,7 +92,7 @@ jobs:
92 - name: Check the lower crates build alone
93 shell: bash
94 run: |
95 - for crate in core aso pricing signing reports; do
95 + for crate in core aso pricing signing reports play; do
96 cargo check -p "smbcloud-ascapi-${crate}" --locked
97 done
98
@@ -135,13 +135,15 @@ jobs:
135
136 # Dependency order: a crate can only be published once everything it
137 # depends on is on crates.io. core first, then the domain crates
138 - # that only depend on core, then frontend, mcp, and the CLI last.
138 + # that only depend on core, then play (which depends on neither),
139 + # then frontend, mcp, and the CLI last.
140 crates=(
141 core
142 aso
143 pricing
144 signing
145 reports
146 + play
147 frontend
148 mcp
149 cli