fix(ext-ci): use browser_download_url + curl -f + ZIP magic check (XPI silently corrupt) #20

Merged
bvandeusen merged 0 commits from dev into main 2026-05-26 00:43:02 -04:00
bvandeusen commented 2026-05-26 00:42:50 -04:00 (Migrated from git.fabledsword.com)

Root cause

The currently-deployed :latest from PR #19's build silently shipped a corrupt XPI. Verified via curl http://curator.traefik.internal/extension/fabledcurator-latest.xpi returning a 19-byte response: 404 page not found.

My build-web code in PR #19 had three compounding bugs:

  1. Wrong endpoint/api/v1/.../releases/assets/<id> returns asset METADATA (JSON), not the binary blob. The correct download URL is the asset's browser_download_url field.
  2. No -f flag on curl — when the metadata endpoint returned 404 (or HTML), curl wrote the response body to the destination file with exit code 0. Build proceeded happily; docker image shipped a 19-byte text file masquerading as an XPI.
  3. No content validation — nothing checked that the downloaded file was actually a ZIP before sealing it into the image.

Fix

  • Parse browser_download_url from release.json (where the tag-lookup writes the asset metadata) and curl THAT URL.
  • Add -f to the download curl so any HTTP error fails the build instead of writing the error body.
  • Add a magic-byte check: the first two bytes of the downloaded file must be PK (ZIP magic). If not, dump the file preview and exit 1. This is the defense-in-depth lesson banked from the "silent corruption shipped to production" failure mode.

Bonus

In v26.05.25.5 also lives the sidecar NN_ prefix fix (0978fba) — that one's unrelated to the XPI install but addresses a much bigger silent failure (0 Posts in operator's DB despite 24 deep-refresh calls). Both ship together.

🤖 Generated with Claude Code

## Root cause The currently-deployed `:latest` from PR #19's build silently shipped a corrupt XPI. Verified via `curl http://curator.traefik.internal/extension/fabledcurator-latest.xpi` returning a 19-byte response: `404 page not found`. My build-web code in PR #19 had three compounding bugs: 1. **Wrong endpoint** — `/api/v1/.../releases/assets/<id>` returns asset METADATA (JSON), not the binary blob. The correct download URL is the asset's `browser_download_url` field. 2. **No `-f` flag on curl** — when the metadata endpoint returned 404 (or HTML), curl wrote the response body to the destination file with exit code 0. Build proceeded happily; docker image shipped a 19-byte text file masquerading as an XPI. 3. **No content validation** — nothing checked that the downloaded file was actually a ZIP before sealing it into the image. ## Fix - Parse `browser_download_url` from `release.json` (where the tag-lookup writes the asset metadata) and curl THAT URL. - Add `-f` to the download curl so any HTTP error fails the build instead of writing the error body. - Add a magic-byte check: the first two bytes of the downloaded file must be `PK` (ZIP magic). If not, dump the file preview and exit 1. This is the defense-in-depth lesson banked from the "silent corruption shipped to production" failure mode. ## Bonus In v26.05.25.5 also lives the sidecar `NN_` prefix fix (`0978fba`) — that one's unrelated to the XPI install but addresses a much bigger silent failure (0 Posts in operator's DB despite 24 deep-refresh calls). Both ship together. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledCurator#20