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
+14 -4
View File
@@ -29,6 +29,9 @@ pub const PRODUCTION_ENDPOINTS: KigiEndpoints = KigiEndpoints {
pub const CODE_BASE_URL_ENV: &str = "KIGI_CODE_BASE_URL";
/// Env var overriding [`oauth_host`] (PRD F1).
pub const OAUTH_HOST_ENV: &str = "KIGI_OAUTH_HOST";
/// Env var overriding [`update_base_url`] (PRD F8). Points the self-updater
/// at an alternate GitHub-Releases-shaped API (mirrors, tests).
pub const UPDATE_BASE_URL_ENV: &str = "KIGI_UPDATE_BASE_URL";
fn resolve(var: &str, compiled: &'static str) -> String {
match std::env::var(var) {
@@ -49,10 +52,11 @@ pub fn oauth_host() -> String {
resolve(OAUTH_HOST_ENV, PRODUCTION_ENDPOINTS.oauth_host)
}
/// GitHub Releases API endpoint for the self-updater. Compile-time constant;
/// the updater's channel/rollback semantics layer on top of it.
pub fn update_base_url() -> &'static str {
PRODUCTION_ENDPOINTS.update_base_url
/// GitHub Releases API endpoint for the self-updater:
/// `KIGI_UPDATE_BASE_URL` override when set, else the compiled production
/// endpoint. The updater's channel/rollback semantics layer on top of it.
pub fn update_base_url() -> String {
resolve(UPDATE_BASE_URL_ENV, PRODUCTION_ENDPOINTS.update_base_url)
}
/// Subscription upgrade page shown in rate-limit and upsell surfaces.
@@ -144,6 +148,12 @@ mod tests {
drop(_g);
let _g2 = EnvVarGuard::set(OAUTH_HOST_ENV, "https://auth.example.test");
assert_eq!(oauth_host(), "https://auth.example.test");
drop(_g2);
let _g3 = EnvVarGuard::set(UPDATE_BASE_URL_ENV, "http://127.0.0.1:1/releases");
assert_eq!(update_base_url(), "http://127.0.0.1:1/releases");
drop(_g3);
let _unset = EnvVarGuard::remove(UPDATE_BASE_URL_ENV);
assert_eq!(update_base_url(), PRODUCTION_ENDPOINTS.update_base_url);
}
#[test]