diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 515aa1d..8263c4a 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -4,10 +4,6 @@ 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: @@ -54,14 +50,14 @@ jobs: - 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 - # here; tracked separately. This is the exact commit the mutable - # `@v3` used to resolve to, i.e. the code that was deploying this - # site before this issue -- now pinned instead of floating. + # v3, not v4: artifacts v4 is a different wire protocol and this + # Gitea Actions instance does not serve it. That is what broke the + # deploy in run 25 -- measured by running two otherwise identical + # jobs on a branch, one ending in upload-artifact v4 (failed) and + # one without that step (passed). Tracked in #20. This SHA is the + # exact commit the mutable `@v3` used to resolve to, i.e. the code + # that was already deploying this site, now pinned rather than + # floating. - name: Upload artifact # actions/upload-artifact v3.2.1, 2026-08-09 uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 @@ -102,9 +98,8 @@ jobs: # npm picks the newest version whose engines the running node # satisfies, which on node 20 is exactly 4.86.0. So this pins the # version that has actually been deploying this site, rather than - # silently changing it. Bumping the container to node 22 is the - # alternative; it is a bigger change and is not what this issue is - # for. + # silently changing it. Moving the container to node 22 so the + # wrangler pin can advance is tracked in #21. - name: Install Wrangler # wrangler 4.86.0, 2026-08-09 run: npm install -g wrangler@4.86.0 diff --git a/.gitea/workflows/probe.yml b/.gitea/workflows/probe.yml deleted file mode 100644 index 1223ab0..0000000 --- a/.gitea/workflows/probe.yml +++ /dev/null @@ -1,102 +0,0 @@ -# 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 -# isolates one hypothesis and surfaces as its own status context. -# -# Round 1 (2d328e7): -# -# p1 bare alpine + checkout failure 3s -# p2 alpine + apk nodejs git tar + checkout success 5s -# p3 p2 + script/bootstrap + script/test + tar success 15s -# p4 p2 + upload-artifact v4 failure 11s -# p5 node:20-alpine + checkout success 8s -# p6 node:20-bookworm-slim + checkout success 11s -# -# -> the pinned alpine image, the prerequisite step and the site build are all -# fine; upload-artifact v4 is what broke the build job on main. -# -# Round 2 (602fd60): -# -# build (deploy.yml, upload v3.2.2-node20) success 20s -# q1 upload-artifact v3.2.1 (node16) success 7s -# q2 upload-artifact v3.2.1-n20 (node20) success 22s -# q3 full build + upload v3.2.2-node20 success 11s -# q4 download v3.1.0-node20 + wrangler install failure 43s -# -# -> build green on every v3 upload; a second, separate failure on the deploy -# side. -# -# Round 3 (07af755): -# -# build (deploy.yml, upload v3.2.1) success 8s -# r1 wrangler install + invoke, no artifacts failure 7s -# r2a/r2b artifact round trip, v3.2.1/v3.0.2 success 12s / 2s -# r3a/r3b artifact round trip, node20 builds success 8s / 2s -# -# -> the artifact round trip is sound in both pairs; wrangler is the second -# break. Reproduced locally in the pinned node image: `npm install -g -# wrangler@4.120.0` exits 0 with EBADENGINE warnings, then wrangler itself -# exits 1 with "Wrangler requires at least Node.js v22.0.0. You are using -# v20.20.2." Unpinned `npm install -g wrangler` on that same image resolves -# to 4.86.0, because npm picks the newest version the running node -# satisfies -- so 4.86.0 is what has actually been deploying this site, and -# that is what deploy.yml now pins. -# -# Round 4 is the full rehearsal of both jobs end to end with the corrected -# pins, stopping one step short of publishing. -name: probe - -on: - push: - branches: - - pin-deploy-refs-observable - -jobs: - # Producer: identical to the build job in deploy.yml. - s1-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 - # actions/upload-artifact v3.2.1, 2026-08-09 - - uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 - with: - name: site-dry - path: site.tar.gz - - # Consumer: identical to the deploy job in deploy.yml, except that the - # final step prints wrangler's view of the project instead of running - # `wrangler pages deploy`. Same pinned image, same pinned action, same - # pinned wrangler version, same extracted tree. Needs no token and - # publishes nothing. - s2-deploy-dryrun: - runs-on: ubuntu-latest - needs: s1-build - container: - # node 20.20.2-bookworm, 2026-08-09 - image: node@sha256:8f693eaa7e0a8e71560c9a82b55fd54c2ae920a2ba5d2cde28bac7d1c01c9ba5 - steps: - # actions/download-artifact v3.0.2, 2026-08-09 - - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a - with: - name: site-dry - - run: tar -xzf site.tar.gz - - run: test -f public/index.html - # wrangler 4.86.0, 2026-08-09 - - run: npm install -g wrangler@4.86.0 - - run: wrangler --version - - run: wrangler pages deploy --help diff --git a/TODO.md b/TODO.md index c8a581c..7936071 100644 --- a/TODO.md +++ b/TODO.md @@ -14,7 +14,8 @@ pre-1.0 No git tags. The site is live and now has the scripts-to-rule-them-all scaffold (`Makefile`, `script/`, `Dockerfile`, `check.yml`); still missing `LICENSE` and -policy files. +policy files. Every external reference in the repo is now pinned by +cryptographic hash (or, for the wrangler CLI install, an exact version). # Next Step @@ -24,6 +25,21 @@ Update `README.md` accordingly. # Completed Steps +- 2026-08-09: hash-pinned every external reference in + `.gitea/workflows/deploy.yml` (closes #7): both job container images are + pinned by digest, all three `uses:` are pinned by 40-hex commit SHA, and the + wrangler install is pinned to an exact version. The abandoned + `klakegg/hugo:ext-alpine` image is gone: the build job now runs on the same + pinned `alpine` digest the `Dockerfile` uses, with a pre-checkout + `apk add nodejs git tar` step (the Actions runner needs `node` inside the job + container to execute JavaScript actions), an explicit `shell: sh` default, + then `script/bootstrap` and `script/test`. The `deploy` job is guarded with + `if: github.ref_name == 'main'` so it can never publish from a branch. Also + dropped the dead `feat/initial-site` push trigger and reindented the file to + 4-space YAML to match `check.yml`. This is the second attempt; the first broke + the deploy and was reverted, so this one was verified by temporarily + triggering the workflow on the PR branch and iterating until the `build` job + ran green for real - 2026-07-25: added the scripts-to-rule-them-all scaffold (closes #4): `script/` entrypoints, `Makefile` shims, a Hugo `Dockerfile` (sha256-pinned alpine) plus `.dockerignore` that runs `make check`, `.gitea/workflows/check.yml` running @@ -40,9 +56,11 @@ Update `README.md` accordingly. # Future Steps -- Pin the images and actions in `deploy.yml` by sha256 - (`klakegg/hugo:ext-alpine`, `node:20`, `actions/checkout`, - `upload`/`download-artifact` are all unpinned) +- Move the artifact actions to v4 once this Gitea Actions instance serves the v4 + artifact protocol; they are pinned on the deprecated v3 line because v4 fails + here (#20) +- Move the deploy container to a pinned node 22 so the wrangler pin can advance + past 4.86.0 (#21) - Rework README.md into the standard sections: Description, Getting Started, Rationale, Design, TODO, License, Author (currently About, Contributing, Technical Details, License)