From 505904b1e5fc8f284696f6fe6db91556581f46a7 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 30 Jul 2026 15:27:57 -0400 Subject: [PATCH] ci: swap artifact upload to the mirrored action (issue 2270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both desktop upload steps used actions/upload-artifact@v3, which reports success while Gitea stores the result in a format its v4-only artifact API will never serve back — 110 artifacts on this repo are on disk, have valid DB rows, and are invisible to the REST API, the web download route and the MCP tools alike. Green jobs producing nothing retrievable. Point both at bvandeusen/upload-artifact (pull mirror of the Forgejo project's fork, GHES refusal disabled), pinned by SHA because the mirror auto-syncs. Not actions/upload-artifact@v4: its isGhes() throws on the hostname before opening a connection, so no server-side change reaches it. Also drop continue-on-error and set if-no-files-found: error on both steps. Between them, a failed or empty upload was reported as a green run — the same silence that let this go unnoticed for a month. Co-Authored-By: Claude Opus 5 (1M context) --- .forgejo/workflows/desktop.yml | 27 +++++++++++++++++---------- ci-requirements.md | 27 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/desktop.yml b/.forgejo/workflows/desktop.yml index 77bd7c2..76f01c9 100644 --- a/.forgejo/workflows/desktop.yml +++ b/.forgejo/workflows/desktop.yml @@ -154,20 +154,25 @@ jobs: run: bash desktop/packaging/arch/package-prebuilt.sh # Make the built .deb + .AppImage downloadable from the run (for hand-testing). - # continue-on-error: the Forgejo artifact backend may not be configured yet; a - # failed upload must not fail the build itself. - # Forgejo doesn't support the v4 artifact protocol (@actions/artifact v2+), - # so pin v3, which uses the older protocol the instance accepts. + # Mirrored action, never actions/upload-artifact: @v4+ throws + # GHESNotSupportedError on the hostname before it connects, and @v3 uploads + # something Gitea stores but will never serve back (it returns artifacts only + # through the v4 API, which filters on content_encoding='application/zip'). + # Pinned by SHA — the mirror auto-syncs, so a moved upstream tag would + # silently change what runs. See Scribe issues 2255 / 2270. + # No continue-on-error: a swallowed upload failure is exactly how 110 + # unreachable artifacts accumulated here unnoticed. Fail loudly instead. - name: Upload bundles - continue-on-error: true - uses: actions/upload-artifact@v3 + uses: https://git.fabledsword.com/bvandeusen/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 with: name: thoughtsync-linux path: | desktop/src-tauri/target/release/bundle/appimage/*.AppImage desktop/src-tauri/target/release/bundle/deb/*.deb desktop/src-tauri/target/release/bundle/arch/*.pkg.tar.* - if-no-files-found: warn + # error, not warn: a build that bundles nothing should report as a + # failure, not as a green run with an empty artifact. + if-no-files-found: error # Tag builds only: publish a real, versioned Fabled-Git Release with the # AppImage + .deb attached — the stable fetch target the install script and @@ -262,13 +267,15 @@ jobs: --config "$updater" working-directory: desktop/src-tauri + # Mirrored action, never actions/upload-artifact — see the Linux job's + # Upload bundles step for the full reasoning. Pinned by SHA because the + # mirror auto-syncs. - name: Upload installer - continue-on-error: true - uses: actions/upload-artifact@v3 + uses: https://git.fabledsword.com/bvandeusen/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 with: name: thoughtsync-windows path: desktop/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe - if-no-files-found: warn + if-no-files-found: error # Publishes to the SAME release as the Linux job. Safe to run twice: the # script reuses an existing release (409) and nullglob means each job uploads diff --git a/ci-requirements.md b/ci-requirements.md index 0489762..0165888 100644 --- a/ci-requirements.md +++ b/ci-requirements.md @@ -45,6 +45,33 @@ entirely on `ci-python:3.14`. (family rule 46). - The production runtime `Dockerfile` tracks python:3.12 so test results stay representative of the deployed image. +- **Artifacts — use the mirrored upload action, never `actions/upload-artifact`.** + ```yaml + uses: https://git.fabledsword.com/bvandeusen/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 + ``` + Upstream's `actions/upload-artifact@v4` cannot work against this instance and + no server-side change will help: its `isGhes()` rejects any hostname that isn't + `github.com` / `*.ghe.com` / `*.localhost` and throws before it opens a + connection, so the server is never asked what it supports. `@v3` is worse — it + reports success, and Gitea then serves artifacts back only through the v4 API + (`content_encoding = application/zip`), so a v3 upload is stored but invisible + to every retrieval path. A green job producing nothing retrievable. + + `bvandeusen/upload-artifact` is our pull mirror of `forgejo/upload-artifact` + (the Forgejo project's fork, one commit on upstream v5.0.0 disabling that + check). Mirrored so CI depends on a commit we hold; pinned by SHA because the + mirror auto-syncs and a moved upstream tag would otherwise change what runs. + + Both desktop upload steps also set `if-no-files-found: error` and carry **no** + `continue-on-error`. They previously had both defaults inverted, which is how + 110 unreachable artifacts accumulated on this repo without anyone noticing — + the upload could fail or match nothing and the run still went green. Scribe + issues 2255 / 2270 have the full teardown. + + Download: `GET /api/v1/repos/{owner}/{repo}/actions/runs/{run_id}/artifacts` + for the id (global run id, not the repo-scoped run number), then + `…/actions/artifacts/{id}/zip`. Note the workstation has no `unzip` — use + `python3 -m zipfile -e`. ## Desktop (Tauri) lane — separate workflow