diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c649ae4..49568d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,8 @@ jobs: build-test-package: runs-on: ubuntu-24.04 timeout-minutes: 30 + env: + RELEASE_VERSION: v0.2.8 steps: - name: Check out source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -43,12 +45,31 @@ jobs: ARCH=amd64 bash scripts/test CROSS=1 bash scripts/build SOURCE_DATE_EPOCH="$(git show -s --format=%ct HEAD)" bash scripts/package + raw="dist/artifacts/per-host-subnet-${RELEASE_VERSION}-linux-amd64" + test -f "$raw" + cmp bin/linux/amd64/per-host-subnet "$raw" + test "$("$raw" --version)" = "$RELEASE_VERSION" + tar -xOf "dist/artifacts/per-host-subnet-${RELEASE_VERSION#v}-linux-amd64.tar.xz" \ + usr/bin/per-host-subnet | cmp - "$raw" mkdir -p evidence + go version -m "$raw" | tee evidence/product-go-version.txt + grep -F "${raw}: go1.27.0" evidence/product-go-version.txt >/dev/null + (cd dist/artifacts && sha256sum -c SHA256SUMS) go version > evidence/go-version.txt go env -json GOOS GOARCH GOVERSION GOMOD GOENV > evidence/go-environment.json go list -m -json all > evidence/go-modules.json sha256sum dist/artifacts/* > evidence/artifacts.sha256 + - name: Scan Linux candidate binary + shell: bash + run: | + set -euo pipefail + mkdir -p "$RUNNER_TEMP/bin" + GOBIN="$RUNNER_TEMP/bin" go install golang.org/x/vuln/cmd/govulncheck@v1.6.0 + "$RUNNER_TEMP/bin/govulncheck" -mode=binary \ + "dist/artifacts/per-host-subnet-${RELEASE_VERSION}-linux-amd64" \ + | tee evidence/product-govulncheck.txt + - name: Upload build evidence if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/README.md b/README.md index 5ffc914..a27867d 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ PastureStack is an independent community effort to preserve, audit, and moderniz The preserved upstream release boundary is `v0.2.4`. Labels `v0.2.5` and `v0.2.6` existed only in a later local maintenance fork and are not represented as upstream releases here. Their reviewed Ubuntu and Go compatibility changes are retained in the PastureStack maintenance commit without inventing an upstream version. GitHub retains the pure numeric `v0.2.7` Linux prerelease as immutable review -evidence. Current `main` is newer than that tag and has no reserved release -version. PastureStack Server still carries the separately verified historical -Windows compatibility asset version `0.2.4`; none of these coordinates may be -presented as a new current Release. +evidence. `v0.2.8` is the proposed Linux/amd64 rebuild with Go 1.27.0; it is +not an available release until its candidate checks pass and the matching +GitHub asset and SHA-256 are published. PastureStack Server still carries the +separately verified historical Windows compatibility asset version `0.2.4`. ## Current scope @@ -45,17 +45,25 @@ go vet ./... go build -trimpath -buildvcs=false ./ ``` -The repository also provides `scripts/test`, `scripts/validate`, and `scripts/build` for local validation. From current `main`, build a review artifact with the commit-derived development version: +The repository also provides `scripts/test`, `scripts/validate`, and `scripts/build` for local validation. To build the `v0.2.8` candidate from a clean reviewed commit: ```sh -SOURCE_DATE_EPOCH=0 make package +RELEASE_VERSION=v0.2.8 SOURCE_DATE_EPOCH=0 make package ``` +This creates `dist/artifacts/per-host-subnet-v0.2.8-linux-amd64` for the overlay +package consumer, the Linux archive, a Windows review ZIP, and `SHA256SUMS` for +the Linux artifacts. Confirm the raw binary's embedded Go version with +`go version -m`, compare it byte-for-byte with the Linux archive entry, and +verify `SHA256SUMS` before publishing. Building the Windows review ZIP does not +approve it for deployment. CI additionally checks the Linux binary's reported +version and runs `govulncheck` on that exact packaged binary. + The historical Server build downloads its Windows compatibility asset from the matching versioned Server Release and verifies its SHA-256 digest. A future -Per-Host Subnet publication must first choose an unused pure numeric version, -rebuild both platform assets, and complete privileged Linux and Windows -integration. No deployment workflow is included at this stage. +Windows publication still requires privileged Windows integration. The Linux +binary refresh does not establish privileged two-host, upgrade, or rollback +compatibility, and no deployment workflow is included at this stage. The Windows ZIP retains the internal `rancher/` directory solely for the established Windows agent include/extraction contract. That directory is a compatibility boundary, not current product branding. New executable, service, environment, metadata-label, repository, and external asset names use PastureStack naming. diff --git a/scripts/package b/scripts/package index 9b8cf9d..b9fe9a8 100755 --- a/scripts/package +++ b/scripts/package @@ -7,6 +7,7 @@ cd "$(dirname "$0")/.." version="${VERSION#v}" linux_binary="bin/linux/amd64/per-host-subnet" windows_binary="bin/windows/amd64/per-host-subnet.exe" +linux_raw="dist/artifacts/per-host-subnet-v${version}-linux-amd64" linux_artifact="dist/artifacts/per-host-subnet-${version}-linux-amd64.tar.xz" windows_artifact="dist/artifacts/per-host-subnet-${version}-windows-amd64.zip" @@ -20,7 +21,8 @@ done rm -rf rootfs mkdir -p rootfs/linux/usr/bin dist/artifacts install -m 0755 "$linux_binary" rootfs/linux/usr/bin/per-host-subnet -rm -f "$linux_artifact" "$windows_artifact" +install -m 0755 "$linux_binary" "$linux_raw" +rm -f "$linux_artifact" "$windows_artifact" dist/artifacts/SHA256SUMS XZ_OPT=-9e tar \ --sort=name \ @@ -57,4 +59,10 @@ with zipfile.ZipFile(output, "w", compression=zipfile.ZIP_DEFLATED, compressleve archive.writestr(entry, path.read_bytes()) PY -printf '%s\n%s\n' "$linux_artifact" "$windows_artifact" +( + cd dist/artifacts + sha256sum "${linux_raw##*/}" "${linux_artifact##*/}" > SHA256SUMS + sha256sum -c SHA256SUMS +) + +printf '%s\n%s\n%s\n' "$linux_raw" "$linux_artifact" "$windows_artifact"