F8: distribution and GitHub-Releases self-update

- .github/workflows/release.yml: on tag v* build all 5 targets (macOS
  arm64/x86_64, Linux arm64/x86_64 incl. free arm runners, Windows
  x86_64) with the release-dist profile, archive kigi-<version>-<triple>
  with LICENSE/NOTICE/THIRD-PARTY-NOTICES, generate SHA256SUMS, publish
  the release (prerelease for tags containing '-'), with a tag↔workspace
  version guard.
- install.sh / install.ps1 (repo root): platform detection, latest or
  --version download from GitHub Releases, SHA-256 verification against
  SHA256SUMS, install into the kigi home's downloads/ + bin/kigi symlink
  (the same layout the self-updater manages), smoke test, PATH guidance.
- kigi-update rewritten onto the GitHub Releases API (documented wire
  shape; stable=/latest, alpha=semver-max across the list, pinned=/tags):
  SHA-256 gate before any binary swap, tar.gz/zip extraction per
  platform, atomic bin/kigi symlink swap, channel/rollback semantics and
  the KIGI_AUTO_UPDATE gate preserved verbatim; every x.ai/GCS/npm
  endpoint deleted, npm/gh-release installers removed, legacy grok/agent
  links retired on install. kigi-env owns the update base URL with a
  KIGI_UPDATE_BASE_URL override (this is what the test artifact server
  injects).
- .cargo/config.toml: removed the non-portable neoverse-v2 CPU pin on
  Linux arm64 (fleet-specific); RELRO/NX hardening link-args now apply
  to the gnu targets too, matching the release-dist profile's contract.
- THIRD-PARTY-NOTICES regenerated via cargo-about (about.toml +
  template); the M0 hand-built file is dropped and README points at the
  generated one. docs/RELEASE.md carries the release checklist.
- Deleted xAI-era leftovers: kigi-tui/scripts/install*.{sh,ps1} (x.ai
  CDN) and the @xai-official/grok npm skeleton (PRD F8: no npm).

Gates: fmt clean; workspace check/clippy 0/0 (--locked, -D warnings);
kigi-update 58 lib + 86 integration tests green; deny ok;
release-dist build of kigi-bin succeeds and reports 'kigi 0.1.0'.
This commit is contained in:
2026-07-18 00:54:53 -04:00
parent 5e4e24db99
commit 86e3724310
57 changed files with 27431 additions and 27787 deletions
+58
View File
@@ -0,0 +1,58 @@
# Release checklist (PRD F8)
Kigi ships as a single-file binary for five targets, published on this
repo's GitHub Releases by `.github/workflows/release.yml`. Users install via
`install.sh` / `install.ps1` and stay current through the in-app
self-updater (`kigi-update`), which resolves the same Releases API.
## Cutting a release
1. Bump `[workspace.package] version` in `Cargo.toml`; land the change on
`main` with green CI.
2. Regenerate the third-party notices (not enforced by CI — this is the
step that keeps `THIRD-PARTY-NOTICES.md` fresh):
```sh
cargo install cargo-about --locked # once
cargo about generate about.hbs -o THIRD-PARTY-NOTICES.md
```
Commit the result if it changed.
3. Tag and push:
```sh
git tag vX.Y.Z && git push origin vX.Y.Z
```
The tag must equal the workspace version (`vX.Y.Z` ↔ `X.Y.Z`); the
workflow fails fast on a mismatch.
4. The `Release` workflow builds all five targets with the hardened
`release-dist` profile, packages
`kigi-<version>-<target-triple>.{tar.gz|zip}` archives (binary +
LICENSE + NOTICE + THIRD-PARTY-NOTICES), generates `SHA256SUMS`, and
publishes the GitHub Release. Tags containing `-` (e.g.
`v0.2.0-alpha.1`) publish as pre-releases, which only the `alpha`
update channel picks up.
5. Smoke-test an installed artifact:
```sh
curl -fsSL https://raw.githubusercontent.com/ZacharyZhang-NY/Kigi-CLI/main/install.sh | sh
~/.kigi/bin/kigi --version
```
## Invariants to keep in lockstep
- Asset naming `kigi-<version>-<target-triple>.{tar.gz|zip}` and the
`SHA256SUMS` manifest are consumed by three clients: `install.sh`,
`install.ps1`, and `auto_update::release_asset_name()` in
`crates/codegen/kigi-update`. Change one, change all (the kigi-update
test `test_release_asset_name_matches_release_workflow_naming` pins the
Rust side).
- Never publish two builds of the same semver version differing only in
build metadata (`+…`) — the `semver` crate orders build metadata, so
auto-update would bounce users between them.
- Rollbacks: deleting the bad release (or re-pointing "latest") is enough —
the internal installer treats the Releases API as authoritative and
downgrades clients on its own.
- No PyPI/npm packages, ever; in particular never squat the `kimi-cli`
package name (PRD F8).