mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-08 17:10:50 -10:00
fix(release): give each crate package rerun its own root and keep the token out of it
Follow-up to8b92463a2c, fixing three review findings on that commit (the fourth, its Refs line, was already corrected to CW-7445). Unique rerun root. The refusal and the runbook named the rerun root release-verify-<sha10> only. The documented flow runs a receipt dry run, then publish, then possibly partial-publish reruns, all at the same frozen SHA, so the printed mkdir failed with "File exists" on the very next use: /Volumes/VIXinSSD/cw-build-cache/release-verify-14683c9983 already exists from the 0.10.2 receipt, and14683c9983is the tag source. The root is now release-verify-<sha10>-<mode>-<UTC %Y%m%dT%H%M%SZ> in publish-crates.sh and in both runbook blocks. The refusal and the runbook say that publish and each partial-publish rerun get their own root. Credentials. The runbook and refusal told the operator to run cargo login into the per-run CARGO_HOME. That leaves a plaintext token in <cache root>/release-verify-*/cargo-home/credentials.toml after every publish, in a tree agents list and prune. Both now pass the token as CARGO_REGISTRY_TOKEN for the one publish command. Cargo's config reference names it as the crates.io token, and crates-io is the default registry name the script's --registry flag uses. Cargo writes no file for it. After a cargo login there instead, run cargo logout with that CARGO_HOME. Step 5 of the Rust crates release is now the full isolated block (read -rs token, a new root, CARGO_REGISTRY_TOKEN, unset token). The workstation note (~:340), the crates.io gate's recovery step (~:602-603, which still said to run cargo login and then publish on the default home, which the guard refuses on this Mac) and the partial-publish bullet now use that block. docs/RELEASE_CHECKLIST.md section 6 also said to run plain publish-crates.sh publish. It now points at the block, so the two release docs agree. web/data/agent-docs.generated.json was regenerated with npm run prebuild because check:web flagged it as stale. Fallbacks and scope. The runbook block used ${CODEWHALE_CACHE_ROOT} with no default. When it was unset, the root became /release-verify-<sha> at the filesystem root. The block now sets cache and lock with the same fallbacks dev-cache.sh and the script use: ${XDG_CACHE_HOME:-$HOME/.cache}/codewhale and ${cache}/build.lock. The runbook and the refusal say that CODEWHALE_CACHE_ROOT and CODEWHALE_BUILD_LOCK_FILE take effect only when cargo on PATH is scripts/dev-cargo.sh or a wrapper that execs it, such as the strict dry-run wrapper the 0.10.2 receipt used. Plain Cargo ignores both and takes no machine lock. With plain Cargo, the runbook says to use CARGO_TARGET_DIR, plus scripts/build-lock.py when other builds may run. Verification (this Mac, HEAD8b92463a2cplus this diff): - Real state, through the no-build shim (exits 99 on cargo publish/package/build/check/...), then the strict wrapper, then dev-cargo.sh: dry-run exit 1 in about 4 s. It listed 28 extractions and 145 compiled units across 28 crates. It printed root release-verify-8b92463a2c-dry-run-20261016T154914Z. Publish mode also refused, printing release-verify-8b92463a2c-publish-20261016T154936Z, before the tag guard. The shim was never reached. The extraction listing, the deps entry count (181348) and the codewhale-state eb1a8b21e14a9d0b rlib did not change. The printed roots were not created. - Isolated: the runbook preflight block, extracted from the doc and run as written, with CODEWHALE_CACHE_ROOT and CODEWHALE_BUILD_LOCK_FILE unset, XDG_CACHE_HOME in scratch, CARGO_NET_OFFLINE=true and the shim. It ran once under bash and once under zsh. Both resolved the fallback cache. Each got its own root (...T155014Z and ...T155016Z), and mkdir succeeded both times. build.lock was created at the fallback ${cache}/build.lock, not inside the root. The guard passed, the script reached "Verifying all 29 release package tarballs" and the shim stopped cargo publish (exit 99). Each root holds only an empty build/. - bash -n and zsh -n pass on both runbook blocks. bash -n passes on the script. shellcheck shows only the 3 findings HEAD already has. - python3 scripts/release/publish-crates.test.py (under build-lock.py): "Ran 6 tests in 2.791s OK"; ~/.cargo/registry/src unchanged. - bash scripts/release/validate-crate-publish-order.test.sh: passed. node .github/scripts/release-workflows.test.js: exit 0. - cargo fmt --all -- --check (dev-cargo.sh): exit 0. No Rust changed, so there is no clippy or nextest target. - npm test: root 101/101, runtime-sdk 19/19, extension-host 420 (413 pass, 7 skipped), web node 7/7. npm run check:web: exit 0 after the prebuild regeneration, vitest 772/772 (74 files). Not verified: CARGO_REGISTRY_TOKEN with a real token (no token was used; the claim rests on Cargo's bundled config reference), the step 5 publish block end to end (it needs the tag, network and a token), cargo logout in a per-run CARGO_HOME, a full dry run in a new root (a cold build of about 19 GB) and GNU grep in CI/CNB. Not mirrored to GitHub. Not a CHANGELOG item (maintainer release tooling). Refs CW-7445 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NBKbhx19BRbZtvWK8rVKjz
This commit is contained in:
1 parent
8b92463a2c
commit
9ded7ce896
4 files changed
+71
-38
No files matched your search
@@ -212,11 +212,13 @@ known limitations and publication approval. These proofs are separate.
|
||||
switch release lanes or force-fetch a conflicting tag. If `main` advanced,
|
||||
coordinate with Hunter for a new candidate or separately authorized
|
||||
recovery plan.
|
||||
- [ ] Publish Cargo manually within the approved scope:
|
||||
`./scripts/release/publish-crates.sh publish`. It verifies every package,
|
||||
skips already-published versions and waits for each new dependency to
|
||||
appear. npm normally uses Trusted Publishing; manual recovery keeps the
|
||||
same clean-source and public-asset guards.
|
||||
- [ ] Publish Cargo manually within the approved scope with the
|
||||
[runbook's step 5 block](RELEASE_RUNBOOK.md#rust-crates-release), which
|
||||
runs `./scripts/release/publish-crates.sh publish` from a new, empty
|
||||
`CARGO_HOME` and cache root with the token in `CARGO_REGISTRY_TOKEN`. It
|
||||
verifies every package, skips already-published versions and waits for
|
||||
each new dependency to appear. npm normally uses Trusted Publishing;
|
||||
manual recovery keeps the same clean-source and public-asset guards.
|
||||
|
||||
## 7. Verify public results
|
||||
|
||||
|
||||
+58
-28
@@ -146,27 +146,39 @@ crate's `<crate>-<version>` directory under any `$CARGO_HOME/registry/src/*`
|
||||
other than crates.io's `index.crates.io-*`, or a dep-info file under the build
|
||||
directory's `*/deps/` that names such a directory. The refusal lists what it
|
||||
found and deletes nothing; removing shared cache directories still needs
|
||||
explicit cleanup approval. It prints, with the paths filled in, the rerun that
|
||||
produced the 0.10.2 receipt at 14683c9983 on 2026-10-16: a new, empty
|
||||
`CARGO_HOME` and `CODEWHALE_CACHE_ROOT`.
|
||||
explicit cleanup approval. It prints, with the paths filled in, the kind of
|
||||
rerun that produced the 0.10.2 receipt at 14683c9983 on 2026-10-16: a new,
|
||||
empty `CARGO_HOME` and `CODEWHALE_CACHE_ROOT`.
|
||||
|
||||
```bash
|
||||
lock="${CODEWHALE_CACHE_ROOT}/build.lock"
|
||||
root="${CODEWHALE_CACHE_ROOT}/release-verify-$(git rev-parse --short=10 HEAD)"
|
||||
mode=dry-run
|
||||
cache="${CODEWHALE_CACHE_ROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/codewhale}"
|
||||
lock="${CODEWHALE_BUILD_LOCK_FILE:-${cache}/build.lock}"
|
||||
root="${cache}/release-verify-$(git rev-parse --short=10 HEAD)-${mode}-$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
mkdir "${root}"
|
||||
CODEWHALE_BUILD_LOCK_FILE="${lock}" CARGO_HOME="${root}/cargo-home" \
|
||||
CODEWHALE_CACHE_ROOT="${root}" ./scripts/release/publish-crates.sh dry-run
|
||||
CODEWHALE_CACHE_ROOT="${root}" ./scripts/release/publish-crates.sh "${mode}"
|
||||
```
|
||||
|
||||
That run was a cold build of about 19 GB and 962 compile steps, so check
|
||||
`df -h` first. It kept its lock file inside the new root and did not serialize
|
||||
with other builds on the machine; `CODEWHALE_BUILD_LOCK_FILE` keeps the machine
|
||||
lock. `CODEWHALE_CACHE_ROOT` moves the build directory only when `cargo` runs
|
||||
through `scripts/dev-cargo.sh`; with plain Cargo, set
|
||||
`CARGO_TARGET_DIR="${root}/target"` instead. Every run leaves state that the
|
||||
next run at the same version refuses, so publish mode needs another new root,
|
||||
with `cargo login` run for that `CARGO_HOME` (the token lives there). The CNB
|
||||
`work/v*` release preflight in `.cnb.yml` calls this script in a fresh
|
||||
`df -h` first. `cache` and `lock` use the same fallbacks as
|
||||
`scripts/dev-cache.sh`. `CODEWHALE_CACHE_ROOT` and `CODEWHALE_BUILD_LOCK_FILE`
|
||||
take effect only when `cargo` on `PATH` is `scripts/dev-cargo.sh` or a wrapper
|
||||
that execs it, such as the strict dry-run wrapper used for the 0.10.2 receipt.
|
||||
That run kept its lock file inside the new root and did not serialize with
|
||||
other builds on the machine; `CODEWHALE_BUILD_LOCK_FILE` keeps the machine
|
||||
lock. Plain Cargo ignores both variables and takes no machine lock: set
|
||||
`CARGO_TARGET_DIR="${root}/target"` in place of `CODEWHALE_CACHE_ROOT`, and
|
||||
wrap the command in `python3 scripts/build-lock.py "${lock}" --` if other
|
||||
builds may run. Every run leaves state that the next run at the same version
|
||||
refuses, so the root name carries the SHA, the mode and a UTC timestamp:
|
||||
publish mode (step 5 of the Rust crates release) and each partial-publish
|
||||
rerun get their own root. Pass the crates.io token to publish mode as
|
||||
`CARGO_REGISTRY_TOKEN` for that one command, as step 5 shows; Cargo then
|
||||
writes no `credentials.toml` under the root. If you run `cargo login` with
|
||||
that `CARGO_HOME` instead, run `CARGO_HOME="${root}/cargo-home" cargo logout`
|
||||
once the publish finishes, so no plaintext token copy stays in the cache tree.
|
||||
The CNB `work/v*` release preflight in `.cnb.yml` calls this script in a fresh
|
||||
container, where the check finds nothing. Known limits: the check also refuses
|
||||
compiled units recorded against a different `CARGO_HOME`, which Cargo would
|
||||
rebuild rather than reuse, and it does not scan `<target-triple>/`
|
||||
@@ -337,8 +349,8 @@ handoff. Keep backups as recovery artifacts, not alternate development lanes.
|
||||
|
||||
Crate publishing to crates.io is **manual** — there is no automated
|
||||
`crates-publish` GitHub workflow. Operators run the helpers in
|
||||
`scripts/release/` from a developer workstation that has `cargo login`
|
||||
configured.
|
||||
`scripts/release/` from a developer workstation, passing a crates.io publish
|
||||
token to the publish command as `CARGO_REGISTRY_TOKEN` (step 5).
|
||||
|
||||
Release preparation lands directly on canonical `main` in verified slices;
|
||||
contributor PRs retain their normal review/merge process. The source must be on
|
||||
@@ -386,7 +398,16 @@ and fails branch-only release sources before assets are published.
|
||||
|
||||
```bash
|
||||
./scripts/release/require-release-tag-checkout.sh X.Y.Z
|
||||
./scripts/release/publish-crates.sh publish
|
||||
mode=publish
|
||||
cache="${CODEWHALE_CACHE_ROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/codewhale}"
|
||||
lock="${CODEWHALE_BUILD_LOCK_FILE:-${cache}/build.lock}"
|
||||
root="${cache}/release-verify-$(git rev-parse --short=10 HEAD)-${mode}-$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
mkdir "${root}"
|
||||
read -rs token
|
||||
CARGO_REGISTRY_TOKEN="${token}" CODEWHALE_BUILD_LOCK_FILE="${lock}" \
|
||||
CARGO_HOME="${root}/cargo-home" CODEWHALE_CACHE_ROOT="${root}" \
|
||||
./scripts/release/publish-crates.sh "${mode}"
|
||||
unset token
|
||||
```
|
||||
|
||||
Both Cargo and npm publication fail closed unless `HEAD`, the clean local
|
||||
@@ -394,9 +415,13 @@ and fails branch-only release sources before assets are published.
|
||||
dependency order lives in `scripts/release/crates.sh`; do not maintain a
|
||||
second handwritten order in this runbook. The helper waits for each new
|
||||
version to appear on crates.io before moving to dependents and safely skips
|
||||
versions that are already public on a rerun. Run it from a new, empty
|
||||
`CARGO_HOME` and cache root, as the package preflight above describes; the
|
||||
dry run's state makes it refuse otherwise.
|
||||
versions that are already public on a rerun. The block runs it from a new,
|
||||
empty `CARGO_HOME` and cache root of its own, as the package preflight
|
||||
above describes; the dry run's state makes it refuse otherwise. `read -rs`
|
||||
keeps the token out of shell history, and the environment variable keeps
|
||||
it out of `credentials.toml`. The cache and lock variables take effect only
|
||||
through `scripts/dev-cargo.sh` or a wrapper that execs it; see the package
|
||||
preflight for plain Cargo.
|
||||
If shared `main` advances or the checkout becomes dirty, stop and coordinate
|
||||
a new candidate or separately authorized recovery with Hunter. Do not switch
|
||||
branches, create another checkout, force-fetch a conflicting tag or bypass
|
||||
@@ -586,8 +611,9 @@ for that version — bump to the next patch instead.
|
||||
|
||||
### External publish gates (not code defects)
|
||||
|
||||
- **crates.io:** publishing needs a valid `cargo login` token on the operator
|
||||
machine. Verify it with an authenticated, read-only *client* call rather
|
||||
- **crates.io:** publishing needs a valid crates.io publish token, passed to
|
||||
the publish command as `CARGO_REGISTRY_TOKEN` (Rust crates release, step 5).
|
||||
Verify it with an authenticated, read-only *client* call rather
|
||||
than the `/api/v1/me` endpoint: crates.io answers `/api/v1/me` with
|
||||
`403 {"errors":[{"detail":"this action can only be performed on the
|
||||
crates.io website"}]}` even for a good token (checked 2026-09-21 with a
|
||||
@@ -595,12 +621,16 @@ for that version — bump to the next patch instead.
|
||||
credential.
|
||||
|
||||
```bash
|
||||
cargo owner --list codewhale-tui # prints the owner, e.g. `Hmbown (Hunter Bown)`
|
||||
read -rs token
|
||||
CARGO_REGISTRY_TOKEN="${token}" cargo owner --list codewhale-tui # prints the owner, e.g. `Hmbown (Hunter Bown)`
|
||||
unset token
|
||||
```
|
||||
|
||||
A 403 or `401` from this call, or `cargo publish` refusing credentials,
|
||||
means the token is missing/expired — `cargo login`, then
|
||||
`./scripts/release/publish-crates.sh publish`.
|
||||
means the token is missing/expired. Create a new token, check it with this
|
||||
call, then rerun the step 5 block. It makes another new `CARGO_HOME` and
|
||||
cache root, which the rerun needs because the failed run's own state makes
|
||||
the guard refuse otherwise, and it keeps the token out of that root.
|
||||
- **npm:** the OIDC job publishes only if the npmjs.com Trusted Publisher for
|
||||
`codewhale-hq` / `Codewhale` / workflow `release.yml` / blank environment is
|
||||
configured. Missing config → the `npm` job fails `E404 No match found`. Fix
|
||||
@@ -621,9 +651,9 @@ for that version — bump to the next patch instead.
|
||||
- keep [docs/INSTALL.md](INSTALL.md#roll-back-to-a-previous-release) in sync
|
||||
with these commands
|
||||
- Crates publish partially:
|
||||
- rerun `./scripts/release/publish-crates.sh publish` from another new,
|
||||
empty `CARGO_HOME` and cache root (see the package preflight); the failed
|
||||
run's own state makes it refuse otherwise
|
||||
- rerun the Rust crates release step 5 block; its timestamped root gives
|
||||
each rerun another new, empty `CARGO_HOME` and cache root, and the failed
|
||||
run's own state makes `publish-crates.sh publish` refuse otherwise
|
||||
- already-published crate versions will be skipped
|
||||
- GitHub assets missing or checksum manifest incomplete:
|
||||
- fix `.github/workflows/release.yml`, but do not rerun it over an existing
|
||||
|
||||
@@ -85,15 +85,16 @@ if [[ -d "${deps_dirs[0]}" ]]; then
|
||||
fi
|
||||
if (( ${#reused[@]} > 0 )); then
|
||||
cache_root="${CODEWHALE_CACHE_ROOT:-${XDG_CACHE_HOME:-${HOME}/.cache}/codewhale}"
|
||||
verify_root="${cache_root}/release-verify-$(git rev-parse --short=10 HEAD 2>/dev/null || echo candidate)"
|
||||
verify_root="${cache_root}/release-verify-$(git rev-parse --short=10 HEAD 2>/dev/null || echo candidate)-${mode}-$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
{
|
||||
echo "Refusing to package release crates: Cargo would reuse ${workspace_version} state from an earlier package run instead of the current sources:"
|
||||
printf ' %s\n' "${reused[@]}"
|
||||
echo "Cargo treats crates served from its temporary package registry as immutable by name and version. It skips extraction once .cargo-ok exists and keeps compiled units that do not track their sources, so this run would verify old code. Nothing was deleted."
|
||||
echo "Rerun from a new, empty Cargo home and cache root:"
|
||||
echo "Rerun from a new, empty Cargo home and cache root. Every run leaves state the next run at this version refuses, so publish and each partial-publish rerun need their own root:"
|
||||
echo " mkdir \"${verify_root}\""
|
||||
echo " CODEWHALE_BUILD_LOCK_FILE=\"${CODEWHALE_BUILD_LOCK_FILE:-${cache_root}/build.lock}\" CARGO_HOME=\"${verify_root}/cargo-home\" CODEWHALE_CACHE_ROOT=\"${verify_root}\" $0 ${mode}"
|
||||
echo "If cargo is not scripts/dev-cargo.sh, set CARGO_TARGET_DIR=\"${verify_root}/target\" in place of CODEWHALE_CACHE_ROOT. Publish mode also needs cargo login with that CARGO_HOME. See docs/RELEASE_RUNBOOK.md."
|
||||
echo "CODEWHALE_CACHE_ROOT and CODEWHALE_BUILD_LOCK_FILE take effect only when cargo on PATH is scripts/dev-cargo.sh or a wrapper that execs it. Plain cargo ignores both and takes no machine build lock; with it, set CARGO_TARGET_DIR=\"${verify_root}/target\" in place of CODEWHALE_CACHE_ROOT."
|
||||
echo "For publish mode, pass the crates.io token as CARGO_REGISTRY_TOKEN for that one command, so Cargo writes no credentials.toml under the new root. After cargo login with that CARGO_HOME instead, run cargo logout with it once the publish finishes. See docs/RELEASE_RUNBOOK.md."
|
||||
} >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -357,8 +357,8 @@
|
||||
},
|
||||
{
|
||||
"path": "docs/RELEASE_CHECKLIST.md",
|
||||
"sha256": "48264ce4cbd3429546ee8ad9dbd28df565a8d3ab814d5a2c77d6450f96b82d2c",
|
||||
"content": "# Release Checklist\n\nFollow this sequence from the canonical `/Volumes/VIXinSSD/CW/codewhale`\ncheckout on `main`. Agent-owned preparation lands as verified slices on `main`;\nit requires no release branch, worktree, nested clone or preparation PR.\nContributor PRs still land as PRs. Treat any unchecked required gate as a release\nblocker.\n\nFor deeper context on the underlying tools (preflight scripts, npm smoke,\npublish-crates), see [`RELEASE_RUNBOOK.md`](RELEASE_RUNBOOK.md).\nFor larger milestone releases, add any version-specific acceptance matrix to\nthe existing release packet before tagging; use it for provider routes, feature\ngates, GUI/runtime smoke, remote-workbench decisions, and credit hygiene that the\ngeneric checklist does not enumerate. Record its candidate SHA, owners, local\ncheck results, hosted run URLs, artifact inventory, install/provider receipts,\nknown limitations and publication approval. These proofs are separate.\n\n## 0. Reconcile the canonical checkout\n\n- [ ] Inspect the branch, status, upstream and alternate checkouts before editing:\n ```bash\n git branch --show-current\n git status --short --branch\n git log -5 --oneline\n git worktree list\n git fetch origin main\n git log --left-right --oneline main...origin/main\n ```\n- [ ] The canonical checkout is on `main`. Recover stranded work only after\n preserving dirty/untracked files and comparing commits with current\n `origin/main`. Keep a recoverable backup and unresolved inventory; do not\n reset away work, stash it indefinitely or create another development lane.\n- [ ] Partition files among active writers. Check status before staging and\n stage only owned paths. Historical branches/checkouts are inventoried;\n deleting them requires explicit Hunter approval even if a helper calls\n their tips safe to delete.\n\n## 1. CHANGELOG entry exists for the version\n\n- [ ] `CHANGELOG.md` has a `## [X.Y.Z] - YYYY-MM-DD` heading at the top\n- [ ] The entry credits every external contributor, harvested PR author,\n linked issue reporter, reproduction/log provider, reviewer, and\n verification helper whose work materially shaped this version. Get the\n commit list with:\n ```\n git log vPREV..HEAD --no-merges --format=\"%h %an <%ae> %s\" \\\n | grep -v '<your-email@…>'\n ```\n For each contributor, link both their display name and (when known)\n `@github-handle`. Then inspect linked issues and harvested PRs so\n reporters/helpers are not lost just because they did not author commits.\n Keep `docs/CONTRIBUTORS.md` and `web/lib/release-credits.ts` consistent.\n- [ ] The entry uses the Keep a Changelog headers — `Added`, `Changed`,\n `Fixed`, `Security`, `Removed`, `Deprecated`. Add `Known issues` only\n if there is something material the user must work around.\n- [ ] The entry mentions all referenced issue/PR numbers as `#NNNN` so the\n auto-linker on GitHub picks them up.\n- [ ] Run `scripts/sync-changelog.sh` to regenerate `crates/tui/CHANGELOG.md`\n (the recent-releases slice embedded in the binary for `/change`). Do\n not edit that file by hand, and do not copy the full root changelog\n into it — older entries live in `docs/CHANGELOG_ARCHIVE.md`.\n- [ ] Run `scripts/release/check-feature-release-notes.sh vPREV HEAD`. Every\n issue-linked `feat` commit must leave a receipt in `CHANGELOG.md` or the\n archive; the Version drift CI gate runs the same check with full history.\n\n## 2. Version pins are in sync\n\n- [ ] Use `./scripts/release/prepare-release.sh X.Y.Z` when version pins or\n generated sources need preparation. Reuse a valid preparation receipt\n when those sources are already current. The helper bumps the\n workspace version, every per-crate dependency pin, the npm wrapper\n (`version` + `codewhaleBinaryVersion`), Runtime SDK, VS Code extension\n and lock, remote-smoke default, public source-candidate facts, and README\n install-tag examples; it refreshes the Cargo/npm locks, regenerates\n `crates/tui/CHANGELOG.md` and `web/lib/facts.generated.ts`, and ends\n by running the version and OHOS gates. Write the CHANGELOG entry\n **before** running it. The helper is safe to rerun at the requested\n workspace version; it skips replacements but refreshes both generated\n files and reruns the gates.\n- [ ] `npm/deepseek-tui/package.json` remains private/compatibility-only and\n is **not** bumped or published.\n- [ ] `./scripts/release/check-versions.sh` reports\n `Version state OK: workspace=X.Y.Z, npm=X.Y.Z, npm-binary=X.Y.Z, lockfile in sync.`\n- [ ] `./scripts/release/check-ohos-deps.sh` reports that the OpenHarmony\n Windows linker keeps the target/sysroot flags, the target enables the\n `rquickjs-sys` bindgen edge, and its graph does not pull the unsupporLine truncated
|
||||
"sha256": "4a0cab2b895cdc01067f0663b1f77c4993d090b3daa29b9eb29557fdfb9eb88d",
|
||||
"content": "# Release Checklist\n\nFollow this sequence from the canonical `/Volumes/VIXinSSD/CW/codewhale`\ncheckout on `main`. Agent-owned preparation lands as verified slices on `main`;\nit requires no release branch, worktree, nested clone or preparation PR.\nContributor PRs still land as PRs. Treat any unchecked required gate as a release\nblocker.\n\nFor deeper context on the underlying tools (preflight scripts, npm smoke,\npublish-crates), see [`RELEASE_RUNBOOK.md`](RELEASE_RUNBOOK.md).\nFor larger milestone releases, add any version-specific acceptance matrix to\nthe existing release packet before tagging; use it for provider routes, feature\ngates, GUI/runtime smoke, remote-workbench decisions, and credit hygiene that the\ngeneric checklist does not enumerate. Record its candidate SHA, owners, local\ncheck results, hosted run URLs, artifact inventory, install/provider receipts,\nknown limitations and publication approval. These proofs are separate.\n\n## 0. Reconcile the canonical checkout\n\n- [ ] Inspect the branch, status, upstream and alternate checkouts before editing:\n ```bash\n git branch --show-current\n git status --short --branch\n git log -5 --oneline\n git worktree list\n git fetch origin main\n git log --left-right --oneline main...origin/main\n ```\n- [ ] The canonical checkout is on `main`. Recover stranded work only after\n preserving dirty/untracked files and comparing commits with current\n `origin/main`. Keep a recoverable backup and unresolved inventory; do not\n reset away work, stash it indefinitely or create another development lane.\n- [ ] Partition files among active writers. Check status before staging and\n stage only owned paths. Historical branches/checkouts are inventoried;\n deleting them requires explicit Hunter approval even if a helper calls\n their tips safe to delete.\n\n## 1. CHANGELOG entry exists for the version\n\n- [ ] `CHANGELOG.md` has a `## [X.Y.Z] - YYYY-MM-DD` heading at the top\n- [ ] The entry credits every external contributor, harvested PR author,\n linked issue reporter, reproduction/log provider, reviewer, and\n verification helper whose work materially shaped this version. Get the\n commit list with:\n ```\n git log vPREV..HEAD --no-merges --format=\"%h %an <%ae> %s\" \\\n | grep -v '<your-email@…>'\n ```\n For each contributor, link both their display name and (when known)\n `@github-handle`. Then inspect linked issues and harvested PRs so\n reporters/helpers are not lost just because they did not author commits.\n Keep `docs/CONTRIBUTORS.md` and `web/lib/release-credits.ts` consistent.\n- [ ] The entry uses the Keep a Changelog headers — `Added`, `Changed`,\n `Fixed`, `Security`, `Removed`, `Deprecated`. Add `Known issues` only\n if there is something material the user must work around.\n- [ ] The entry mentions all referenced issue/PR numbers as `#NNNN` so the\n auto-linker on GitHub picks them up.\n- [ ] Run `scripts/sync-changelog.sh` to regenerate `crates/tui/CHANGELOG.md`\n (the recent-releases slice embedded in the binary for `/change`). Do\n not edit that file by hand, and do not copy the full root changelog\n into it — older entries live in `docs/CHANGELOG_ARCHIVE.md`.\n- [ ] Run `scripts/release/check-feature-release-notes.sh vPREV HEAD`. Every\n issue-linked `feat` commit must leave a receipt in `CHANGELOG.md` or the\n archive; the Version drift CI gate runs the same check with full history.\n\n## 2. Version pins are in sync\n\n- [ ] Use `./scripts/release/prepare-release.sh X.Y.Z` when version pins or\n generated sources need preparation. Reuse a valid preparation receipt\n when those sources are already current. The helper bumps the\n workspace version, every per-crate dependency pin, the npm wrapper\n (`version` + `codewhaleBinaryVersion`), Runtime SDK, VS Code extension\n and lock, remote-smoke default, public source-candidate facts, and README\n install-tag examples; it refreshes the Cargo/npm locks, regenerates\n `crates/tui/CHANGELOG.md` and `web/lib/facts.generated.ts`, and ends\n by running the version and OHOS gates. Write the CHANGELOG entry\n **before** running it. The helper is safe to rerun at the requested\n workspace version; it skips replacements but refreshes both generated\n files and reruns the gates.\n- [ ] `npm/deepseek-tui/package.json` remains private/compatibility-only and\n is **not** bumped or published.\n- [ ] `./scripts/release/check-versions.sh` reports\n `Version state OK: workspace=X.Y.Z, npm=X.Y.Z, npm-binary=X.Y.Z, lockfile in sync.`\n- [ ] `./scripts/release/check-ohos-deps.sh` reports that the OpenHarmony\n Windows linker keeps the target/sysroot flags, the target enables the\n `rquickjs-sys` bindgen edge, and its graph does not pull the unsupporLine truncated
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user