From a7f1829484438d9e888d2276bc11320f2b382b8f Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Mon, 28 Sep 2026 09:01:00 +0200 Subject: [PATCH] ci: default to GitHub-hosted runners with opt-in Blacksmith Workflows now run on GitHub-hosted runners unless the repository variable USE_BLACKSMITH is "true", so forks work without setup. When enabled, jobs run on Blacksmith runners (32 vCPU for build/test, 2 vCPU for lightweight jobs) and use useblacksmith/checkout, useblacksmith/setup-docker-builder, and useblacksmith/build-push-action. Docker layer caches are keyed per architecture. Replaces the CI_RUNNER_X64 and CI_RUNNER_ARM64 variables. --- .github/actionlint.yaml | 1 + .github/workflows/autofix.yml | 7 ++++- .github/workflows/crowdin-sync.yml | 10 +++++- .github/workflows/docker-build.yml | 49 +++++++++++++++++++++++------ .github/workflows/e2e.yml | 9 +++++- .github/workflows/label-issues.yml | 9 +++++- .github/workflows/stale-issues.yml | 2 +- .github/workflows/vercel.yml | 18 ++++++++--- docs/agents/container-publishing.md | 15 ++++++--- 9 files changed, 98 insertions(+), 22 deletions(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index ee89a24ae..331742e03 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -1,4 +1,5 @@ self-hosted-runner: labels: + - blacksmith-2vcpu-ubuntu-2404 - blacksmith-32vcpu-ubuntu-2404 - blacksmith-32vcpu-ubuntu-2404-arm diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 5dc2891b8..6ce7a879e 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -13,12 +13,17 @@ env: jobs: autofix: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-32vcpu-ubuntu-2404' || 'ubuntu-latest' }} steps: - name: Checkout Repository + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: actions/checkout@v6 + - name: Checkout Repository (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 + - name: Check for merge conflict markers run: | if git grep -nEI '<{7} |>{7} |^={7}$' -- ':(exclude)*.md' ':(exclude)*.mdx'; then diff --git a/.github/workflows/crowdin-sync.yml b/.github/workflows/crowdin-sync.yml index 7bc809728..8cff6f5d5 100644 --- a/.github/workflows/crowdin-sync.yml +++ b/.github/workflows/crowdin-sync.yml @@ -10,7 +10,7 @@ concurrency: jobs: crowdin-sync: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} permissions: contents: write @@ -18,8 +18,16 @@ jobs: steps: - name: Checkout Repository + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: actions/checkout@v6 + # The Crowdin action runs in a container that cannot reach the git mirror mount, so copy its objects. + - name: Checkout Repository (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 + with: + dissociate: true + - name: Sync Translations from Crowdin uses: crowdin/github-action@v2 with: diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index da9ef64c0..3da8ab025 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -24,7 +24,7 @@ env: jobs: mode: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} outputs: nightly: ${{ steps.mode.outputs.nightly }} @@ -61,10 +61,10 @@ jobs: matrix: include: - platform: linux/amd64 - runner: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runner: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-32vcpu-ubuntu-2404' || 'ubuntu-latest' }} arch: amd64 - platform: linux/arm64 - runner: ${{ vars.CI_RUNNER_ARM64 || 'ubuntu-24.04-arm' }} + runner: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-32vcpu-ubuntu-2404-arm' || 'ubuntu-24.04-arm' }} arch: arm64 runs-on: ${{ matrix.runner }} @@ -78,11 +78,24 @@ jobs: steps: - name: Checkout Repository + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: actions/checkout@v6 + - name: Checkout Repository (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 + - name: Setup Docker Buildx + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: docker/setup-buildx-action@v4 + # Persists BuildKit layers and the Dockerfile's pnpm cache mounts between runs, one cache per architecture. + - name: Setup Docker Builder (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/setup-docker-builder@v2 + with: + cache-key: Dockerfile-${{ matrix.arch }} + - ®istries name: Determine registries id: registries @@ -133,17 +146,23 @@ jobs: type=sha,prefix=sha-,suffix=-${{ matrix.arch }} - name: Cache-only smoke build - if: ${{ needs.mode.outputs.canary == 'true' }} + if: ${{ needs.mode.outputs.canary == 'true' && vars.USE_BLACKSMITH != 'true' }} uses: docker/build-push-action@v7 - with: + with: &cache-only-build context: . platforms: ${{ matrix.platform }} outputs: type=cacheonly + - name: Cache-only smoke build (Blacksmith) + if: ${{ needs.mode.outputs.canary == 'true' && vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/build-push-action@v2 + with: *cache-only-build + - name: Build and Push by Digest id: build + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: docker/build-push-action@v7 - with: + with: &build-push context: . sbom: true push: true @@ -153,10 +172,16 @@ jobs: labels: ${{ steps.meta.outputs.labels }} annotations: ${{ steps.meta.outputs.annotations }} + - name: Build and Push by Digest (Blacksmith) + id: build-blacksmith + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/build-push-action@v2 + with: *build-push + - name: Export digest run: | mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" + digest="${{ steps.build.outputs.digest || steps.build-blacksmith.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - name: Upload digest @@ -172,7 +197,7 @@ jobs: - mode - build timeout-minutes: 30 - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} env: DEPLOY: ${{ secrets.SSH_KEY != '' && secrets.SSH_HOST != '' && secrets.SSH_USER != '' }} @@ -186,11 +211,17 @@ jobs: steps: - name: Checkout Repository + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: actions/checkout@v6 - with: + with: &checkout-package-json sparse-checkout: package.json sparse-checkout-cone-mode: false + - name: Checkout Repository (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 + with: *checkout-package-json + - name: Get version from package.json id: version run: echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ac174a909..f6fd778bb 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -20,7 +20,7 @@ env: jobs: e2e: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-32vcpu-ubuntu-2404' || 'ubuntu-latest' }} timeout-minutes: 30 services: @@ -40,10 +40,17 @@ jobs: steps: - name: Checkout Repository + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: actions/checkout@v6 with: persist-credentials: false + - name: Checkout Repository (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 + with: + persist-credentials: false + - name: Install pnpm uses: pnpm/action-setup@v6 diff --git a/.github/workflows/label-issues.yml b/.github/workflows/label-issues.yml index f58ef2135..2f72f1bdc 100644 --- a/.github/workflows/label-issues.yml +++ b/.github/workflows/label-issues.yml @@ -10,14 +10,21 @@ permissions: jobs: label: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} steps: - name: Checkout Repository + if: ${{ vars.USE_BLACKSMITH != 'true' }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false + - name: Checkout Repository (Blacksmith) + if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 + with: + persist-credentials: false + - name: Apply Form Labels uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml index 600ace5ed..7210e6f1a 100644 --- a/.github/workflows/stale-issues.yml +++ b/.github/workflows/stale-issues.yml @@ -10,7 +10,7 @@ permissions: jobs: stale: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} steps: - name: Close Inactive Issues Awaiting Information diff --git a/.github/workflows/vercel.yml b/.github/workflows/vercel.yml index 6e5a3b5ef..5593c0035 100644 --- a/.github/workflows/vercel.yml +++ b/.github/workflows/vercel.yml @@ -14,7 +14,7 @@ env: jobs: artifact: - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-32vcpu-ubuntu-2404' || 'ubuntu-latest' }} timeout-minutes: 20 services: postgres: @@ -36,7 +36,12 @@ jobs: VERCEL: "1" VERCEL_ENV: production steps: - - uses: actions/checkout@v6 + - if: ${{ vars.USE_BLACKSMITH != 'true' }} + uses: actions/checkout@v6 + with: + persist-credentials: false + - if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 with: persist-credentials: false - uses: pnpm/action-setup@v6 @@ -81,11 +86,16 @@ jobs: live-smoke: if: github.event_name == 'workflow_dispatch' - runs-on: ${{ vars.CI_RUNNER_X64 || 'ubuntu-latest' }} + runs-on: ${{ vars.USE_BLACKSMITH == 'true' && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }} environment: vercel-smoke timeout-minutes: 10 steps: - - uses: actions/checkout@v6 + - if: ${{ vars.USE_BLACKSMITH != 'true' }} + uses: actions/checkout@v6 + with: + persist-credentials: false + - if: ${{ vars.USE_BLACKSMITH == 'true' }} + uses: useblacksmith/checkout@v1 with: persist-credentials: false - uses: actions/setup-node@v6 diff --git a/docs/agents/container-publishing.md b/docs/agents/container-publishing.md index 68725c90c..fffb40c1d 100644 --- a/docs/agents/container-publishing.md +++ b/docs/agents/container-publishing.md @@ -7,10 +7,17 @@ The repository is `reactive-resume/reactive-resume`. Docker Hub remains ## Builds and release safety `.github/workflows/docker-build.yml` builds AMD64 and ARM64 on matching native runners. -Repository variables `CI_RUNNER_X64` and `CI_RUNNER_ARM64` select the runner labels; -they default to `ubuntu-latest` and `ubuntu-24.04-arm`, respectively. Other CI workflows -also use `CI_RUNNER_X64`. Docker Buildx shares its local cache between steps within a job; -no cache is persisted between workflow runs. +All workflows run on GitHub-hosted runners (`ubuntu-latest`, `ubuntu-24.04-arm`) by default, +so forks work without setup. Setting the repository variable `USE_BLACKSMITH=true` switches +every job to Blacksmith runners (32 vCPU for build/test jobs, 2 vCPU for lightweight jobs) and +swaps in `useblacksmith/checkout`, `useblacksmith/setup-docker-builder`, and +`useblacksmith/build-push-action`. Because `uses:` cannot be an expression, each swapped +action is a pair of steps gated on the variable; keep both halves in sync when editing. + +On GitHub-hosted runners, Docker Buildx shares its local cache between steps within a job and +no cache is persisted between workflow runs. On Blacksmith, the builder persists layers and the +Dockerfile's pnpm cache mounts between runs, keyed per architecture (`Dockerfile-amd64`, +`Dockerfile-arm64`). | Trigger | Published aliases | Production deployment | | --- | --- | --- |