Some checks failed
check / check (push) Successful in 6s
Build and Deploy to Cloudflare Pages / build (push) Successful in 20s
probe / q1-upload-v3-node16 (push) Successful in 7s
probe / q2-upload-v3-node20 (push) Successful in 22s
probe / q3-build-for-roundtrip (push) Successful in 11s
Build and Deploy to Cloudflare Pages / deploy (push) Has been skipped
probe / q4-deploy-dryrun (push) Failing after 43s
Round 1 of the branch probes reproduced the main failure and localised it.
Observed commit-status output for 2d328e7:
check / check success 10s
Build and Deploy .../ build failure 15s <- reproduced
Build and Deploy .../ deploy skipped <- if: guard working
probe / p1-bare-alpine-checkout failure 3s
probe / p2-alpine-apk-checkout success 5s
probe / p3-alpine-apk-build success 15s
probe / p4-alpine-apk-upload failure 11s
probe / p5-node20alpine-checkout success 8s
probe / p6-node20slim-checkout success 11s
Reading that:
- p1 vs p2: act_runner does not supply node for JavaScript actions, so the
`apk add --no-cache nodejs git tar` prerequisite step is genuinely required
and genuinely sufficient. checkout then runs on musl.
- p3: script/bootstrap and script/test complete inside the Actions container
on the pinned alpine digest. The mandated image replacement was never the
problem.
- p2 vs p4: the only difference is a trailing upload-artifact v4 step, and it
is the difference between success and failure.
- p5/p6: musl is not the issue -- checkout runs on both musl and glibc images.
So what broke the deploy was not the image swap that everyone reviewed, it was
the v3 -> v4 artifact bump that nobody questioned. Gitea 1.25.4's artifact
backend and this runner do not serve the v4 protocol; the workflow used v3
before this issue and that is what worked.
The artifact actions therefore move back to the v3 line, still pinned by full
commit SHA, which satisfies the hash-pinning requirement this issue is actually
about. Both are the node20 builds rather than the node16 defaults, so nothing
depends on a node16 runtime:
- upload-artifact -> c6a3b2bd (v3.2.2-node20)
- download-artifact -> ad191675 (v3.1.0-node20)
Round 2 probes: the two fallback v3 builds in case the node20 ones do not
resolve, plus a producer/consumer pair that rehearses the deploy job -- same
pinned node image, same pinned download action, same pinned wrangler version,
stopping short of `wrangler pages deploy` so it touches nothing external.
103 lines
4.6 KiB
YAML
103 lines
4.6 KiB
YAML
name: Build and Deploy to Cloudflare Pages
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
# TEMPORARY: development-only trigger so the build job actually
|
|
# executes under act_runner before this reaches main. Removed in
|
|
# the final commit.
|
|
- pin-deploy-refs-observable
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
# Same digest the Dockerfile pins: one pinned base image and the
|
|
# same dependency list (script/bootstrap) for both the check build
|
|
# and the deploy build. The one extra thing this job needs on top
|
|
# of the Dockerfile is the Actions runner's own prerequisites --
|
|
# see the first step.
|
|
# alpine 3.21, 2026-02-28
|
|
image: alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
|
|
defaults:
|
|
run:
|
|
# The default step shell is bash; this image has only busybox
|
|
# sh, so say so explicitly rather than rely on a fallback.
|
|
shell: sh
|
|
steps:
|
|
# This image is bare busybox+musl. act_runner executes JavaScript
|
|
# actions (checkout, upload-artifact) with `node` *inside* the job
|
|
# container and does not inject one, so node has to exist before
|
|
# the first `uses:` step -- script/bootstrap runs too late. git is
|
|
# needed for checkout's `submodules: recursive` (without it
|
|
# checkout degrades to a tarball download that cannot do
|
|
# submodules). An inline `run:` needs only a shell, so this step
|
|
# works on the bare image. These apk packages resolve at run time
|
|
# and are not hash-pinned; that gap is repo-wide (script/bootstrap
|
|
# has it too) and is tracked in #19.
|
|
- name: Install runner prerequisites
|
|
run: apk add --no-cache nodejs git tar
|
|
|
|
- name: Checkout
|
|
# actions/checkout v4.2.2, 2026-02-28
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install build dependencies
|
|
run: script/bootstrap
|
|
|
|
- name: Build site
|
|
run: script/test
|
|
|
|
- name: Archive site
|
|
run: tar -czf site.tar.gz public
|
|
|
|
# v4 does not work on this Gitea Actions instance -- it is what
|
|
# broke the deploy in run 25. Measured on this branch: a job
|
|
# identical to this one but ending in upload-artifact v4 fails,
|
|
# while the same job without that step passes. So this stays on
|
|
# the v3 line, pinned, using the node20 build of it rather than
|
|
# the node16 default. Revisit when the artifact v4 protocol works
|
|
# here; tracked separately.
|
|
- name: Upload artifact
|
|
# actions/upload-artifact v3.2.2-node20, 2026-08-09
|
|
uses: actions/upload-artifact@c6a3b2bd78b3985e4b2f15397fec357f0fd808de
|
|
with:
|
|
name: site
|
|
path: site.tar.gz
|
|
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
needs: build
|
|
# Publishing guard. This job spends CLOUDFLARE_API_TOKEN and creates a
|
|
# real Cloudflare Pages deployment, so it must never run off main --
|
|
# not even if a branch is added to the push trigger above, deliberately
|
|
# or by accident. Costs one line; the build job stays exercisable from
|
|
# a branch without this job touching anything external.
|
|
if: github.ref_name == 'main'
|
|
container:
|
|
# node 20.20.2-bookworm, 2026-08-09
|
|
image: node@sha256:8f693eaa7e0a8e71560c9a82b55fd54c2ae920a2ba5d2cde28bac7d1c01c9ba5
|
|
steps:
|
|
# Must match the upload-artifact major above -- v4 artifacts and
|
|
# v3 artifacts are different protocols and do not interoperate.
|
|
- name: Download artifact
|
|
# actions/download-artifact v3.1.0-node20, 2026-08-09
|
|
uses: actions/download-artifact@ad191675b41f6a5b46da9a048cb6893812da158b
|
|
with:
|
|
name: site
|
|
|
|
- name: Extract site
|
|
run: tar -xzf site.tar.gz
|
|
|
|
- name: Install Wrangler
|
|
# wrangler 4.120.0, 2026-08-09
|
|
run: npm install -g wrangler@4.120.0
|
|
|
|
- name: Deploy to Cloudflare Pages
|
|
run: wrangler pages deploy public --project-name=lora-vegas --branch=${{ github.ref_name }}
|
|
env:
|
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|