16 lines
5.0 KiB
Markdown
16 lines
5.0 KiB
Markdown
# Tooling: one canonical install bundle per target, for online and offline alike
|
|
|
|
Each Release now attaches exactly one artifact per target: `penguin-{linux,darwin}-{x64,arm64}.tar.gz`, `penguin-universal.tar.gz` and `penguin-win32-x64.zip` are flat installer bundles, each sealing the native installer, the program payload (`payload.tar.gz` / `payload.zip`) and the payload's SHA256 checksum. Raw program archives and the five `*-offline` wrappers introduced in 0.1.5 are no longer published; `SHA256SUMS` covers exactly the six bundles.
|
|
|
|
Both installation modes consume the same file. Online, `install.sh` / `install.ps1` download the bundle, verify it against its published `.sha256` — checksums are now always mandatory; the online warn-and-skip fallback is gone — then open the flat outer layer and verify the payload checksum sealed inside before staging. Offline, the user transfers that one file, extracts it once and runs the bundled `./install.sh` (or double-clicks `install.cmd`); the installer finds the sibling payload by itself and verifies the same sealed checksum with no network access, so no separate checksum file needs to be carried.
|
|
|
|
Archive shape is probed by content, not filename: a top-level `payload.*` means bundle, anything else is treated as a program archive with a top-level `penguin/`. That single probe replaces the previous online/offline split and keeps pinned pre-0.1.6 versions and legacy local archives installable (see the batch's [backward-compatibility notes](2026-07-31-backward-compatibility.md)). On Windows, the flat outer layer means the initial extraction never creates deep paths — PowerShell 5.1's 260-character limit stops being reachable from the download directory — and the zip shape probe reads the entry list without extracting; only the installer expands the payload, straight into its short staging directory.
|
|
|
|
The canonical installers travel byte-identical inside the bundles — the generated POSIX wrapper entry (`penguin-installer.sh` + stub `install.sh`) is gone, replaced by sibling-payload detection in the one real installer. That detection is hardened to keep 0.1.5's "never trust archives beside a temporary script" property: it engages only for a real file actually named `install.sh`, and the penguin.ooo forwarder now stages its download in a private `mktemp -d` directory rather than a bare file in shared `/tmp`. The Windows forwarder already runs the installer as an in-memory script block and keeps its sibling detection offline-only.
|
|
|
|
In-place upgrades stop failing on filesystems that pin in-use directories. `penguin update` re-runs the installer while the CLI process is still executing out of `lib/`; on overlayfs under Docker the plain `mv lib .old.<pid>/lib` failed with `Device or resource busy` and rolled back. Directory moves now degrade through three strategies — whole-directory rename, per-entry renames into a fresh or existing destination, then per-entry copy with the source cleared (POSIX keeps an unlinked-but-open file valid for the process using it) — with a pinned, empty directory husk reused by the incoming move, rollback following the same rules, and a failure message that says to stop running penguin processes. A hermetic test stubs `mv`/`rmdir` to refuse directory renames touching the installed `lib/` and verifies the upgrade completes cleanly.
|
|
|
|
Two Windows papercuts are fixed at the root. The payload no longer ships a `penguin.ps1` launcher: PowerShell prefers `.ps1` over `.cmd` on PATH and client Windows defaults to the Restricted execution policy, so a fresh install's plain `penguin` command failed with "running scripts is disabled"; batch files are policy-exempt, both PowerShell and cmd.exe resolve `penguin.cmd`, and since upgrades swap `bin\` wholesale, re-running the installer also removes the old shim (see the batch's [backward-compatibility notes](2026-07-31-backward-compatibility.md)). And after appending to the user Path registry value, the installer now broadcasts `WM_SETTINGCHANGE` — a raw registry write alone left Explorer, and every terminal launched from it, on the stale Path until the next logon, which is why a brand-new PowerShell window still could not find `penguin`; the completion note now says to open a new terminal window rather than a new tab.
|
|
|
|
`scripts/package-release-bundles.sh` replaces `package-offline-bundles.sh`, and the release workflow now builds payloads as intermediates, packages the six bundles, and validates the real outputs before upload: outer checksum, exact flat member set, byte-identical installer and payload, and a passing sealed checksum. `scripts/test-installer.sh` and `scripts/test-installer.ps1` replace the offline-only test scripts and hermetically cover bundle layout, offline installs with network access stubbed to fail, corrupted-payload rejection, upgrade rollback, both checksum layers, no-fallback download failures and pinned legacy versions, wired into the existing Linux and Windows CI jobs. README, the docs Installation page and the landing install copy describe the single-artifact flow.
|