From cf8777daff0553757a6d371d83c490c509260848 Mon Sep 17 00:00:00 2001 From: Bartek Kus <7887446+bartekus@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:02:16 -0600 Subject: [PATCH] fix(007): quiet installer tag lookup; spec complete after live check - install.sh: buffer the GitHub API response before parsing; streaming into grep -m1 closed the pipe early and made curl print a spurious "(56) Failure writing output" line on the happy path - specs/007 status section records the v0.1.0 live check (15 assets, checksum + provenance verified in hard mode, installed binary reports 0.1.0) and flips implementation to complete --- .../by-spec/007-release-distribution.json | 2 +- .../by-spec/007-release-distribution.json | 7 +++-- install.sh | 7 ++++- specs/007-release-distribution/spec.md | 31 ++++++++++++++++++- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/.derived/codebase-index/by-spec/007-release-distribution.json b/.derived/codebase-index/by-spec/007-release-distribution.json index 04aef8c..255732b 100644 --- a/.derived/codebase-index/by-spec/007-release-distribution.json +++ b/.derived/codebase-index/by-spec/007-release-distribution.json @@ -45,5 +45,5 @@ "specStatus": "approved" }, "schemaVersion": "1.1.0", - "shardHash": "775d293277f36d26bd48854630315b34d9525eca17f5a4504b42528fc7d0deae" + "shardHash": "e91733cd067aa8ddbc3bdfb90442a31ca30bb600dea6a3caa1bd6663c077e3f2" } diff --git a/.derived/spec-registry/by-spec/007-release-distribution.json b/.derived/spec-registry/by-spec/007-release-distribution.json index de0bc90..9ccc666 100644 --- a/.derived/spec-registry/by-spec/007-release-distribution.json +++ b/.derived/spec-registry/by-spec/007-release-distribution.json @@ -15,7 +15,7 @@ } ], "id": "007-release-distribution", - "implementation": "in-progress", + "implementation": "complete", "sectionHeadings": [ "007: Release distribution", "1. Purpose", @@ -24,13 +24,14 @@ "4. Behavior: install.sh", "5. Release procedure", "6. Acceptance", - "7. Out of scope" + "7. Out of scope", + "8. Status (2026-07-22)" ], "specPath": "specs/007-release-distribution/spec.md", "status": "approved", "summary": "Closes the gap between \"builds from source\" and \"installable product\": pushing a v tag builds a per-triple archive for the five supported targets, attaches checksums, a CycloneDX SBOM, and a SLSA build-provenance attestation to a GitHub Release, and install.sh (curl | sh) consumes the archives. Mirrors the spec-spine release pipeline (the family precedent this repo's own CI already consumes) plus the fail-fast version guard OPC's release workflow learned the hard way. No registry publishing: the crate is a binary product, not a library.\n", "title": "Release distribution: tag-gated prebuilt binaries and installer" }, - "shardHash": "905bd5059b673e380bf011d965d61dbc18be5ec2821715c5aa110e76b6cbdda1", + "shardHash": "0fcb6689c4d1d550042bc6f9ac3c643a6311099bfa955e38bfe47cb5dcc6211e", "specVersion": "1.1.0" } diff --git a/install.sh b/install.sh index 7e94ad2..77a64e0 100755 --- a/install.sh +++ b/install.sh @@ -65,7 +65,12 @@ triple="${cpu}-${plat}" tag="${STATECRAFT_VERSION:-latest}" if [ "$tag" = "latest" ]; then say "resolving latest release…" - tag="$(dl_stdout "https://api.github.com/repos/${REPO}/releases/latest" \ + # Buffer the API response before parsing: streaming into `grep -m1` closes + # the pipe as soon as the tag line is found, and curl then prints a spurious + # "(56) Failure writing output" line on the happy path. + latest_json="$(dl_stdout "https://api.github.com/repos/${REPO}/releases/latest")" \ + || die "could not query the latest release (set STATECRAFT_VERSION)" + tag="$(printf '%s\n' "$latest_json" \ | grep -m1 '"tag_name"' \ | sed -E 's/.*"tag_name"[ ]*:[ ]*"([^"]+)".*/\1/')" [ -n "$tag" ] || die "could not resolve the latest release tag (set STATECRAFT_VERSION)" diff --git a/specs/007-release-distribution/spec.md b/specs/007-release-distribution/spec.md index f20c6ab..7de4f12 100644 --- a/specs/007-release-distribution/spec.md +++ b/specs/007-release-distribution/spec.md @@ -3,7 +3,7 @@ id: "007-release-distribution" title: "Release distribution: tag-gated prebuilt binaries and installer" status: approved created: "2026-07-22" -implementation: in-progress +implementation: complete depends_on: - "002-crate-scaffold" establishes: @@ -126,3 +126,32 @@ names above. authenticity story). - Self-update (re-run install.sh or use the Releases page; no in-binary updater, matching the no-bypass posture of the verbs). + +## 8. Status (2026-07-22) + +Implemented and live-verified; `implementation: complete`. + +The first release, v0.1.0 (signed tag on merge commit 4f0cc73, +workflow run 29964581207), went green on the first run: the version +guard passed, all five matrix legs built, and the publish job attached +all fifteen assets (five archives, five `.sha256` sidecars, five +CycloneDX SBOMs) to a published release with generated notes. + +Live check (§6 acceptance), Apple Silicon dev machine, hard mode: +`curl -fsSL .../install.sh | sh` with +`STATECRAFT_REQUIRE_ATTESTATION=1` resolved the latest tag to v0.1.0, +verified the checksum, verified the provenance attestation, installed +the aarch64-apple-darwin binary, and the installed `statecraft +--version` printed `statecraft 0.1.0` (`version --output json`: +`{"name":"statecraft","version":"0.1.0"}`). + +One wart found by the live check and fixed with this status edit: the +installer's latest-tag resolution streamed the GitHub API response +into `grep -m1`, which closes the pipe as soon as the tag line is +found and makes curl print a spurious "(56) Failure writing output" +line on the happy path; the response is now buffered before parsing. + +Known cosmetic follow-up, deliberately deferred: the pinned +actions/checkout (v4.3.1, shared with ci.yml) emits a Node 20 +deprecation notice on current runners. Bump both workflows together +when refreshing action pins; not worth a lone-file drift now.