Re-apply deploy.yml pinning behind a deploy guard, and probe the failure
Some checks failed
check / check (push) Successful in 10s
Build and Deploy to Cloudflare Pages / build (push) Failing after 15s
probe / p1-bare-alpine-checkout (push) Failing after 3s
probe / p2-alpine-apk-checkout (push) Successful in 5s
probe / p3-alpine-apk-build (push) Successful in 15s
probe / p4-alpine-apk-upload (push) Failing after 11s
probe / p5-node20alpine-checkout (push) Successful in 8s
probe / p6-node20slim-checkout (push) Successful in 11s
Build and Deploy to Cloudflare Pages / deploy (push) Has been skipped

Restores the hash-pinning work reverted in 3d17e22 (originally 3f91a7c and
b157bfd) verbatim -- all six pinned values were independently re-resolved and
confirmed correct twice, so they are reused, not re-derived.

What is different this time is that the path is observable before it reaches
main. The previous attempt broke the deploy because deploy.yml triggers only on
push to main, so every pre-merge check simulated the runner instead of being
it, and two adversarial reviews could not catch what neither could execute.

Three changes on top of the restored work:

- A temporary development-only branch trigger on on.push.branches, so the
  build job actually executes under act_runner. Removed before merge.
- if: github.ref_name == 'main' on the deploy job. Without it, a branch push
  would run wrangler pages deploy against the real Cloudflare project with the
  real token on every iteration. This guard is permanent: it is one line and it
  makes any future branch trigger, deliberate or accidental, unable to reach
  Cloudflare.
- A temporary .gitea/workflows/probe.yml, also deleted before merge. The
  Actions jobs and logs API is not readable by this account; the commit-status
  API is, and it reports one entry per job. So the diagnosis is encoded as job
  topology rather than log output: six jobs, each isolating one hypothesis
  about the 22s failure (bare alpine vs apk prerequisites, checkout vs site
  build vs artifact upload, musl node vs glibc node), each surfacing as its own
  status context so a single push tests them all in parallel.

make check is green. No pinned value is touched.
This commit is contained in:
2026-08-09 02:46:29 +00:00
parent 3d17e22385
commit 2d328e759b
2 changed files with 191 additions and 40 deletions

View File

@@ -1,52 +1,93 @@
name: Build and Deploy to Cloudflare Pages
on:
push:
branches:
- feat/initial-site
- main
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:
image: klakegg/hugo:ext-alpine
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
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: Build site
run: hugo --minify
- name: Checkout
# actions/checkout v4.2.2, 2026-02-28
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
submodules: recursive
- name: Archive site
run: tar -czf site.tar.gz public
- name: Install build dependencies
run: script/bootstrap
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: site
path: site.tar.gz
- name: Build site
run: script/test
deploy:
runs-on: ubuntu-latest
needs: build
container:
image: node:20
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: site
- name: Archive site
run: tar -czf site.tar.gz public
- name: Extract site
run: tar -xzf site.tar.gz
- name: Upload artifact
# actions/upload-artifact v4.6.2, 2026-08-09
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: site
path: site.tar.gz
- name: Install Wrangler
run: npm install -g wrangler
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:
- name: Download artifact
# actions/download-artifact v4.3.0, 2026-08-09
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: site
- 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 }}
- 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 }}

110
.gitea/workflows/probe.yml Normal file
View File

@@ -0,0 +1,110 @@
# TEMPORARY diagnostic workflow. Deleted before this branch is merged.
#
# The Actions jobs/logs API is not readable by this account, so the only
# available signal is the commit-status API, which reports one entry per
# *job*. This file therefore encodes the diagnosis as job topology: each job
# below isolates exactly one hypothesis about why the pinned-alpine build job
# failed after 22s on main (run 25), and each shows up as its own status
# context, so one push tests them all in parallel.
name: probe
on:
push:
branches:
- pin-deploy-refs-observable
jobs:
# Control. If this passes, act_runner supplies its own node for JS actions
# and the whole "install node first" theory is wrong.
p1-bare-alpine-checkout:
runs-on: ubuntu-latest
container:
# alpine 3.21, 2026-02-28
image: alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
steps:
# actions/checkout v4.2.2, 2026-02-28
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# Exactly the reverted prefix: apk prerequisites, then checkout. Isolates
# checkout from everything downstream of it.
p2-alpine-apk-checkout:
runs-on: ubuntu-latest
container:
# alpine 3.21, 2026-02-28
image: alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
defaults:
run:
shell: sh
steps:
- run: apk add --no-cache nodejs git tar
# actions/checkout v4.2.2, 2026-02-28
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
submodules: recursive
# p2 plus the site build. Isolates script/bootstrap and script/test inside
# the Actions container from the JS-action machinery.
p3-alpine-apk-build:
runs-on: ubuntu-latest
container:
# alpine 3.21, 2026-02-28
image: alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
defaults:
run:
shell: sh
steps:
- run: apk add --no-cache nodejs git tar
# actions/checkout v4.2.2, 2026-02-28
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
submodules: recursive
- run: script/bootstrap
- run: script/test
- run: tar -czf site.tar.gz public
# p2 plus the artifact upload. This is the one step whose protocol changed
# in this issue (v3 -> v4) and the ~22s timing is consistent with reaching
# it.
p4-alpine-apk-upload:
runs-on: ubuntu-latest
container:
# alpine 3.21, 2026-02-28
image: alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
defaults:
run:
shell: sh
steps:
- run: apk add --no-cache nodejs git tar
# actions/checkout v4.2.2, 2026-02-28
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- run: tar -czf probe4.tar.gz hugo.toml
# actions/upload-artifact v4.6.2, 2026-08-09
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: probe4
path: probe4.tar.gz
# Fallback image direction, measured rather than assumed: an image that
# already carries node.
p5-node20alpine-checkout:
runs-on: ubuntu-latest
container:
# node 20-alpine, 2026-08-09
image: node@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293
defaults:
run:
shell: sh
steps:
# actions/checkout v4.2.2, 2026-02-28
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# The glibc control. If musl node is the problem, this passes where the
# alpine jobs do not.
p6-node20slim-checkout:
runs-on: ubuntu-latest
container:
# node 20-bookworm-slim, 2026-08-09
image: node@sha256:2cf067cfed83d5ea958367df9f966191a942351a2df77d6f0193e162b5febfc0
steps:
# actions/checkout v4.2.2, 2026-02-28
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683