diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index e6a5c9a4..577b5b45 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -245,14 +245,20 @@ jobs: # Tag pushes only — android-release just produced this. Non-tag # builds take the "Bundle latest release APK" path below instead. if: steps.guard.outputs.ready == 'true' && startsWith(github.ref, 'refs/tags/v') - # Consuming half of the pair — must match the upload's protocol, so it - # uses the download mirror, never actions/download-artifact. Same fork, + # Consuming half of the pair — never actions/download-artifact. Same fork, # same reason: upstream's client-side GHES check rejects this hostname # before it connects. bvandeusen/download-artifact mirrors - # code.forgejo.org/forgejo/download-artifact; SHA below is its `v5` tag, - # the major matching the upload pin. Pinned, not tagged — the mirror - # auto-syncs every 8h and a moved tag would change what runs. - uses: https://git.fabledsword.com/bvandeusen/download-artifact@1314311ddb542af343a82d478ac786ceada4143a + # code.forgejo.org/forgejo/download-artifact. + # + # SHA below is that fork's `v6` tag. Match on @actions/artifact, NOT on + # the action's own version number — the two actions release on unrelated + # cadences, and download v5 would pair a ^2.3.2 client with this file's + # ^4.0.0 uploader. v6 is the tag whose bundled library major (^4.0.0) is + # the same one proven against this instance by the upload side. + # Deliberately NOT v7: it moves to node24 and upstream requires runner + # >= 2.327.1 for it, which act_runner does not claim to satisfy. + # Pinned, not tagged — the mirror auto-syncs every 8h. + uses: https://git.fabledsword.com/bvandeusen/download-artifact@8d4e9521a5f7e5f8b6351f341f719f9f45a92a3a with: name: minstrel-apk path: client/ diff --git a/ci-requirements.md b/ci-requirements.md index 7d34d5e6..712ccda0 100644 --- a/ci-requirements.md +++ b/ci-requirements.md @@ -47,7 +47,7 @@ None. - **Artifacts — use the mirrored actions, never `actions/{upload,download}-artifact`.** ```yaml uses: https://git.fabledsword.com/bvandeusen/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 - uses: https://git.fabledsword.com/bvandeusen/download-artifact@1314311ddb542af343a82d478ac786ceada4143a + uses: https://git.fabledsword.com/bvandeusen/download-artifact@8d4e9521a5f7e5f8b6351f341f719f9f45a92a3a ``` Upstream's `@v4+` cannot work against this instance and no server-side change will help: `isGhes()` rejects any hostname that isn't `github.com` / @@ -62,11 +62,39 @@ None. (`code.forgejo.org/forgejo/{upload,download}-artifact`, one commit on upstream disabling that check), mirrored so CI depends on commits we hold and pinned by SHA because the mirrors auto-sync every 8h — a moved upstream tag would - otherwise silently change what runs. The pins are upstream's `v5` tags on both - sides; **keep the majors matched.** `release.yml` is a producer/consumer pair — - `android-release` uploads `minstrel-apk`, `image-release` downloads it — and - mixing protocol versions across that pair yields an empty listing rather than - an error, which is the failure mode this whole entry exists to prevent. + otherwise silently change what runs. + + **Match the pins on `@actions/artifact`, not on the actions' own version + numbers.** The two actions release on unrelated cadences, so equal version + numbers do NOT mean a compatible pair — upload `v5` bundles `@actions/artifact` + ^4.0.0 while download `v5` bundles ^2.3.2. The pins above are upload **v5** and + download **v6**, which is the pairing that puts ^4.0.0 on both sides. This + matters because `release.yml` is a producer/consumer pair — `android-release` + uploads `minstrel-apk`, `image-release` downloads it — and a protocol mismatch + across it yields an empty listing rather than an error, exactly the silent + failure this entry exists to prevent. + + | tag | `@actions/artifact` | runtime | + |---|---|---| + | upload v4 | ^2.1.1 | node20 | + | **upload v5** ← pinned | **^4.0.0** | node20 | + | download v4 | ^2.1.1 | node20 | + | download v5 | ^2.3.2 | node20 | + | **download v6** ← pinned | **^4.0.0** | node20 | + | download v7 | ^5.0.0 | **node24** | + + The only true protocol break in this history was **v3 → v4** (upstream: + "Downloading artifacts that were created from `actions/upload-artifact@v3` and + below are not supported"); v4-and-up are one family. Later majors are mostly + ergonomics and runtime — upload v4 forbids re-uploading a name and caps a job + at 500 artifacts; download v5 made by-ID extraction match by-name. + + **Do not jump the download pin to v7.** That major is a runner requirement, not + a feature change: it moves to `runs.using: node24` and upstream states it + "requires a minimum Actions Runner version of 2.327.1 … if you are using + self-hosted runners, ensure they are updated before upgrading." act_runner is + not GitHub's runner and makes no such version claim, so node24 is unverified + here. Everything currently pinned is node20. Upload steps set `if-no-files-found: error` rather than the default `warn`, so an upload that matches nothing fails its own job instead of failing the