From affd72517ae01ae44ef4dfcb9cb70b55af645a23 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 24 Oct 2026 16:57:48 -0300 Subject: [PATCH 1/4] ci: GitHub's runners devcontainer-cli is public: GitHub's standard runners are free there and have 4 vCPU, the Blacksmith size every job ran on (659 Blacksmith minutes in October). The release's buildx builder is Docker's own action; nothing here kept state between runs. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/go-cli.yml | 16 ++++++++-------- .github/workflows/release.yml | 15 +++++++-------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/go-cli.yml b/.github/workflows/go-cli.yml index d208e52..77e43aa 100644 --- a/.github/workflows/go-cli.yml +++ b/.github/workflows/go-cli.yml @@ -21,7 +21,7 @@ permissions: jobs: lint-and-test: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest permissions: contents: read steps: @@ -51,7 +51,7 @@ jobs: if-no-files-found: error e2e: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: lint-and-test steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -75,7 +75,7 @@ jobs: # Hermetic parity gate: read-configuration golden comparison + the contract # lane of the parity matrix (flag validation / output contract, no Docker). parity: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: lint-and-test steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -123,7 +123,7 @@ jobs: # on quiet days. Runs on schedule/dispatch so the daily lanes' `needs:` is satisfied. daily-changes: if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest outputs: run: ${{ steps.check.outputs.run }} steps: @@ -153,7 +153,7 @@ jobs: && needs.lint-and-test.result == 'success' && (github.event_name == 'push' || github.event_name == 'pull_request' || needs.daily-changes.outputs.run == 'true') - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: @@ -220,7 +220,7 @@ jobs: parity-publish-full: needs: [lint-and-test, daily-changes] if: needs.daily-changes.outputs.run == 'true' - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: @@ -246,7 +246,7 @@ jobs: # publish) into the one true cross-lane number. parity-runtime-gate: if: always() - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: [lint-and-test, e2e, parity, parity-runtime, parity-publish-full] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -276,7 +276,7 @@ jobs: run: go tool task parity:gate cross-compile: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: lint-and-test steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 485831b..4214675 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: # exists; on dispatch we compute the version and validate the tag is free, but # DO NOT tag yet (the `tag` job below tags only after the gates pass). prepare: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest outputs: version: ${{ steps.resolve.outputs.version }} tag: ${{ steps.resolve.outputs.tag }} @@ -48,7 +48,7 @@ jobs: # Hermetic gates — the same task targets CI runs on every push/PR. # The release is blocked unless these pass. gate: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: prepare steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -78,7 +78,7 @@ jobs: # Runtime lane (real Docker containers). ubuntu-latest ships Docker. gate-runtime: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: prepare steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -116,7 +116,7 @@ jobs: # skipped (the tag already exists). The GITHUB_TOKEN push does not re-trigger the # workflow, so there is no second run. tag: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: [prepare, gate, gate-runtime] if: github.event_name == 'workflow_dispatch' steps: @@ -133,7 +133,7 @@ jobs: run: go tool task release:tag goreleaser: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: [prepare, gate, gate-runtime, tag] # `tag` is skipped on the push path, so gate on explicit success/skip rather # than the default all-succeeded semantics. @@ -166,8 +166,7 @@ jobs: # Multi-arch image build (arm64 emulated) + buildx driver for the # dockers:/docker_manifests: blocks in .goreleaser.yml. - uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4 - - name: Setup Blacksmith Builder - uses: useblacksmith/setup-docker-builder@19215110ab936351210feebdfa5b440b4493e184 # v2 + - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 # GHCR login. Only reached on the tag path (this workflow is push.tags), # never on PRs, so images are pushed exclusively from an approved tag run. @@ -216,7 +215,7 @@ jobs: # Non-gating: perf/distribution metrics recorded per release, never blocks. metrics: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest needs: [prepare, goreleaser] continue-on-error: true steps: From 8f545b59882e86af6999a21a9007dea671874da3 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 24 Oct 2026 17:28:54 -0300 Subject: [PATCH 2/4] ci: bake's filesystem entitlement off for the parity runtime The TS reference builds a compose service from a Dockerfile it writes under /tmp, outside the build context; bake on buildx 0.38 (GitHub's runner image) refuses that without --allow=fs.read, which the reference never passes, and every compose case read as a divergence (run 40127656115). Confirmed on the runner: the same build passes with BUILDX_BAKE_ENTITLEMENTS_FS=0 (run 40129625428). Co-Authored-By: Claude Fable 5.1 --- .github/actions/setup-parity-runtime/action.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/actions/setup-parity-runtime/action.yml b/.github/actions/setup-parity-runtime/action.yml index b606a1a..c9d31e2 100644 --- a/.github/actions/setup-parity-runtime/action.yml +++ b/.github/actions/setup-parity-runtime/action.yml @@ -22,5 +22,14 @@ runs: # the Taskfile so the runner prep is identical to release.yml. - run: go tool task ci:prepare-runner shell: bash + # The TS reference builds a compose service from a Dockerfile it writes under + # /tmp, outside the build context. Compose builds through bake, and bake on + # buildx 0.38 (GitHub's runner image, 2026-10-24) refuses to read a file + # outside the context unless the caller passes --allow=fs.read, which the + # reference never does: every compose case failed with "additional + # privileges requested". The Go CLI passes the entitlement itself. Off for + # the whole job, so both sides build the same way. + - run: echo "BUILDX_BAKE_ENTITLEMENTS_FS=0" >> "$GITHUB_ENV" + shell: bash - run: go tool task reference shell: bash From 75f195f7f1145d178cf71860595f135544020c8f Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 24 Oct 2026 17:29:37 -0300 Subject: [PATCH 3/4] ci: the release's runtime gate builds as the parity lane does Co-Authored-By: Claude Fable 5.1 --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4214675..1c96f1b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,6 +100,8 @@ jobs: # Reuse the same runner prep as the go-cli.yml runtime job, or a tagged # release stalls on a default-driver runner. - run: go tool task ci:prepare-runner + # Bake's filesystem entitlement off, as .github/actions/setup-parity-runtime says why. + - run: echo "BUILDX_BAKE_ENTITLEMENTS_FS=0" >> "$GITHUB_ENV" - run: go tool task reference - run: go tool task test:e2e From 016b49a18a86006b8e46cb696095b10f12b08db4 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 24 Oct 2026 17:33:39 -0300 Subject: [PATCH 4/4] ci: bake's entitlement is the runner prep task's A step is one task (taskgate); ci:prepare-runner is where the runner is made ready for the parity lane, on both workflows. Co-Authored-By: Claude Fable 5.1 --- .github/actions/setup-parity-runtime/action.yml | 14 +++----------- .github/workflows/release.yml | 2 -- Taskfile.yml | 9 ++++++++- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/actions/setup-parity-runtime/action.yml b/.github/actions/setup-parity-runtime/action.yml index c9d31e2..8ee5eaf 100644 --- a/.github/actions/setup-parity-runtime/action.yml +++ b/.github/actions/setup-parity-runtime/action.yml @@ -18,18 +18,10 @@ runs: - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 with: node-version: "24" - # Free disk + enable the containerd image store (build-cache export). Reuses - # the Taskfile so the runner prep is identical to release.yml. + # Free disk, enable the containerd image store (build-cache export) and turn + # bake's filesystem entitlement off. Reuses the Taskfile so the runner prep + # is identical to release.yml. - run: go tool task ci:prepare-runner shell: bash - # The TS reference builds a compose service from a Dockerfile it writes under - # /tmp, outside the build context. Compose builds through bake, and bake on - # buildx 0.38 (GitHub's runner image, 2026-10-24) refuses to read a file - # outside the context unless the caller passes --allow=fs.read, which the - # reference never does: every compose case failed with "additional - # privileges requested". The Go CLI passes the entitlement itself. Off for - # the whole job, so both sides build the same way. - - run: echo "BUILDX_BAKE_ENTITLEMENTS_FS=0" >> "$GITHUB_ENV" - shell: bash - run: go tool task reference shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c96f1b..4214675 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,8 +100,6 @@ jobs: # Reuse the same runner prep as the go-cli.yml runtime job, or a tagged # release stalls on a default-driver runner. - run: go tool task ci:prepare-runner - # Bake's filesystem entitlement off, as .github/actions/setup-parity-runtime says why. - - run: echo "BUILDX_BAKE_ENTITLEMENTS_FS=0" >> "$GITHUB_ENV" - run: go tool task reference - run: go tool task test:e2e diff --git a/Taskfile.yml b/Taskfile.yml index 2effcaa..2524a29 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -322,9 +322,16 @@ tasks: - go test ./internal/cli -run TestPublishParity -count=1 -timeout 10m -v ci:prepare-runner: - desc: "CI-ONLY: free disk + enable the containerd image store (uses sudo; not for local dev)" + desc: "CI-ONLY: free disk + enable the containerd image store + bake's fs entitlement off (uses sudo; not for local dev)" cmds: - go run ./cmd/devtool ci-prepare-runner + # The TS reference builds a compose service from a Dockerfile it writes under /tmp, + # outside the build context. Compose builds through bake, and bake on buildx 0.38 + # (GitHub's runner image, 2026-10-24) refuses to read a file outside the context unless + # the caller passes --allow=fs.read, which the reference never does: every compose case + # failed with "additional privileges requested" while the Go CLI, which passes the + # entitlement itself, succeeded. Off for the whole job, so both sides build the same way. + - echo "BUILDX_BAKE_ENTITLEMENTS_FS=0" >> "${GITHUB_ENV:-/dev/null}" ci:daily-changes: desc: "Whether the daily lanes run (run= to $GITHUB_OUTPUT, or the terminal): always on a manual dispatch, else only when HEAD changed in the last day"