From 0896b16db3e8ee89ffd08f13c848bc07185f3107 Mon Sep 17 00:00:00 2001 From: zzstoatzz Date: Thu, 3 Sep 2026 01:46:18 -0500 Subject: [PATCH] release: add /release skill; point operations doc at it Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01Th6389kN3H2AyUae7yEJAW --- .claude/skills/release/SKILL.md | 70 +++++++++++++++++++++++++++++++++ docs/operations.md | 4 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 .claude/skills/release/SKILL.md diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md new file mode 100644 index 0000000..00100e5 --- /dev/null +++ b/.claude/skills/release/SKILL.md @@ -0,0 +1,70 @@ +--- +name: release +description: cut a zds release end to end — bump build.zig.zon, promote the unreleased changelog section, run the checks, tag, push (which deploys pds.zat.dev via spindle), verify the live version, publish the container image. use when asked to release, tag, or ship a version, or what the next release would contain. +--- + +release the current state of `main`. context (if any): $ARGUMENTS + +zds ships two ways from one tag: the push to `main` deploys `pds.zat.dev` +through `.tangled/workflows/deploy.yml`, and `just docker-publish-release` +pushes the image to `atcr.io/zat.dev/zds`. the tag is the release; the +changelog section is its notes. policy (patch vs minor vs major) lives in +[docs/operations.md#releases](../../../docs/operations.md#releases). + +## version locations + +- `build.zig.zon` line 3: `.version = "x.y.z"` — `GET /xrpc/_health` reports + it, which is how the live deploy is verified +- `CHANGELOG.md`: `## unreleased` at the top collects entries as work lands; + a release renames it to `## x.y.z — YYYY-MM-DD`. entries are + `- **fix**:` / `- **feat**:` / `- **refactor**:` / `- **docs**:`, prose + that says what a client or operator sees now versus before, with nested + bullets for the per-method minutiae. there is no empty `## unreleased` + between releases; the next change recreates it. + +## steps + +1. **what is shipping**: `git log v..main --format='%h %s'` and read + `## unreleased`. every commit on that range that a client or operator can + notice should have an entry; add the missing ones before bumping. +2. **decide the bump**: patch for compatibility fixes and operator-safe bug + fixes; minor for protocol surface, storage shape (a schema migration + counts), or operator workflow changes; major only for a declared + incompatible contract. before 1.0 a protocol-parity fix is still a patch. +3. **update**: `.version` in `build.zig.zon`; rename `## unreleased` to + `## x.y.z — `. +4. **checks** (all must pass, no flags): + ```sh + just test + just smoke + just smoke-permissioned # when com.atproto.space.* or storage changed + git diff --check + zig zen + ``` + `zig fmt --check` on the files the release touches; a few untouched + files fail a whole-tree check and are not this release's problem. +5. **parity releases**: if the range changed protocol behaviour or storage + shape, complete the + [benchmark stage checklist](../../../bench/README.md#stage-checklist) + and record any remaining mismatch as a decision or follow-up in `docs/`. +6. **commit**: `release: vx.y.z` with only the version and changelog edits. +7. **tag and push**: `git tag -a vx.y.z -m "vx.y.z" && git push origin main vx.y.z`. + the push is the deploy gate; never run `flyctl deploy` ahead of it. +8. **watch the deploy**: the remote is a repo DID, so `tg` needs the + handle/repo form: `tg pipeline status zat.dev/zds`. it is a finite status + line per workflow, not the interactive `ssh -t ... 3333` viewer the push + prints. when `deploy to fly.io` finishes, verify the live version: + ```sh + curl -fsS https://pds.zat.dev/xrpc/_health | jq .version + ``` + then follow the post-deploy checks in + [docs/deployment.md](../../../docs/deployment.md): a 200 from `_health` + alone is not verification when the change touched auth, sync, or storage. +9. **container image**: `just docker-publish-release vx.y.z` (builds locally + with docker/orbstack; needs an `atcr.io` session, which is a browser + OAuth login, not an app password). this publishes `vx.y.z`, `latest`, and + the commit tag. +10. **devlog**: if the release has a technical story worth telling (a new + subsystem, a parity finding across PDS implementations, a measured + perf win), suggest a `docs/` note or a notes-repo entry and ask before + writing it. diff --git a/docs/operations.md b/docs/operations.md index 608b7a0..183788e 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -211,7 +211,9 @@ bug fixes. Minor releases are for meaningful protocol surface, storage shape, or operator workflow changes. Major releases are reserved for explicit incompatible production contracts once ZDS declares a stable surface. -Release checklist: +The `/release` skill (`.claude/skills/release/SKILL.md`) walks this end to end, +including the changelog promotion, the spindle deploy watch, and the live +version check. Release checklist: ```sh just test -- 2.51.2