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
+9 -9
View File
@@ -1,7 +1,7 @@
//! I/O integration tests for the auto-update crate.
//!
//! These tests touch global process state — `KIGI_SHARE_DIR` (a `OnceLock` in
//! `kigi-config`), `KIGI_TEST_VERSION`, and `NPM_TOKEN` — so they
//! `kigi-config`), `KIGI_TEST_VERSION` — so they
//! must run serially. Once `KIGI_SHARE_DIR` is initialized for a process, it can't
//! be changed; we set it from a single shared `OnceLock` and reset the
//! contents of the directory between tests.
@@ -277,13 +277,13 @@ async fn write_version_cache_idempotent_for_same_version() {
}
// ─────────────────────────────────────────────────────────────────────────────
// get_installed_grok_version env override
// get_installed_kigi_version env override
//
// The function honors `KIGI_TEST_VERSION` for testing. We exercise it
// via the public re-export only — no private items leaked.
// ─────────────────────────────────────────────────────────────────────────────
//
// Note: `get_installed_grok_version` is not re-exported from `lib.rs`, but
// Note: `get_installed_kigi_version` is not re-exported from `lib.rs`, but
// it's `pub` from `version` module and accessible via `version::`.
#[tokio::test]
@@ -295,7 +295,7 @@ async fn get_installed_version_uses_env_var_override() {
unsafe {
std::env::set_var("KIGI_TEST_VERSION", "9.9.9");
}
let v = kigi_update::version::get_installed_grok_version();
let v = kigi_update::version::get_installed_kigi_version();
assert_eq!(v, "9.9.9");
unsafe {
std::env::remove_var("KIGI_TEST_VERSION");
@@ -311,7 +311,7 @@ async fn get_installed_version_falls_back_to_cargo_pkg_version_when_env_unset()
unsafe {
std::env::remove_var("KIGI_TEST_VERSION");
}
let v = kigi_update::version::get_installed_grok_version();
let v = kigi_update::version::get_installed_kigi_version();
// The compile-time CARGO_PKG_VERSION must be a parseable semver string.
let _: semver::Version = v
.parse()
@@ -328,13 +328,13 @@ async fn get_installed_version_with_env_var_takes_precedence() {
unsafe {
std::env::remove_var("KIGI_TEST_VERSION");
}
kigi_update::version::get_installed_grok_version()
kigi_update::version::get_installed_kigi_version()
};
unsafe {
std::env::set_var("KIGI_TEST_VERSION", "0.0.0-test");
}
let overridden = kigi_update::version::get_installed_grok_version();
let overridden = kigi_update::version::get_installed_kigi_version();
assert_ne!(real, overridden);
assert_eq!(overridden, "0.0.0-test");
@@ -352,7 +352,7 @@ async fn get_installed_version_handles_alpha_prerelease_in_env() {
unsafe {
std::env::set_var("KIGI_TEST_VERSION", "0.1.200-alpha.5");
}
let v = kigi_update::version::get_installed_grok_version();
let v = kigi_update::version::get_installed_kigi_version();
assert_eq!(v, "0.1.200-alpha.5");
unsafe {
std::env::remove_var("KIGI_TEST_VERSION");
@@ -370,7 +370,7 @@ async fn get_installed_version_does_not_validate_env_var_format() {
unsafe {
std::env::set_var("KIGI_TEST_VERSION", "not-a-version");
}
let v = kigi_update::version::get_installed_grok_version();
let v = kigi_update::version::get_installed_kigi_version();
assert_eq!(v, "not-a-version");
unsafe {
std::env::remove_var("KIGI_TEST_VERSION");