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
Owner

Fixes the artifact defect from Scribe issue 2270 on this repo. CI-only — three files, no application code.

What was wrong

android.yml and release.yml uploaded via actions/upload-artifact@v3, which reports success while Gitea stores the result in a format its v4-only artifact API will never serve back. 72 artifacts on this repo are on disk with valid DB rows and are invisible to the REST API, the web download route and the MCP tools alike. Green jobs producing nothing retrievable — the dangerous failure mode, not a red build.

actions/upload-artifact@v4+ is not the fix: its isGhes() rejects any hostname that isn't github.com / *.ghe.com / *.localhost and throws before opening a connection, so no server-side change reaches it.

What changed

file site change
android.yml upload debug APK upload-artifact mirror @ cb8afe72 (v5)
release.yml upload minstrel-apk upload-artifact mirror @ cb8afe72 (v5)
release.yml download minstrel-apk download-artifact mirror @ 8d4e9521 (v6)

Both point at pull mirrors of the Forgejo project's forks, which disable the client-side GHES refusal. Pinned by SHA because the mirrors auto-sync every 8h.

This repo consumes artifacts as well as producing themimage-release downloads minstrel-apk to bundle the APK into the container. Swapping only the upload would have left a v3 downloader reading the v1/v3 listing against a v4-protocol artifact: an empty result, not an error. So the download side needed a mirror too (bvandeusen/download-artifact, created for this).

Pin selection matches on @actions/artifact, not on the actions' version numbers — the two actions release on unrelated cadences, so upload v5 (^4.0.0) pairs with download v6 (^4.0.0), not download v5 (^2.3.2). ^4.0.0 is the library major just proven end to end on thoughtsync. Deliberately not download v7: that major moves to node24 and requires Actions Runner >= 2.327.1, which act_runner makes no claim to satisfy.

Uploads also set if-no-files-found: error so an upload that matches nothing fails its own job instead of failing the consumer later.

ci-requirements.md carries the full reasoning plus a version/runtime table.

Verification

The same swap is proven end to end on thoughtsync (run 3094): both artifacts listed via GET …/actions/runs/{id}/artifacts, downloaded from …/artifacts/{id}/zip, extracted, payloads genuine.

Merging here is what exercises it on this repo — android.yml's upload step is gated to main pushes, so dev cannot prove it. I'll verify the APK artifact lists and downloads once the main run completes.

Known gap: release.yml's upload+download pair is gated to v* tags, so it ships correct-by-analysis but unexercised until the next release.

🤖 Generated with Claude Code

Fixes the artifact defect from Scribe issue 2270 on this repo. CI-only — three files, no application code. ## What was wrong `android.yml` and `release.yml` uploaded via `actions/upload-artifact@v3`, which reports success while Gitea stores the result in a format its v4-only artifact API will never serve back. **72 artifacts on this repo** are on disk with valid DB rows and are invisible to the REST API, the web download route and the MCP tools alike. Green jobs producing nothing retrievable — the dangerous failure mode, not a red build. `actions/upload-artifact@v4+` is not the fix: its `isGhes()` rejects any hostname that isn't `github.com` / `*.ghe.com` / `*.localhost` and throws before opening a connection, so no server-side change reaches it. ## What changed | file | site | change | |---|---|---| | `android.yml` | upload debug APK | → `upload-artifact` mirror @ `cb8afe72` (v5) | | `release.yml` | upload `minstrel-apk` | → `upload-artifact` mirror @ `cb8afe72` (v5) | | `release.yml` | download `minstrel-apk` | → `download-artifact` mirror @ `8d4e9521` (v6) | Both point at pull mirrors of the Forgejo project's forks, which disable the client-side GHES refusal. Pinned by SHA because the mirrors auto-sync every 8h. **This repo consumes artifacts as well as producing them** — `image-release` downloads `minstrel-apk` to bundle the APK into the container. Swapping only the upload would have left a v3 downloader reading the v1/v3 listing against a v4-protocol artifact: an empty result, not an error. So the download side needed a mirror too (`bvandeusen/download-artifact`, created for this). **Pin selection matches on `@actions/artifact`, not on the actions' version numbers** — the two actions release on unrelated cadences, so upload v5 (`^4.0.0`) pairs with download **v6** (`^4.0.0`), not download v5 (`^2.3.2`). `^4.0.0` is the library major just proven end to end on thoughtsync. Deliberately not download v7: that major moves to `node24` and requires Actions Runner >= 2.327.1, which act_runner makes no claim to satisfy. Uploads also set `if-no-files-found: error` so an upload that matches nothing fails its own job instead of failing the consumer later. `ci-requirements.md` carries the full reasoning plus a version/runtime table. ## Verification The same swap is proven end to end on thoughtsync (run 3094): both artifacts listed via `GET …/actions/runs/{id}/artifacts`, downloaded from `…/artifacts/{id}/zip`, extracted, payloads genuine. Merging here is what exercises it on this repo — `android.yml`'s upload step is gated to `main` pushes, so `dev` cannot prove it. I'll verify the APK artifact lists and downloads once the `main` run completes. **Known gap:** `release.yml`'s upload+download pair is gated to `v*` tags, so it ships correct-by-analysis but unexercised until the next release. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bvandeusen added 2 commits 2026-07-30 15:50:50 -04:00
ci: swap artifact upload+download to the mirrored actions (issue 2270)
android / Build + lint + test (push) Successful in 4m30s
52d53e0044
android.yml and release.yml uploaded via actions/upload-artifact@v3, which
reports success while Gitea stores the result in a format its v4-only
artifact API will never serve back — 72 artifacts on this repo are on disk,
have valid DB rows, and are invisible to every retrieval path. Green jobs
producing nothing retrievable.

release.yml is a producer/consumer pair: android-release uploads
minstrel-apk and image-release downloads it to bundle into the container.
Swapping only the upload would have left download-artifact@v3 reading the
v1/v3 listing and finding nothing, so mirror the download side too —
bvandeusen/download-artifact, pull mirror of forgejo/download-artifact,
pinned at its v5 tag to match the upload pin's major.

Not actions/{upload,download}-artifact@v4: isGhes() throws on the hostname
before opening a connection, so no server-side change reaches it.

Upload steps also set if-no-files-found: error — image-release hard-depends
on minstrel-apk existing, so an empty upload must fail where it happens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous pin matched the two actions by their own version numbers, which
is meaningless: upload-artifact and download-artifact release on unrelated
cadences. upload v5 bundles @actions/artifact ^4.0.0; download v5 bundles
^2.3.2. "v5 and v5" was in fact a mismatched pair.

download v6 is the tag that puts ^4.0.0 on both sides — and ^4.0.0 is the
library major just proven against this instance by the upload side
(thoughtsync run 3094: two artifacts listed, downloaded and extracted
intact). ^2.3.2 has never been exercised here.

Not v7: that major is a runner requirement rather than a feature change. It
moves to runs.using: node24 and upstream requires runner >= 2.327.1 for it,
which act_runner does not claim to satisfy. Everything pinned stays node20.

ci-requirements.md now carries the version/runtime table and the reasoning,
so the next person matches on the library instead of the tag number.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
bvandeusen merged commit 7d45a4e5c7 into main 2026-07-30 15:51:16 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/minstrel#113