ci: artifacts that can actually be downloaded (issue 2270) #113

Merged
bvandeusen merged 2 commits from dev into main 2026-07-30 15:51:16 -04:00
2 changed files with 46 additions and 12 deletions
Showing only changes of commit fa0827f668 - Show all commits
+12 -6
View File
@@ -245,14 +245,20 @@ jobs:
# Tag pushes only — android-release just produced this. Non-tag # Tag pushes only — android-release just produced this. Non-tag
# builds take the "Bundle latest release APK" path below instead. # builds take the "Bundle latest release APK" path below instead.
if: steps.guard.outputs.ready == 'true' && startsWith(github.ref, 'refs/tags/v') 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 # Consuming half of the pair — never actions/download-artifact. Same fork,
# uses the download mirror, never actions/download-artifact. Same fork,
# same reason: upstream's client-side GHES check rejects this hostname # same reason: upstream's client-side GHES check rejects this hostname
# before it connects. bvandeusen/download-artifact mirrors # before it connects. bvandeusen/download-artifact mirrors
# code.forgejo.org/forgejo/download-artifact; SHA below is its `v5` tag, # code.forgejo.org/forgejo/download-artifact.
# the major matching the upload pin. Pinned, not tagged — the mirror #
# auto-syncs every 8h and a moved tag would change what runs. # SHA below is that fork's `v6` tag. Match on @actions/artifact, NOT on
uses: https://git.fabledsword.com/bvandeusen/download-artifact@1314311ddb542af343a82d478ac786ceada4143a # 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: with:
name: minstrel-apk name: minstrel-apk
path: client/ path: client/
+34 -6
View File
@@ -47,7 +47,7 @@ None.
- **Artifacts — use the mirrored actions, never `actions/{upload,download}-artifact`.** - **Artifacts — use the mirrored actions, never `actions/{upload,download}-artifact`.**
```yaml ```yaml
uses: https://git.fabledsword.com/bvandeusen/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 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 Upstream's `@v4+` cannot work against this instance and no server-side change
will help: `isGhes()` rejects any hostname that isn't `github.com` / 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 (`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 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 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 otherwise silently change what runs.
sides; **keep the majors matched.** `release.yml` is a producer/consumer pair —
`android-release` uploads `minstrel-apk`, `image-release` downloads it — and **Match the pins on `@actions/artifact`, not on the actions' own version
mixing protocol versions across that pair yields an empty listing rather than numbers.** The two actions release on unrelated cadences, so equal version
an error, which is the failure mode this whole entry exists to prevent. 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 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 an upload that matches nothing fails its own job instead of failing the