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.
This commit is contained in:
Amruth Pillai
2026-09-28 09:01:00 +02:00
parent 328bf73cee
commit a7f1829484
9 changed files with 98 additions and 22 deletions
+1
View File
@@ -1,4 +1,5 @@
self-hosted-runner:
labels:
- blacksmith-2vcpu-ubuntu-2404
- blacksmith-32vcpu-ubuntu-2404
- blacksmith-32vcpu-ubuntu-2404-arm
+6 -1
View File
@@ -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
+9 -1
View File
@@ -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:
+40 -9
View File
@@ -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 }}
- &registries
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"
+8 -1
View File
@@ -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
+8 -1
View File
@@ -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:
+1 -1
View File
@@ -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
+14 -4
View File
@@ -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
+11 -4
View File
@@ -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 |
| --- | --- | --- |