|
| 1 | +# Cutting a phenotype-journeys release |
| 2 | + |
| 3 | +Operator runbook for tagging `v0.1.0` (T1) and publishing Rust crates to |
| 4 | +crates.io (T2). Do **not** run these until `main` has the release-ready |
| 5 | +CHANGELOG section and local quality gates are green. |
| 6 | + |
| 7 | +T0 honesty still applies until T2 completes: end-user install remains |
| 8 | +**path/git only** — do not advertise `cargo install phenotype-journey` / |
| 9 | +`cargo add phenotype-journey-core` until crates.io publish succeeds. |
| 10 | + |
| 11 | +## Preconditions |
| 12 | + |
| 13 | +```bash |
| 14 | +cd /path/to/phenotype-journeys # worktree or canonical after merge |
| 15 | +git checkout main |
| 16 | +git pull --rebase origin main |
| 17 | +cargo test --locked |
| 18 | +cargo clippy --workspace --all-targets --locked -- -D warnings |
| 19 | +grep -A2 '## \[0.1.0\]' CHANGELOG.md # section must exist with a date |
| 20 | +``` |
| 21 | + |
| 22 | +Confirm root `Cargo.toml` `workspace.package.version = "0.1.0"` matches the |
| 23 | +CHANGELOG heading. |
| 24 | + |
| 25 | +## Publish order (crates.io) |
| 26 | + |
| 27 | +Publish in dependency order. Do **not** publish `klipdot-capture` in this |
| 28 | +release (`publish = false` — local KlipDot daemon, not part of the journey |
| 29 | +harness crates.io surface). |
| 30 | + |
| 31 | +| Order | Crate | Notes | |
| 32 | +|------:|-------|-------| |
| 33 | +| 1 | `phenotype-journey-core` | No workspace path deps | |
| 34 | +| 2 | `phenotype-journeys-observability` | No workspace path deps | |
| 35 | +| 3 | `phenotype-journey` | Depends on (1) and (2) via version+path | |
| 36 | + |
| 37 | +## T1 — git tag + GitHub Release (no crates.io yet) |
| 38 | + |
| 39 | +Exact commands (annotated tag preferred): |
| 40 | + |
| 41 | +```bash |
| 42 | +git tag -a v0.1.0 -m "phenotype-journeys v0.1.0" |
| 43 | +git push origin v0.1.0 |
| 44 | + |
| 45 | +gh release create v0.1.0 \ |
| 46 | + --title "v0.1.0" \ |
| 47 | + --notes-file <(sed -n '/## \[0.1.0\]/,/^## \[/p' CHANGELOG.md | sed '$d') |
| 48 | +``` |
| 49 | + |
| 50 | +Alternate notes from the tag: |
| 51 | + |
| 52 | +```bash |
| 53 | +gh release create v0.1.0 --title "v0.1.0" --notes-from-tag |
| 54 | +``` |
| 55 | + |
| 56 | +Publishing the GitHub Release triggers |
| 57 | +[`.github/workflows/release-attestation.yml`](../../.github/workflows/release-attestation.yml) |
| 58 | +(SLSA build attestation). GitHub Actions billing may block the run — treat |
| 59 | +attestation as best-effort; do not block crates.io publish on Actions green. |
| 60 | + |
| 61 | +Do **not** run `cargo publish` in T1. |
| 62 | + |
| 63 | +## T2 — crates.io publish |
| 64 | + |
| 65 | +After the tag exists on the release commit: |
| 66 | + |
| 67 | +```bash |
| 68 | +cargo login # once per machine / token |
| 69 | + |
| 70 | +# Pre-T2 local check (path deps): CLI builds without needing crates.io yet |
| 71 | +cargo build -p phenotype-journey --locked |
| 72 | + |
| 73 | +# 1) library (types + verify) |
| 74 | +cargo publish -p phenotype-journey-core --dry-run --locked |
| 75 | +cargo publish -p phenotype-journey-core --locked |
| 76 | + |
| 77 | +# 2) observability adapter |
| 78 | +cargo publish -p phenotype-journeys-observability --dry-run --locked |
| 79 | +cargo publish -p phenotype-journeys-observability --locked |
| 80 | + |
| 81 | +# 3) CLI — dry-run only works AFTER 1+2 are indexed on crates.io. |
| 82 | +# Before that, expect: "no matching package named `phenotype-journey-core`". |
| 83 | +# Wait a few seconds / retry if the index lags. |
| 84 | +cargo publish -p phenotype-journey --dry-run --locked |
| 85 | +cargo publish -p phenotype-journey --locked |
| 86 | +``` |
| 87 | + |
| 88 | +After a successful publish: |
| 89 | + |
| 90 | +1. Prefer `cargo install phenotype-journey --locked` / `cargo add phenotype-journey-core` in README Install. |
| 91 | +2. Update Work State: crates.io = published; keep git tag / Release as done. |
| 92 | +3. npm packages remain on the separate GitHub Packages path (`npm/PUBLISHING.md`). |
| 93 | + |
| 94 | +## Rollback / mistakes |
| 95 | + |
| 96 | +- Wrong tag before push: `git tag -d v0.1.0` (local only). |
| 97 | +- Wrong tag already pushed: do **not** force-delete without explicit operator |
| 98 | + approval; prefer a patch tag (`v0.1.1`) and a forward CHANGELOG entry. |
| 99 | +- Never `cargo publish` a version that does not match the git tag / CHANGELOG. |
| 100 | +- crates.io versions are immutable — yank only for severe breakage, then ship |
| 101 | + a patch. |
| 102 | + |
| 103 | +## Related |
| 104 | + |
| 105 | +- [CHANGELOG.md](../../CHANGELOG.md) |
| 106 | +- [docs/slsa.md](../slsa.md) — attestation / provenance |
| 107 | +- [README.md](../../README.md) — install honesty until crates.io lands |
| 108 | +- [npm/PUBLISHING.md](../../npm/PUBLISHING.md) — npm / GitHub Packages |
0 commit comments