From a2acf7fb415a47d8017ad0c19fcf51cf2456c8dd Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 12 Sep 2026 19:50:52 -0700 Subject: [PATCH] chore(ci): refresh build pins and strengthen portable checks --- .github/workflows/ci.yml | 48 +++++++++++++++------ .github/workflows/crabbox-hydrate.yml | 4 +- .github/workflows/pages.yml | 8 ++-- .github/workflows/release-assets.yml | 4 +- .github/workflows/release.yml | 10 ++--- CHANGELOG.md | 3 ++ Makefile | 6 ++- README.md | 6 +-- docs/development.md | 2 + docs/releasing.md | 2 +- go.mod | 2 +- scripts/bootstrap-go-toolchain.sh | 16 +++---- scripts/rebuild-release-assets.sh | 2 +- scripts/recheck-release-source.sh | 4 +- scripts/release-local | 22 +++++----- scripts/test-release-assets.sh | 22 +++++----- scripts/test-release-local.sh | 61 ++++++++++++++------------- scripts/test-reproducible-builds.sh | 2 +- scripts/test-security-ci.sh | 18 ++++---- scripts/verify-release-assets.sh | 4 +- scripts/verify-snapshot-security.sh | 2 +- 21 files changed, 140 insertions(+), 108 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2e9d84..a663c9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,8 @@ name: ci on: push: + branches: + - main pull_request: permissions: @@ -11,10 +13,10 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/setup-go@v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod cache: true @@ -25,34 +27,54 @@ jobs: - name: Install golangci-lint run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.2 - name: Lint - run: make lint + run: make lint-check GOLANGCI_LINT=golangci-lint + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "26.8.2" + - name: Documentation metadata + run: | + node --test scripts/llms-metadata.test.mjs + node scripts/generate-llms.mjs + git diff --exit-code -- docs/llms.txt + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: "1.27.1" + cache: true + - name: Test latest Go on Windows + run: go test -race ./... audit: # The release contract exercises pinned macOS signing/verifier tools with # test doubles; run the whole audit on the platform whose system paths and # BSD tool semantics those boundaries deliberately freeze. runs-on: macos-15 steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/setup-go@v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod cache: true - name: Install dependencies run: go mod download + - name: Race tests on macOS + run: go test -race ./... - name: Install pinned ShellCheck run: | shellcheck_bin="$(./scripts/bootstrap-shellcheck.sh "$RUNNER_TEMP/shellcheck")" printf '%s\n' "${shellcheck_bin%/*}" >> "$GITHUB_PATH" - name: Lint workflows run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 - - name: Staticcheck - run: go run honnef.co/go/tools/cmd/staticcheck@v0.8.1 ./... - name: Deadcode run: | output_file=$(mktemp) - go run golang.org/x/tools/cmd/deadcode@v0.49.0 -test ./... > "$output_file" + go run golang.org/x/tools/cmd/deadcode@v0.50.0 -test ./... > "$output_file" if [ -s "$output_file" ]; then cat "$output_file" exit 1 @@ -60,19 +82,19 @@ jobs: - name: Security scan run: go run github.com/securego/gosec/v2/cmd/gosec@v2.29.0 ./... - name: Install vulnerability scanner - run: go install golang.org/x/vuln/cmd/govulncheck@v1.7.0 + run: go install golang.org/x/vuln/cmd/govulncheck@v1.8.0 - name: Source vulnerability scan run: '"$(go env GOPATH)/bin/govulncheck" -db=https://vuln.go.dev -test ./...' - - uses: goreleaser/goreleaser-action@v7 + - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: distribution: goreleaser - version: v2.17.1 + version: v2.18.1 args: check --config .goreleaser.yml - name: Build credential-free snapshot - uses: goreleaser/goreleaser-action@v7 + uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: distribution: goreleaser - version: v2.17.1 + version: v2.18.1 args: release --snapshot --clean --skip=publish --config .goreleaser.yml - name: Snapshot binary vulnerability scan env: diff --git a/.github/workflows/crabbox-hydrate.yml b/.github/workflows/crabbox-hydrate.yml index cec3fe0..fe0c8ef 100644 --- a/.github/workflows/crabbox-hydrate.yml +++ b/.github/workflows/crabbox-hydrate.yml @@ -35,12 +35,12 @@ jobs: runs-on: [self-hosted, crabbox, openclaw, goplaces, "${{ inputs.crabbox_runner_label }}"] timeout-minutes: 120 steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref || github.ref }} persist-credentials: false - - uses: actions/setup-go@v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod cache: true diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index d564bfe..4adf70b 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -25,15 +25,15 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/configure-pages@v6 + - uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 with: enablement: true - - uses: actions/upload-pages-artifact@v5 + - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: docs include-hidden-files: true - id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml index 8bdf448..2b7a452 100644 --- a/.github/workflows/release-assets.yml +++ b/.github/workflows/release-assets.yml @@ -187,12 +187,12 @@ jobs: run: | set -euo pipefail [[ -x "$GO_BIN" ]] - [[ "$(GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off "$GO_BIN" env GOVERSION)" == go1.26.7 ]] + [[ "$(GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off "$GO_BIN" env GOVERSION)" == go1.26.8 ]] (cd "$SOURCE" && /usr/bin/env GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off \ GOFLAGS=-mod=readonly GOPROXY=https://proxy.golang.org GOSUMDB=sum.golang.org \ GOVCS='*:off' "$GO_BIN" mod download all) /usr/bin/env GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off \ - GOBIN="$RUNNER_TEMP/tools" "$GO_BIN" install golang.org/x/vuln/cmd/govulncheck@v1.7.0 + GOBIN="$RUNNER_TEMP/tools" "$GO_BIN" install golang.org/x/vuln/cmd/govulncheck@v1.8.0 [[ -x "$RUNNER_TEMP/tools/govulncheck" ]] (cd "$SOURCE" && /usr/bin/env -u GH_TOKEN -u GITHUB_TOKEN \ GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off GOFLAGS=-mod=readonly \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 99d16f9..e839040 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,11 +15,11 @@ jobs: # exercise macOS-only producer and verifier boundaries. runs-on: macos-15 steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - - uses: actions/setup-go@v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod cache: true @@ -49,14 +49,14 @@ jobs: ./scripts/test-release-local.sh ./scripts/test-security-ci.sh - name: Install vulnerability scanner - run: go install golang.org/x/vuln/cmd/govulncheck@v1.7.0 + run: go install golang.org/x/vuln/cmd/govulncheck@v1.8.0 - name: Source vulnerability scan run: '"$(go env GOPATH)/bin/govulncheck" -db=https://vuln.go.dev -test ./...' - name: Build credential-free snapshot - uses: goreleaser/goreleaser-action@v7 + uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: distribution: goreleaser - version: v2.17.1 + version: v2.18.1 args: release --snapshot --clean --skip=publish --config .goreleaser.yml - name: Snapshot binary vulnerability scan env: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8234201..25ec627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Build: require Go 1.26.8 for upstream compiler and runtime fixes; update GoReleaser to 2.18.1, Node to 26.8.2, deadcode to 0.50.0, and govulncheck to 1.8.0 with matching release-verifier pins. +- CI: pin Actions by commit, test Windows with Go 1.27.1 and macOS with the race detector, verify documentation metadata, reject formatting drift, and avoid duplicate branch-push audits. + - CI: update the reviewed GitHub CLI pin to 2.100.0 so release contract tests accept the current Homebrew version installed by CI. - Build: update Kong to 1.16.1, golangci-lint to 2.13.2, deadcode to 0.49.0, gosec to 2.29.0, govulncheck to 1.7.0, and setup-go to v7. diff --git a/Makefile b/Makefile index 32dd420..383b794 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: lint test coverage +.PHONY: lint lint-check test coverage .PHONY: e2e goplaces force GOLANGCI_LINT_VERSION ?= v2.13.2 @@ -8,6 +8,10 @@ lint: $(GOLANGCI_LINT) fmt $(GOLANGCI_LINT) run ./... +lint-check: + $(GOLANGCI_LINT) fmt --diff + $(GOLANGCI_LINT) run ./... + test: go test ./... diff --git a/README.md b/README.md index 75577c9..2b86315 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![CI](https://img.shields.io/github/actions/workflow/status/openclaw/goplaces/ci.yml?branch=main&style=flat-square&label=ci)](https://github.com/openclaw/goplaces/actions/workflows/ci.yml) [![GitHub release](https://img.shields.io/github/v/release/openclaw/goplaces?style=flat-square)](https://github.com/openclaw/goplaces/releases/latest) -[![Go](https://img.shields.io/badge/Go-1.26.7-00ADD8?style=flat-square&logo=go&logoColor=white)](https://go.dev/dl/) +[![Go](https://img.shields.io/badge/Go-1.26.8-00ADD8?style=flat-square&logo=go&logoColor=white)](https://go.dev/dl/) [![License](https://img.shields.io/github/license/openclaw/goplaces?style=flat-square)](LICENSE) [![Homebrew](https://img.shields.io/badge/Homebrew-openclaw%2Ftap-FBB040?style=flat-square&logo=homebrew&logoColor=black)](https://github.com/openclaw/homebrew-tap/blob/main/Casks/goplaces.rb) [![Docs](https://img.shields.io/badge/docs-goplaces.sh-3b82f6?style=flat-square)](https://goplaces.sh) @@ -19,7 +19,7 @@ Homebrew installs the published binary on macOS or Linux: brew install --cask openclaw/tap/goplaces ``` -With Go 1.26.7 or newer: +With Go 1.26.8 or newer: ```sh go install github.com/steipete/goplaces/cmd/goplaces@latest @@ -99,7 +99,7 @@ See the [Go package reference](https://pkg.go.dev/github.com/steipete/goplaces) ## Development -Go 1.26.7 is required. +Go 1.26.8 is required. ```sh go mod download diff --git a/docs/development.md b/docs/development.md index 08239c8..486238b 100644 --- a/docs/development.md +++ b/docs/development.md @@ -12,6 +12,8 @@ make lint test coverage The coverage target enforces the repository's coverage threshold. The CI workflow also runs workflow linting, static analysis, security scanners, release configuration checks, and credential-free release builds. +Use `make lint-check` to check formatting without modifying files. CI tests the declared Go floor on Linux and macOS, runs race tests on macOS and on Windows with the latest stable Go, and verifies the Node documentation metadata tests and generated index. Staticcheck runs through golangci-lint. + ## Authenticated end-to-end tests End-to-end tests are optional because they call Google services and incur normal quota or billing usage. diff --git a/docs/releasing.md b/docs/releasing.md index 8f4bb34..5281f95 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -36,7 +36,7 @@ Run the full local proof set before requesting either serialized gate: - formatting and clean-diff checks; - autoreview to no accepted or actionable findings. -Run `scripts/release-local --check` for the aggregated preflight. It must reject ambient Go build controls, the wrong native Go version, a dirty or stale checkout, a non-default branch, and any mismatch with current protected `main`. The check builds pinned govulncheck v1.7.0 with the pinned Go 1.26.7 producer into its private audit directory, verifies the reviewed module checksum, then disables Go module resolution while querying the exact official vulnerability database URL. It never trusts a user-level `go/bin` lookup. +Run `scripts/release-local --check` for the aggregated preflight. It must reject ambient Go build controls, the wrong native Go version, a dirty or stale checkout, a non-default branch, and any mismatch with current protected `main`. The check builds pinned govulncheck v1.8.0 with the pinned Go 1.26.8 producer into its private audit directory, verifies the reviewed module checksum, then disables Go module resolution while querying the exact official vulnerability database URL. It never trusts a user-level `go/bin` lookup. For a gated pilot or draft, copy `.mac-release.env.example` to the ignored `.mac-release.env`, keep mode `0400` or `0600`, and set the two direct runtime locators shown there: `MAC_RELEASE_CODESIGN_KEYCHAIN` and exported `NOTARYTOOL_KEYCHAIN_PROFILE`. The file is strictly parsed and frozen before `release-mac-app` reads it. Package-secret and 1Password lookup fields are rejected in this lane so the helper and producer can execute with pinned, system-only tool paths. `scripts/release-local` also pins the reviewed SHA-256 of both the external `mac-release` entrypoint and its library before either can enter the secret-bearing process; any helper update requires an explicit local review and pin update. diff --git a/go.mod b/go.mod index 497161e..c05e5ad 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module github.com/steipete/goplaces -go 1.26.7 +go 1.26.8 require github.com/alecthomas/kong v1.16.1 diff --git a/scripts/bootstrap-go-toolchain.sh b/scripts/bootstrap-go-toolchain.sh index 00a7d60..f489a39 100755 --- a/scripts/bootstrap-go-toolchain.sh +++ b/scripts/bootstrap-go-toolchain.sh @@ -43,14 +43,14 @@ destination="$parent/$(basename "$destination")" case "$($uname_bin -m)" in arm64) - archive_name=go1.26.7.darwin-arm64.tar.gz - expected_size=64772572 - expected_sha256=020a1e8224811be75163e920bc77e0926a1390a6aeea19bdcf23f74b9d749f6d + archive_name=go1.26.8.darwin-arm64.tar.gz + expected_size=64626620 + expected_sha256=a012b25b571bd0138a03dcd25375ceba866fe5ca822f426d2c66a4de56fd3f4b ;; x86_64) - archive_name=go1.26.7.darwin-amd64.tar.gz - expected_size=67852067 - expected_sha256=92e8b34bff3c89ab16404c595669ac8cb004cc2f676dcbd1f5b87a6b8def3b47 + archive_name=go1.26.8.darwin-amd64.tar.gz + expected_size=67759394 + expected_sha256=186be014105aa6542b767d2c6ed5cca10a0214bdff809ef1724022a8c7894150 ;; *) die "unsupported macOS architecture" ;; esac @@ -61,7 +61,7 @@ if [[ "$testing" == 1 ]]; then expected_size="${EXPECTED_ARCHIVE_SIZE:-$expected_size}" expected_sha256="${EXPECTED_ARCHIVE_SHA256:-$expected_sha256}" fi -[[ "$archive_url" == https://dl.google.com/go/go1.26.7.darwin-*.tar.gz ]] || die "unexpected toolchain URL" +[[ "$archive_url" == https://dl.google.com/go/go1.26.8.darwin-*.tar.gz ]] || die "unexpected toolchain URL" [[ "$expected_size" =~ ^[1-9][0-9]*$ ]] || die "invalid pinned archive size" [[ "$expected_sha256" =~ ^[0-9a-f]{64}$ ]] || die "invalid pinned archive digest" @@ -95,7 +95,7 @@ $tar_bin -xzf "$archive" -C "$destination" --no-same-owner || die "toolchain ext go_root="$destination/go" [[ -d "$go_root" && ! -L "$go_root" ]] || die "toolchain root is invalid" [[ -f "$go_root/bin/go" && ! -L "$go_root/bin/go" && -x "$go_root/bin/go" ]] || die "toolchain Go executable is invalid" -[[ "$(GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off "$go_root/bin/go" env GOVERSION)" == go1.26.7 ]] || +[[ "$(GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off "$go_root/bin/go" env GOVERSION)" == go1.26.8 ]] || die "extracted toolchain version mismatch" rm -f "$archive" "$members" diff --git a/scripts/rebuild-release-assets.sh b/scripts/rebuild-release-assets.sh index b74d106..580d9ee 100755 --- a/scripts/rebuild-release-assets.sh +++ b/scripts/rebuild-release-assets.sh @@ -39,7 +39,7 @@ done command -v "$go_bin" >/dev/null 2>&1 || die "go is required" [[ -x "$git_bin" ]] || die "trusted Git executable is required" command -v "$jq_bin" >/dev/null 2>&1 || die "jq is required" -[[ "$($go_bin env GOVERSION)" == go1.26.7 ]] || die "rebuild requires Go 1.26.7" +[[ "$($go_bin env GOVERSION)" == go1.26.8 ]] || die "rebuild requires Go 1.26.8" source_dir="$(cd "$source_dir" && pwd -P)" verified_dir="$(cd "$verified_dir" && pwd -P)" diff --git a/scripts/recheck-release-source.sh b/scripts/recheck-release-source.sh index 6587979..7be902a 100755 --- a/scripts/recheck-release-source.sh +++ b/scripts/recheck-release-source.sh @@ -11,8 +11,8 @@ readonly sed_bin=/usr/bin/sed readonly grep_bin=/usr/bin/grep readonly official_origin=https://github.com/openclaw/goplaces.git readonly system_path=/usr/bin:/bin:/usr/sbin:/sbin -readonly expected_go_version=go1.26.7 -readonly expected_goreleaser_version=2.17.1 +readonly expected_go_version=go1.26.8 +readonly expected_goreleaser_version=2.18.1 die() { echo "release source recheck: $*" >&2 diff --git a/scripts/release-local b/scripts/release-local index 5cfa85f..987b981 100755 --- a/scripts/release-local +++ b/scripts/release-local @@ -9,7 +9,7 @@ umask 077 readonly REPOSITORY="openclaw/goplaces" readonly EXPECTED_ORIGIN_HTTPS="https://github.com/${REPOSITORY}" readonly API_VERSION="2026-03-10" -readonly EXPECTED_GO_VERSION="go1.26.7" +readonly EXPECTED_GO_VERSION="go1.26.8" readonly VERIFIER_WORKFLOW=".github/workflows/release-assets.yml" readonly VERIFIER_WORKFLOW_ID="311062804" readonly TAP_REPOSITORY="openclaw/homebrew-tap" @@ -36,13 +36,13 @@ readonly GREP_BIN="/usr/bin/grep" readonly CMP_BIN="/usr/bin/cmp" readonly TAR_BIN="/usr/bin/bsdtar" readonly UNAME_BIN="/usr/bin/uname" -readonly EXPECTED_GORELEASER_VERSION="2.17.1" -readonly EXPECTED_NODE_VERSION="v26.7.0" +readonly EXPECTED_GORELEASER_VERSION="2.18.1" +readonly EXPECTED_NODE_VERSION="v26.8.2" readonly EXPECTED_EXPECT_VERSION="expect version 5.45.4" readonly EXPECTED_PYTHON_VERSION="Python 3.14.7" readonly EXPECTED_GH_VERSION="2.100.0" readonly EXPECTED_JQ_VERSION="jq-1.8.2" -readonly EXPECTED_GOVULNCHECK_MODULE_SUM="h1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=" +readonly EXPECTED_GOVULNCHECK_MODULE_SUM="h1:clG4qBU6zH5VKjti8n5j8BBuYzoSha392xXMkXS351U=" repo_root="$(cd "$(/usr/bin/dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" cd "$repo_root" @@ -234,9 +234,9 @@ resolve_producer_tools() { resolved_expect="$(resolve_executable expect)" resolved_python="$(resolve_executable python3)" if [[ "${GOPLACES_RELEASE_LOCAL_TESTING:-0}" != 1 ]]; then - [[ "$resolved_go" =~ ^(/opt/homebrew|/usr/local)/Cellar/go(@1\.26)?/1\.26\.7/libexec/bin/go$ ]] || die "Go must resolve to the canonical Homebrew 1.26.7 executable" - [[ "$resolved_goreleaser" =~ ^(/opt/homebrew|/usr/local)/Cellar/goreleaser/2\.17\.1/bin/goreleaser$ ]] || die "GoReleaser must resolve to the canonical Homebrew 2.17.1 executable" - [[ "$resolved_node" =~ ^(/opt/homebrew|/usr/local)/Cellar/node/26\.7\.0(_1)?/bin/node$ ]] || die "Node must resolve to the reviewed Homebrew 26.7.0 executable" + [[ "$resolved_go" =~ ^(/opt/homebrew|/usr/local)/Cellar/go(@1\.26)?/1\.26\.8/libexec/bin/go$ ]] || die "Go must resolve to the canonical Homebrew 1.26.8 executable" + [[ "$resolved_goreleaser" =~ ^(/opt/homebrew|/usr/local)/Cellar/goreleaser/2\.18\.1/bin/goreleaser$ ]] || die "GoReleaser must resolve to the canonical Homebrew 2.18.1 executable" + [[ "$resolved_node" =~ ^(/opt/homebrew|/usr/local)/Cellar/node/26\.8\.2/bin/node$ ]] || die "Node must resolve to the reviewed Homebrew 26.8.2 executable" [[ "$resolved_expect" =~ ^(/opt/homebrew|/usr/local)/Cellar/expect/5\.45\.4_3/bin/expect$ ]] || die "Expect must resolve to the canonical Homebrew 5.45.4_3 executable" [[ "$resolved_python" =~ ^(/opt/homebrew|/usr/local)/Cellar/python@3\.14/3\.14\.7/Frameworks/Python\.framework/Versions/3\.14/bin/python3\.14$ ]] || die "Python must resolve to the canonical Homebrew 3.14.7 executable" producer_go_root="${resolved_go%/bin/go}" @@ -1011,7 +1011,7 @@ preflight_repository() { native_go="$(/usr/bin/env -i PATH="$SECRET_SCOPE_SYSTEM_PATH" HOME="${git_isolation_root}/home" TMPDIR="${git_isolation_root}/tmp" LC_ALL=C TZ=UTC GOROOT="$native_go_root" GOENV=off GOTOOLCHAIN=local "$native_go_bin" env GOVERSION)" || die "native Go toolchain is unavailable" [[ "$native_go" == "$EXPECTED_GO_VERSION" ]] || die "requires native $EXPECTED_GO_VERSION, found $native_go" require_regular_file "${protected_source_root}/go.mod" - grep -Eq '^go 1\.26\.7$' "${protected_source_root}/go.mod" || die "protected go.mod must require Go 1.26.7" + grep -Eq '^go 1\.26\.8$' "${protected_source_root}/go.mod" || die "protected go.mod must require Go 1.26.8" require_regular_file "${protected_source_root}/.goreleaser.yml" if grep -Eq 'homebrew_|HOMEBREW_|com\.apple\.quarantine|xattr' "${protected_source_root}/.goreleaser.yml"; then die "GoReleaser config must not publish Homebrew metadata or strip quarantine" @@ -1855,8 +1855,8 @@ validate_govulncheck_build_info() { local build_info="$1" executable="$2" "$GREP_BIN" -Fqx "${executable}: ${EXPECTED_GO_VERSION}" <<< "$build_info" || die "govulncheck was not built with ${EXPECTED_GO_VERSION}" "$GREP_BIN" -Fqx $'\tpath\tgolang.org/x/vuln/cmd/govulncheck' <<< "$build_info" || die "govulncheck command path is not exact" - "$GREP_BIN" -Fqx $'\tmod\tgolang.org/x/vuln\tv1.7.0\t'"$EXPECTED_GOVULNCHECK_MODULE_SUM" <<< "$build_info" || - die "govulncheck module identity is not the reviewed v1.7.0 sum" + "$GREP_BIN" -Fqx $'\tmod\tgolang.org/x/vuln\tv1.8.0\t'"$EXPECTED_GOVULNCHECK_MODULE_SUM" <<< "$build_info" || + die "govulncheck module identity is not the reviewed v1.8.0 sum" } run_check_suite() { @@ -1911,7 +1911,7 @@ run_check_suite() { cd "$source" "${download_env[@]}" "$go_bin" mod download all ) - "${download_env[@]}" GOBIN="$audit_bin" "$go_bin" install golang.org/x/vuln/cmd/govulncheck@v1.7.0 + "${download_env[@]}" GOBIN="$audit_bin" "$go_bin" install golang.org/x/vuln/cmd/govulncheck@v1.8.0 /bin/chmod 500 "$govulncheck_bin" require_canonical_executable "$govulncheck_bin" "frozen govulncheck" govulncheck_build_info="$(/usr/bin/env -i PATH="$SECRET_SCOPE_SYSTEM_PATH" HOME="${scratch}/home" TMPDIR="${scratch}/tmp" LC_ALL=C TZ=UTC GOROOT="$producer_go_root" "$go_bin" version -m "$govulncheck_bin")" || diff --git a/scripts/test-release-assets.sh b/scripts/test-release-assets.sh index 6c18056..0fb0d9c 100755 --- a/scripts/test-release-assets.sh +++ b/scripts/test-release-assets.sh @@ -46,7 +46,7 @@ grep -Fq 'runner: macos-15' "$workflow" || fail "native arm64 runner is missing" grep -Fq 'runner: macos-15-intel' "$workflow" || fail "native Intel runner is missing" if grep -Eq '^[[:space:]]*uses:' "$workflow"; then fail "release verifier must not depend on mutable actions"; fi grep -Fq 'Install exact pinned Go toolchain' "$workflow" || fail "pinned toolchain bootstrap step is missing" -grep -Fq 'govulncheck@v1.7.0' "$workflow" || fail "govulncheck version is not pinned" +grep -Fq 'govulncheck@v1.8.0' "$workflow" || fail "govulncheck version is not pinned" [[ "$(grep -Fc '"$RUNNER_TEMP/tools/govulncheck" -db=https://vuln.go.dev -test ./...' "$workflow")" -eq 1 ]] || fail "exact tagged source must receive one official-database vulnerability scan including tests" grep -Fq "GOPROXY=off GOSUMDB=off GOVCS='*:off'" "$workflow" || fail "exact tagged source scan is not module-offline" grep -Fq 'GOENV=off GOTOOLCHAIN=local GOWORK=off GOTELEMETRY=off' "$workflow" || fail "Go configuration is not hermetic" @@ -98,12 +98,12 @@ done grep -Fq 'unzip_bin=/usr/bin/unzip' scripts/check-release-verifier.sh || fail "verifier checker does not force system unzip in production" grep -Fq '/usr/bin/env -i PATH=/usr/bin:/bin HOME="$scratch/unzip-home"' scripts/check-release-verifier.sh || fail "verifier checker does not isolate unzip configuration" grep -Fq '/usr/bin/awk' scripts/download-release-assets.sh || fail "release downloader does not force system awk" -grep -Fq 'go1.26.7.darwin-amd64.tar.gz' scripts/bootstrap-go-toolchain.sh || fail "Intel toolchain URL is not pinned" -grep -Fq '92e8b34bff3c89ab16404c595669ac8cb004cc2f676dcbd1f5b87a6b8def3b47' scripts/bootstrap-go-toolchain.sh || fail "Intel toolchain digest is not pinned" -grep -Fq '67852067' scripts/bootstrap-go-toolchain.sh || fail "Intel toolchain size is not pinned" -grep -Fq 'go1.26.7.darwin-arm64.tar.gz' scripts/bootstrap-go-toolchain.sh || fail "arm64 toolchain URL is not pinned" -grep -Fq '020a1e8224811be75163e920bc77e0926a1390a6aeea19bdcf23f74b9d749f6d' scripts/bootstrap-go-toolchain.sh || fail "arm64 toolchain digest is not pinned" -grep -Fq '64772572' scripts/bootstrap-go-toolchain.sh || fail "arm64 toolchain size is not pinned" +grep -Fq 'go1.26.8.darwin-amd64.tar.gz' scripts/bootstrap-go-toolchain.sh || fail "Intel toolchain URL is not pinned" +grep -Fq '186be014105aa6542b767d2c6ed5cca10a0214bdff809ef1724022a8c7894150' scripts/bootstrap-go-toolchain.sh || fail "Intel toolchain digest is not pinned" +grep -Fq '67759394' scripts/bootstrap-go-toolchain.sh || fail "Intel toolchain size is not pinned" +grep -Fq 'go1.26.8.darwin-arm64.tar.gz' scripts/bootstrap-go-toolchain.sh || fail "arm64 toolchain URL is not pinned" +grep -Fq 'a012b25b571bd0138a03dcd25375ceba866fe5ca822f426d2c66a4de56fd3f4b' scripts/bootstrap-go-toolchain.sh || fail "arm64 toolchain digest is not pinned" +grep -Fq '64626620' scripts/bootstrap-go-toolchain.sh || fail "arm64 toolchain size is not pinned" grep -Fq 'refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG' "$workflow" || fail "exact annotated tag ref is not fetched into source" [[ "$(grep -Fc 'status --porcelain --untracked-files=all' "$workflow")" -eq 3 ]] || fail "workflow source trees are not checked with exact all-untracked status" @@ -113,7 +113,7 @@ cat >"$bootstrap_payload/go/bin/go" <<'MOCK' #!/usr/bin/env bash set -euo pipefail [[ "$1" == env && "$2" == GOVERSION ]] -printf 'go1.26.7\n' +printf 'go1.26.8\n' MOCK chmod +x "$bootstrap_payload/go/bin/go" bootstrap_archive="$tmp/bootstrap.tar.gz" @@ -149,7 +149,7 @@ for bootstrap_arch in arm64 x86_64; do bootstrap_dest="$tmp/go-$bootstrap_arch" MOCK_BOOTSTRAP_LOG="$tmp/bootstrap.log" MOCK_BOOTSTRAP_ARCHIVE="$bootstrap_archive" MOCK_UNAME_ARCH="$bootstrap_arch" \ GOPLACES_RELEASE_TESTING=1 CURL_BIN="$bootstrap_curl" UNAME_BIN="$bootstrap_uname" \ - EXPECTED_ARCHIVE_URL="https://dl.google.com/go/go1.26.7.darwin-$archive_arch.tar.gz" \ + EXPECTED_ARCHIVE_URL="https://dl.google.com/go/go1.26.8.darwin-$archive_arch.tar.gz" \ EXPECTED_ARCHIVE_SIZE="$bootstrap_size" EXPECTED_ARCHIVE_SHA256="$bootstrap_sha" \ ./scripts/bootstrap-go-toolchain.sh "$bootstrap_dest" >/dev/null [[ -x "$bootstrap_dest/go/bin/go" ]] || fail "bootstrap did not install $bootstrap_arch Go" @@ -495,7 +495,7 @@ mac_mock="$tmp/mac-verify-mock" cat >"$go_mock" <<'MOCK' #!/usr/bin/env bash set -euo pipefail -if [[ "$1" == env && "$2" == GOVERSION ]]; then printf 'go1.26.7\n'; exit 0; fi +if [[ "$1" == env && "$2" == GOVERSION ]]; then printf 'go1.26.8\n'; exit 0; fi if [[ "$1" == env && "$2" == GOMODCACHE ]]; then printf '%s\n' "$MOCK_MODULE_CACHE"; exit 0; fi if [[ "$1" == version && "$2" == -m ]]; then binary=$3 @@ -508,7 +508,7 @@ if [[ "$1" == version && "$2" == -m ]]; then *windows_arm64*) os=windows; arch=arm64 ;; *) exit 90 ;; esac - printf '%s: go1.26.7\n' "$binary" + printf '%s: go1.26.8\n' "$binary" printf '\tpath\tgithub.com/steipete/goplaces/cmd/goplaces\n' printf '\tmod\tgithub.com/steipete/goplaces\tv0.4.5\n' printf '\tbuild\t-ldflags="-s -w -X github.com/steipete/goplaces/internal/cli.Version=0.4.5"\n' diff --git a/scripts/test-release-local.sh b/scripts/test-release-local.sh index 5f260a7..b7ef57b 100755 --- a/scripts/test-release-local.sh +++ b/scripts/test-release-local.sh @@ -156,7 +156,7 @@ EOF grep -Fq 'homebrew_command list "$kind_flag" --full-name' "$release_script" || die "Homebrew installed-state proof is not a no-name full inventory" grep -Fq 'homebrew_command --prefix --formula goplaces' "$release_script" || die "installed binary lookup is not Formula-specific" grep -Fq 'readonly EXPECTED_GH_VERSION="2.100.0"' "$release_script" || die "GitHub CLI version is not pinned" - grep -Fq 'Cellar/node/26\.7\.0(_1)?/bin/node' "$release_script" || die "reviewed Node formula revision is not allowlisted" + grep -Fq 'Cellar/node/26\.8\.2/bin/node' "$release_script" || die "reviewed Node formula revision is not allowlisted" grep -Fq 'candidate=/opt/homebrew/opt/gh/bin/gh' "$release_script" || die "GitHub CLI does not bypass the mutable bin wrapper" ! grep -Fq 'candidate=/opt/homebrew/bin/gh' "$release_script" || die "GitHub CLI still freezes the mutable wrapper" grep -Fq "select(.path == \$path)" "$release_script" || die "workflow path is not exact" @@ -211,18 +211,18 @@ EOF ! grep -Eq '^[[:space:]]+env -i PATH="\$producer_path"' "$release_script" || die "check suite trusts an ambient env executable" grep -Fq '"${download_env[@]}" "$go_bin" mod download all' "$release_script" || die "check suite does not populate its isolated module cache" ! grep -Fq 'need govulncheck' "$release_script" || die "check suite still depends on ambient govulncheck PATH" - grep -Fq '"${download_env[@]}" GOBIN="$audit_bin" "$go_bin" install golang.org/x/vuln/cmd/govulncheck@v1.7.0' "$release_script" || die "check suite does not install pinned govulncheck with pinned Go" + grep -Fq '"${download_env[@]}" GOBIN="$audit_bin" "$go_bin" install golang.org/x/vuln/cmd/govulncheck@v1.8.0' "$release_script" || die "check suite does not install pinned govulncheck with pinned Go" grep -Fq 'require_canonical_executable "$govulncheck_bin" "frozen govulncheck"' "$release_script" || die "installed govulncheck is not frozen before proof" - grep -Fq 'readonly EXPECTED_GOVULNCHECK_MODULE_SUM="h1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg="' "$release_script" || die "govulncheck reviewed module sum is not pinned" + grep -Fq 'readonly EXPECTED_GOVULNCHECK_MODULE_SUM="h1:clG4qBU6zH5VKjti8n5j8BBuYzoSha392xXMkXS351U="' "$release_script" || die "govulncheck reviewed module sum is not pinned" grep -Fq '"$go_bin" version -m "$govulncheck_bin"' "$release_script" || die "installed govulncheck build information is not inspected" grep -Fq 'GOROOT="$producer_go_root" "$go_bin" version -m "$govulncheck_bin"' "$release_script" || die "govulncheck build inspection lost the pinned Go root" - grep -Fq "\$'\\tmod\\tgolang.org/x/vuln\\tv1.7.0\\t'" "$release_script" || die "installed govulncheck module identity is not checked" + grep -Fq "\$'\\tmod\\tgolang.org/x/vuln\\tv1.8.0\\t'" "$release_script" || die "installed govulncheck module identity is not checked" grep -Fq '/bin/chmod -R u+w "$scratch"' "$release_script" || die "check-suite module cache is not made removable" grep -Fq '"${clean_env[@]}" "$govulncheck_bin" -db=https://vuln.go.dev -test ./...' "$release_script" || die "source vulnerability scan does not pin the official database URL" grep -Fq 'SNAPSHOT_EXPECTED_COMMIT="$default_sha" SNAPSHOT_REQUIRE_CLEAN=1' "$release_script" || die "local snapshot proof is not bound to protected clean source" grep -Fq 'GO_BIN="$go_bin" ./scripts/test-reproducible-builds.sh dist' "$release_script" || die "local reproducibility gate does not compare generated snapshot artifacts" download_line="$(grep -nF '"${download_env[@]}" "$go_bin" mod download all' "$release_script" | cut -d: -f1)" - govuln_install_line="$(grep -nF '"${download_env[@]}" GOBIN="$audit_bin" "$go_bin" install golang.org/x/vuln/cmd/govulncheck@v1.7.0' "$release_script" | cut -d: -f1)" + govuln_install_line="$(grep -nF '"${download_env[@]}" GOBIN="$audit_bin" "$go_bin" install golang.org/x/vuln/cmd/govulncheck@v1.8.0' "$release_script" | cut -d: -f1)" offline_line="$(grep -nF 'GOPROXY=off GOSUMDB=off' "$release_script" | head -n 1 | cut -d: -f1)" [[ "$download_line" =~ ^[0-9]+$ && "$govuln_install_line" =~ ^[0-9]+$ && "$offline_line" =~ ^[0-9]+$ && "$download_line" -lt "$govuln_install_line" && "$govuln_install_line" -lt "$offline_line" ]] || die "offline proof begins before dependencies and pinned govulncheck are populated" grep -Fq './scripts/recheck-release-source.sh' "$release_script" || die "codesign-run lacks its protected post-manifest source recheck" @@ -241,16 +241,17 @@ EOF test_govulncheck_build_info_validation() { local binary good bad binary="/private/tmp/frozen/govulncheck" - good="${binary}: go1.26.7"$'\n\tpath\tgolang.org/x/vuln/cmd/govulncheck\n\tmod\tgolang.org/x/vuln\tv1.7.0\th1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=' + good="${binary}: go1.26.8"$'\n\tpath\tgolang.org/x/vuln/cmd/govulncheck\n\tmod\tgolang.org/x/vuln\tv1.8.0\th1:clG4qBU6zH5VKjti8n5j8BBuYzoSha392xXMkXS351U=' ( source_release validate_govulncheck_build_info "$good" "$binary" ) for bad in \ - "${good/go1.26.7/go1.26.4}" \ + "${good/go1.26.8/go1.26.4}" \ "${good/golang.org\/x\/vuln\/cmd\/govulncheck/example.invalid\/govulncheck}" \ - "${good/v1.7.0/v1.4.2}" \ - "${good/4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=}"; do + "${good/v1.8.0/v1.4.2}" \ + "${good/clG4qBU6zH5VKjti8n5j8BBuYzoSha392xXMkXS351U=/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=}"; do + [[ "$bad" != "$good" ]] || die "hostile govulncheck fixture did not mutate valid metadata" if ( source_release validate_govulncheck_build_info "$bad" "$binary" @@ -1104,13 +1105,13 @@ test_post_manifest_source_recheck() { #!/bin/bash -p set -euo pipefail [[ "$*" == 'env GOVERSION' ]] || exit 91 -printf 'go1.26.7\n' +printf 'go1.26.8\n' EOF cat > "$goreleaser_bin" <<'EOF' #!/bin/bash -p set -euo pipefail if [[ "$*" == --version ]]; then - printf 'GitVersion: 2.17.1\n' + printf 'GitVersion: 2.18.1\n' exit 0 fi [[ "${1:-}" == release ]] || exit 92 @@ -1258,7 +1259,7 @@ EOF #!/bin/bash -p set -euo pipefail [[ "$*" == --version ]] || exit 93 -printf 'v26.7.0\n' +printf 'v26.8.2\n' EOF cat > "${directory}/expect" <<'EOF' #!/bin/bash -p @@ -1295,7 +1296,7 @@ test_producer_gate_hardening() { alias_tmp="${scratch}/tmp-alias" mkdir -p "$real_tmp" ln -s "$real_tmp" "$alias_tmp" - make_fake_producer_tools "$tools" go1.26.7 2.17.1 + make_fake_producer_tools "$tools" go1.26.8 2.18.1 mkdir -p "$launch" ln -s "${tools}/go" "${launch}/go" ln -s "${tools}/goreleaser" "${launch}/goreleaser" @@ -1360,7 +1361,7 @@ EOF [[ ! -e "$sentinel" ]] || die "hostile PATH utility executed during producer resolution" old_go="${scratch}/old-go" - make_fake_producer_tools "$old_go" go1.26.4 2.17.1 + make_fake_producer_tools "$old_go" go1.26.4 2.18.1 if ( export GOPLACES_RELEASE_LOCAL_TESTING=1 GOPLACES_RELEASE_LOCAL_SOURCE_ONLY=1 RELEASE_MAC_APP_BIN="$helper" source "$release_script" @@ -1371,7 +1372,7 @@ EOF die "old Go entered the producer gate" fi old_goreleaser="${scratch}/old-goreleaser" - make_fake_producer_tools "$old_goreleaser" go1.26.7 2.15.2 + make_fake_producer_tools "$old_goreleaser" go1.26.8 2.15.2 if ( export GOPLACES_RELEASE_LOCAL_TESTING=1 GOPLACES_RELEASE_LOCAL_SOURCE_ONLY=1 RELEASE_MAC_APP_BIN="$helper" source "$release_script" @@ -1383,7 +1384,7 @@ EOF fi mutation="${scratch}/mutation-tools" - make_fake_producer_tools "$mutation" go1.26.7 2.17.1 + make_fake_producer_tools "$mutation" go1.26.8 2.18.1 if ( export GOPLACES_RELEASE_LOCAL_TESTING=1 GOPLACES_RELEASE_LOCAL_SOURCE_ONLY=1 RELEASE_MAC_APP_BIN="$helper" source "$release_script" @@ -1396,7 +1397,7 @@ EOF ) >/dev/null 2>&1; then die "same-byte GoReleaser inode replacement was accepted" fi - make_fake_producer_tools "$mutation" go1.26.7 2.17.1 + make_fake_producer_tools "$mutation" go1.26.8 2.18.1 if ( export GOPLACES_RELEASE_LOCAL_TESTING=1 GOPLACES_RELEASE_LOCAL_SOURCE_ONLY=1 RELEASE_MAC_APP_BIN="$helper" source "$release_script" @@ -1408,7 +1409,7 @@ EOF ) >/dev/null 2>&1; then die "in-place Go byte mutation was accepted" fi - make_fake_producer_tools "$mutation" go1.26.7 2.17.1 + make_fake_producer_tools "$mutation" go1.26.8 2.18.1 if ( export GOPLACES_RELEASE_LOCAL_TESTING=1 GOPLACES_RELEASE_LOCAL_SOURCE_ONLY=1 RELEASE_MAC_APP_BIN="$helper" source "$release_script" @@ -1421,7 +1422,7 @@ EOF ) >/dev/null 2>&1; then die "same-byte release-mac-app replacement was accepted" fi - make_fake_producer_tools "$mutation" go1.26.7 2.17.1 + make_fake_producer_tools "$mutation" go1.26.8 2.18.1 if ( export GOPLACES_RELEASE_LOCAL_TESTING=1 GOPLACES_RELEASE_LOCAL_SOURCE_ONLY=1 RELEASE_MAC_APP_BIN="$helper" source "$release_script" @@ -1682,7 +1683,7 @@ case "$1 ${2:-}" in 'merge-base --is-ancestor') ;; 'checkout --quiet') mkdir -p "$2/scripts" - printf 'module example.invalid/goplaces\n\ngo 1.26.7\n' > "$2/go.mod" + printf 'module example.invalid/goplaces\n\ngo 1.26.8\n' > "$2/go.mod" printf 'version: 2\nrelease:\n draft: true\n' > "$2/.goreleaser.yml" printf '## 0.4.5 - Unreleased\n\n- Protected pilot release.\n' > "$2/CHANGELOG.md" cp "$MOCK_FIXTURE_ROOT/scripts/release-local" "$2/scripts/release-local" @@ -1701,14 +1702,14 @@ EOF set -euo pipefail printf 'go' >> "$MOCK_LOG"; printf ' <%s>' "$@" >> "$MOCK_LOG"; printf '\n' >> "$MOCK_LOG" [[ "$*" == 'env GOVERSION' ]] || { echo "unexpected go command: $*" >&2; exit 90; } -printf '%s\n' "${MOCK_GO_VERSION:-go1.26.7}" +printf '%s\n' "${MOCK_GO_VERSION:-go1.26.8}" EOF cat > "${root}/mock-bin/goreleaser" <<'EOF' #!/usr/bin/env bash set -euo pipefail printf 'goreleaser' >> "$MOCK_LOG"; printf ' <%s>' "$@" >> "$MOCK_LOG"; printf '\n' >> "$MOCK_LOG" [[ "$*" == --version ]] || { echo "unexpected goreleaser command: $*" >&2; exit 90; } -printf 'GitVersion: %s\n' "${MOCK_GORELEASER_VERSION:-2.17.1}" +printf 'GitVersion: %s\n' "${MOCK_GORELEASER_VERSION:-2.18.1}" EOF cat > "${root}/mock-bin/gh" <<'EOF' #!/usr/bin/env bash @@ -1759,7 +1760,7 @@ fi EOF printf '# frozen mock helper library\n' > "${root}/mock-bin/lib/mac_release.sh" chmod +x "${root}/mock-bin/"* - write_fixture_producer_tools "$root" go1.26.7 2.17.1 + write_fixture_producer_tools "$root" go1.26.8 2.18.1 } write_fixture_producer_tools() { @@ -1781,7 +1782,7 @@ EOF #!/bin/bash -p set -euo pipefail [[ "$*" == --version ]] || exit 93 -printf 'v26.7.0\n' +printf 'v26.8.2\n' EOF cat > "${root}/mock-bin/expect" <<'EOF' #!/bin/bash -p @@ -1815,15 +1816,15 @@ run_fixture() { hostile_environment+=("${name}=${!name}") fi done - write_fixture_producer_tools "$root" "${MOCK_GO_VERSION:-go1.26.7}" "${MOCK_GORELEASER_VERSION:-2.17.1}" + write_fixture_producer_tools "$root" "${MOCK_GO_VERSION:-go1.26.8}" "${MOCK_GORELEASER_VERSION:-2.18.1}" ( cd "$root" /usr/bin/env -i \ "${hostile_environment[@]}" \ PATH="${root}/mock-bin:/opt/homebrew/bin:/usr/bin:/bin" \ HOME="${root}/home" TMPDIR="${root}/tmp" MOCK_LOG="${root}/mock.log" \ - MOCK_GO_VERSION="${MOCK_GO_VERSION:-go1.26.7}" MOCK_GIT_STATUS="${MOCK_GIT_STATUS:-}" \ - MOCK_GORELEASER_VERSION="${MOCK_GORELEASER_VERSION:-2.17.1}" \ + MOCK_GO_VERSION="${MOCK_GO_VERSION:-go1.26.8}" MOCK_GIT_STATUS="${MOCK_GIT_STATUS:-}" \ + MOCK_GORELEASER_VERSION="${MOCK_GORELEASER_VERSION:-2.18.1}" \ MOCK_ORIGIN="${MOCK_ORIGIN:-https://github.com/openclaw/goplaces}" MOCK_BRANCH="${MOCK_BRANCH:-main}" MOCK_SHA="$SHA" \ MOCK_PROTECTED="${MOCK_PROTECTED:-true}" MOCK_API_SHA="${MOCK_API_SHA:-$SHA}" \ MOCK_FIXTURE_ROOT="$root" MOCK_FRESH_STATUS="${MOCK_FRESH_STATUS:-}" \ @@ -1846,9 +1847,9 @@ test_preflight_and_pilot_mocks() { grep -Fq 'gh <--hostname> <-H> ' "${scratch}/mock.log" || die "preflight did not pin the API host and version" MOCK_GO_VERSION=go1.26.4 expect_failure "old native Go" run_fixture "$scratch" --check - MOCK_GO_VERSION=go1.26.8 expect_failure "future native Go" run_fixture "$scratch" --check + MOCK_GO_VERSION=go1.27.1 expect_failure "newer non-pinned Go" run_fixture "$scratch" --check MOCK_GORELEASER_VERSION=2.15.2 expect_failure "old GoReleaser" run_fixture "$scratch" pilot v0.4.5 - MOCK_GORELEASER_VERSION=2.17.2 expect_failure "future GoReleaser" run_fixture "$scratch" pilot v0.4.5 + MOCK_GORELEASER_VERSION=2.19.0 expect_failure "future GoReleaser" run_fixture "$scratch" pilot v0.4.5 MOCK_GIT_STATUS='?? hostile' expect_failure "dirty checkout" run_fixture "$scratch" --check MOCK_ORIGIN=https://github.com/example/goplaces expect_failure "wrong origin" run_fixture "$scratch" --check MOCK_BRANCH=release expect_failure "wrong branch" run_fixture "$scratch" --check @@ -2092,7 +2093,7 @@ fake_root="$(cd "$(dirname "$0")" && pwd -P)" [[ "${GOWORK:-}" == off ]] || exit 94 printf '%s\n' "$*" >> "${fake_root}/go.log" case "$*" in - 'env GOVERSION') printf 'go1.26.7\n' ;; + 'env GOVERSION') printf 'go1.26.8\n' ;; 'env GOMODCACHE') exit 91 ;; build\ *) output="" diff --git a/scripts/test-reproducible-builds.sh b/scripts/test-reproducible-builds.sh index f87613b..c4682c0 100755 --- a/scripts/test-reproducible-builds.sh +++ b/scripts/test-reproducible-builds.sh @@ -7,7 +7,7 @@ die() { } go_bin="${GO_BIN:-go}" -expected_go_version="go1.26.7" +expected_go_version="go1.26.8" version="${REPRO_VERSION:-0.0.0-repro}" version_symbol="github.com/steipete/goplaces/internal/cli.Version" snapshot_dir="${1:-}" diff --git a/scripts/test-security-ci.sh b/scripts/test-security-ci.sh index 8a77ae4..dd454b2 100755 --- a/scripts/test-security-ci.sh +++ b/scripts/test-security-ci.sh @@ -138,7 +138,7 @@ run_lines = steps.flat_map do |step| end required_runs = [ 'shellcheck_bin="$(./scripts/bootstrap-shellcheck.sh "$RUNNER_TEMP/shellcheck")"', - "go install golang.org/x/vuln/cmd/govulncheck@v1.7.0", + "go install golang.org/x/vuln/cmd/govulncheck@v1.8.0", "./scripts/verify-snapshot-security.sh", "./scripts/test-reproducible-builds.sh dist", "./scripts/test-codesign-macos.sh", @@ -151,8 +151,8 @@ raise "missing active source scan" unless run_lines.any? { |line| line.match?(%r snapshot = steps.find { |step| step["run"].to_s.strip == "./scripts/verify-snapshot-security.sh" } raise "snapshot clean gate missing" unless snapshot&.fetch("env", {})&.fetch("SNAPSHOT_REQUIRE_CLEAN", nil).to_s == "1" -goreleaser = steps.find { |step| step["uses"] == "goreleaser/goreleaser-action@v7" && step.fetch("with", {})["args"] == "release --snapshot --clean --skip=publish --config .goreleaser.yml" } -raise "active GoReleaser snapshot missing" unless goreleaser && goreleaser.fetch("with", {})["version"] == "v2.17.1" +goreleaser = steps.find { |step| step["uses"] == "goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94" && step.fetch("with", {})["args"] == "release --snapshot --clean --skip=publish --config .goreleaser.yml" } +raise "active GoReleaser snapshot missing" unless goreleaser && goreleaser.fetch("with", {})["version"] == "v2.18.1" RUBY } @@ -160,9 +160,9 @@ assert_workflow_proof() { local workflow="$1" local contract_test - require_code_pattern "$workflow" '^[[:space:]]+version:[[:space:]]+v2\.17\.1[[:space:]]*$' "GoReleaser v2.17.1 pin" + require_code_pattern "$workflow" '^[[:space:]]+version:[[:space:]]+v2\.18\.1[[:space:]]*$' "GoReleaser v2.18.1 pin" require_code_pattern "$workflow" '^[[:space:]]+args:[[:space:]]+release --snapshot --clean --skip=publish --config \.goreleaser\.yml[[:space:]]*$' "non-publishing snapshot" - require_code_pattern "$workflow" '^[[:space:]]+run:[[:space:]]+go install golang\.org/x/vuln/cmd/govulncheck@v1\.7\.0[[:space:]]*$' "govulncheck v1.7.0 install" + require_code_pattern "$workflow" '^[[:space:]]+run:[[:space:]]+go install golang\.org/x/vuln/cmd/govulncheck@v1\.8\.0[[:space:]]*$' "govulncheck v1.8.0 install" # shellcheck disable=SC2016 require_code_pattern "$workflow" 'shellcheck_bin="\$\(\./scripts/bootstrap-shellcheck\.sh "\$RUNNER_TEMP/shellcheck"\)"' "pinned ShellCheck bootstrap" require_code_pattern "$workflow" '^[[:space:]]+run:[^#]*govulncheck[^#]*-db=https://vuln\.go\.dev[^#]*-test[[:space:]]+\./\.\.\.[^#]*$' "official-database source vulnerability scan including tests" @@ -468,7 +468,7 @@ cat >> "$scratch/missing-persist.yml" <<'EOF' hostile-checkout: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # persist-credentials: false EOF expect_unsafe_workflow "$scratch/missing-persist.yml" "checkout credential omission" @@ -478,12 +478,12 @@ cat >> "$scratch/indented-missing-persist.yml" <<'EOF' hostile-indented-checkout: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # persist-credentials: false EOF expect_unsafe_workflow "$scratch/indented-missing-persist.yml" "indented checkout credential omission" -awk '{if ($0 ~ /uses: actions\/checkout@v7/) sub(/uses: /, "uses: \&checkout_action "); print}' "$release_workflow" > "$scratch/checkout-anchor.yml" +awk '{if ($0 ~ /uses: actions\/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1/) sub(/uses: /, "uses: \&checkout_action "); print}' "$release_workflow" > "$scratch/checkout-anchor.yml" cat >> "$scratch/checkout-anchor.yml" <<'EOF' hostile-aliased-checkout: runs-on: ubuntu-latest @@ -574,7 +574,7 @@ case "$binary" in *windows_arm64*) goos=windows; goarch=arm64 ;; *) exit 2 ;; esac -toolchain=go1.26.7 +toolchain=go1.26.8 main=github.com/steipete/goplaces/cmd/goplaces if [[ "${MOCK_BUILD_INFO_FAULT:-}" == "toolchain" ]]; then toolchain=go0.0.0; fi if [[ "${MOCK_BUILD_INFO_FAULT:-}" == "main" ]]; then main=example.invalid/hostile; fi diff --git a/scripts/verify-release-assets.sh b/scripts/verify-release-assets.sh index bc31538..6756d7b 100755 --- a/scripts/verify-release-assets.sh +++ b/scripts/verify-release-assets.sh @@ -42,7 +42,7 @@ if [[ -z "$govulncheck_bin" ]]; then govulncheck_bin="$($go_bin env GOPATH)/bin/govulncheck" fi [[ -x "$govulncheck_bin" ]] || die "pinned govulncheck is not executable" -[[ "$($go_bin env GOVERSION)" == go1.26.7 ]] || die "verification requires Go 1.26.7" +[[ "$($go_bin env GOVERSION)" == go1.26.8 ]] || die "verification requires Go 1.26.8" [[ "$(/usr/bin/uname -m)" == "$native_arch" ]] || die "runner architecture does not match native verifier job" sha256_file() { @@ -134,7 +134,7 @@ verify_build_info() { local expected_arch="$3" local info="$scratch/build-info.txt" "$go_bin" version -m "$binary" > "$info" || die "could not read Go build info: $expected_os/$expected_arch" - [[ "$(sed -n '1p' "$info")" == "$binary: go1.26.7" ]] || die "wrong Go toolchain: $expected_os/$expected_arch" + [[ "$(sed -n '1p' "$info")" == "$binary: go1.26.8" ]] || die "wrong Go toolchain: $expected_os/$expected_arch" grep -Fqx $'\tpath\tgithub.com/steipete/goplaces/cmd/goplaces' "$info" || die "wrong main package: $expected_os/$expected_arch" [[ "$(awk -F '\t' -v tag="$tag" '$2 == "mod" && $3 == "github.com/steipete/goplaces" && $4 == tag {count++} END {print count + 0}' "$info")" -eq 1 ]] || die "wrong tagged module version: $expected_os/$expected_arch" diff --git a/scripts/verify-snapshot-security.sh b/scripts/verify-snapshot-security.sh index 1350318..a52b182 100755 --- a/scripts/verify-snapshot-security.sh +++ b/scripts/verify-snapshot-security.sh @@ -93,7 +93,7 @@ scan_binary() { build_info="$($go_bin version -m "$binary")" || die "could not read Go build information: $binary" printf '%s\n' "$build_info" - grep -Eq ': go1\.26\.7$' <<<"$(printf '%s\n' "$build_info" | head -n 1)" || die "wrong Go toolchain in $binary" + grep -Eq ': go1\.26\.8$' <<<"$(printf '%s\n' "$build_info" | head -n 1)" || die "wrong Go toolchain in $binary" grep -Fqx $'\tpath\tgithub.com/steipete/goplaces/cmd/goplaces' <<<"$build_info" || die "wrong main package in $binary" grep -Fqx $'\tbuild\tCGO_ENABLED=0' <<<"$build_info" || die "CGO must be disabled in $binary" grep -Fqx $'\tbuild\tGOOS='"$expected_goos" <<<"$build_info" || die "wrong GOOS in $binary"