docs: add operator release runbook#88
Conversation
One-page operator crib sheet for cutting a crates.io release train via Shipper. Cross-references `docs/release-v0.3.0-rc.1-manifest.md` for the deep reference detail (topo order, rate-limit plan, workflow contract); this doc focuses on the operator's sharp edges: - pre-flight checklist (CI, rehearsal, crates.io status, auth) - exact tag-cut commands - during-train stop conditions matrix - resume via `mode=resume --field artifact_run_id=...` - post-train verification steps - containment via reverse-topo `cargo yank` No code, manifest, or workflow changes. Doc-only.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 40 minutes and 7 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive release runbook for operators using Shipper to publish crates to crates.io. The documentation covers pre-flight checks, tag creation, monitoring, error handling, and post-release verification. Feedback was provided to improve the document's maintainability and reusability by replacing hardcoded values—specifically the number of crates and the version string—with generic placeholders or descriptive phrases.
| - Trusted Publishing (preferred): the GitHub Actions OIDC path is configured for this repo on crates.io. Verify the trusted-publishing configuration for each of the 12 crates if they've been pre-registered. | ||
| - Token fallback: `CARGO_REGISTRY_TOKEN` repo secret is set with publish scope for all 12 crates. |
There was a problem hiding this comment.
To improve the long-term maintainability of this runbook, consider avoiding the hardcoded number of crates (12). This number could change as the workspace evolves. A more generic phrase like "all crates in the release plan" would be more resilient to such changes. This also applies to line 78.
| - Trusted Publishing (preferred): the GitHub Actions OIDC path is configured for this repo on crates.io. Verify the trusted-publishing configuration for each of the 12 crates if they've been pre-registered. | |
| - Token fallback: `CARGO_REGISTRY_TOKEN` repo secret is set with publish scope for all 12 crates. | |
| - Trusted Publishing (preferred): the GitHub Actions OIDC path is configured for this repo on crates.io. Verify the trusted-publishing configuration for each of the crates in the release plan if they've been pre-registered. | |
| - Token fallback: `CARGO_REGISTRY_TOKEN` repo secret is set with publish scope for all crates in the release plan. |
| git tag -a v0.3.0-rc.1 -m "v0.3.0-rc.1 — first public crates.io wave" | ||
| git push origin v0.3.0-rc.1 |
There was a problem hiding this comment.
This runbook is very helpful, but it's tightly coupled to the v0.3.0-rc.1 release. To make it reusable for future releases, consider replacing the hardcoded version with a placeholder like <version>. You could add a note at the top for the operator to set this value.
This change would apply to several places in the document, such as lines 6, 48, 83, 95-99, and 102.
| git tag -a v0.3.0-rc.1 -m "v0.3.0-rc.1 — first public crates.io wave" | |
| git push origin v0.3.0-rc.1 | |
| git tag -a <version> -m "<version> — first public crates.io wave" | |
| git push origin <version> |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a5124d7605
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | `Permanent` error (auth, version conflict, manifest) | **Stop.** Fix the cause, bump version, re-tag. Do NOT retry a permanent error. | | ||
| | `Retryable` error (429, transient network) | Let the engine retry — `--max-attempts 12`, `--max-delay 15m` is configured to ride out rate-limit windows. | | ||
| | `Ambiguous` error (upload may have succeeded) | **Pause.** Query the sparse index and API directly for `<crate>@0.3.0-rc.1`. Only resume after out-of-band confirmation; see Resume below. | | ||
| | Runner dies / 180-min timeout | `.shipper/` artifact is still uploaded. Use Resume below. | |
There was a problem hiding this comment.
Do not route timeout recovery to resume unconditionally
This guidance can send operators into a dead end after a mid-train timeout: in .github/workflows/release.yml, release-resume downloads only shipper-state-final, but that artifact is uploaded in the last step of publish-crates-io (after publish/verification). If the runner dies or the job times out before that step, only earlier artifacts exist, so “Use Resume below” will fail to recover state despite the table implying it always works.
Useful? React with 👍 / 👎.
| cargo yank --vers 0.3.0-rc.1 shipper-config shipper-registry | ||
| cargo yank --vers 0.3.0-rc.1 shipper-types | ||
| cargo yank --vers 0.3.0-rc.1 shipper-cargo-failure shipper-duration shipper-encrypt shipper-output-sanitizer shipper-retry shipper-sparse-index shipper-webhook |
There was a problem hiding this comment.
These rollback commands pass multiple crate names to a single cargo yank invocation, which aborts the containment procedure at exactly the point it is needed most. cargo yank --help documents Usage: cargo yank [OPTIONS] [CRATE] (single crate argument), so each crate must be yanked in its own command to avoid a CLI parse error during incident response.
Useful? React with 👍 / 👎.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Summary
Adds `docs/release-runbook.md` — a one-page operator crib sheet for cutting a crates.io release train via Shipper.
Relationship to existing docs
`docs/release-v0.3.0-rc.1-manifest.md` is already a comprehensive release reference (topo order, rate-limit plan, workflow contract, `.shipper/` state persistence rules, resume discipline). This new runbook complements that — it's what an operator actually types and reads during the train:
Total: ~100 lines. No code, manifest, workflow, or `Cargo.*` changes. Doc-only.
Scope / status
Deferred. Current `main` is the release-candidate baseline for the first crates.io publish wave. Per the closeout plan, no mainline changes (including this doc) land before that wave completes. This PR stays draft until post-release, same queue policy as #87.
The doc is in the right state to use during Wave 1 even without being merged: an operator can pull from this branch's tip or read it directly on the PR.
Test plan