fix(ci): switch generic-packages upload auth to HTTP Basic with owner:token #111

Merged
David merged 1 commit from fix/generic-packages-basic-auth into main 2026-05-15 03:04:45 +02:00
Owner

Summary

First live run of build-desktop-{linux,windows}.yml (from #110) 401'd on both DELETE and PUT:

DELETE https://dev.a8n.run/api/packages/a8n-tools-private/generic/lets-chat/latest/lets-chat-desktop-linux-x86_64
401
PUT https://dev.a8n.run/api/packages/a8n-tools-private/generic/lets-chat/latest/lets-chat-desktop-linux-x86_64
curl: (22) The requested URL returned error: 401

Root cause: the auth shape I copied from da-os/.forgejo/workflows/build-{linux,windows}.yml uses --header "Authorization: token $FORGEJO_TOKEN", which this org's Forgejo Packages endpoint rejects with 401 before checking whether the target path exists. The pattern that actually works (per eform/.forgejo/workflows/build-oci-image.yml::Publish binary as Generic Package, and structurally the same shape as the docker login --username $OWNER --password $PAT call in build-oci-image.yml that has been passing) is HTTP Basic auth with the package owner as the username.

Changes

Three workflow files updated to the eform pattern:

  • .forgejo/workflows/build-desktop-linux.yml
  • .forgejo/workflows/build-desktop-windows.yml
  • .forgejo/workflows/publish-release.yml

In each: replace --header "Authorization: token $FORGEJO_TOKEN" with --user "${PACKAGE_OWNER}:${FORGEJO_TOKEN}" on both DELETE and PUT. PUT switched from --fail to --fail-with-body so any future Forgejo rejection surfaces the response body instead of just the curl error code. Multi-line curl invocations collapsed into one-line form matching eform, so the three files diff cleanly.

Audit

grep -rn 'Authorization: token\|--user\|--header' .forgejo/workflows/ after the change:

  • 3x --user $userpass callsites (two desktop, one in publish-release).
  • 0x --header lines.
  • 0x Authorization: token auth lines; the remaining matches are comments documenting why we are not using that shape.
  • 1x --username for docker login in build-oci-image.yml against the container registry, which is a separate endpoint and was never failing.

Test plan

  • Next main push: build-desktop-linux.yml and build-desktop-windows.yml complete and produce ${ORG}/generic/lets-chat/latest/lets-chat-desktop-{linux,windows}-x86_64[.exe] in the Generic Packages UI.
  • Re-run with the same head SHA succeeds (DELETE removes the prior upload before PUT).
  • curl -L "${GITHUB_SERVER_URL}/api/packages/${ORG}/generic/lets-chat/latest/lets-chat-desktop-linux-x86_64" -o /tmp/lcd && file /tmp/lcd shows an ELF binary.
  • Future v* tag push: publish-release.yml succeeds end-to-end including the latest/latest.json upload.
## Summary First live run of `build-desktop-{linux,windows}.yml` (from #110) 401'd on both DELETE and PUT: ``` DELETE https://dev.a8n.run/api/packages/a8n-tools-private/generic/lets-chat/latest/lets-chat-desktop-linux-x86_64 401 PUT https://dev.a8n.run/api/packages/a8n-tools-private/generic/lets-chat/latest/lets-chat-desktop-linux-x86_64 curl: (22) The requested URL returned error: 401 ``` Root cause: the auth shape I copied from `da-os/.forgejo/workflows/build-{linux,windows}.yml` uses `--header "Authorization: token $FORGEJO_TOKEN"`, which this org's Forgejo Packages endpoint rejects with 401 before checking whether the target path exists. The pattern that actually works (per `eform/.forgejo/workflows/build-oci-image.yml::Publish binary as Generic Package`, and structurally the same shape as the `docker login --username $OWNER --password $PAT` call in `build-oci-image.yml` that has been passing) is HTTP Basic auth with the package owner as the username. ## Changes Three workflow files updated to the eform pattern: - `.forgejo/workflows/build-desktop-linux.yml` - `.forgejo/workflows/build-desktop-windows.yml` - `.forgejo/workflows/publish-release.yml` In each: replace `--header "Authorization: token $FORGEJO_TOKEN"` with `--user "${PACKAGE_OWNER}:${FORGEJO_TOKEN}"` on both DELETE and PUT. PUT switched from `--fail` to `--fail-with-body` so any future Forgejo rejection surfaces the response body instead of just the curl error code. Multi-line curl invocations collapsed into one-line form matching eform, so the three files diff cleanly. ## Audit `grep -rn 'Authorization: token\|--user\|--header' .forgejo/workflows/` after the change: - 3x `--user $userpass` callsites (two desktop, one in publish-release). - 0x `--header` lines. - 0x `Authorization: token` auth lines; the remaining matches are comments documenting why we are not using that shape. - 1x `--username` for `docker login` in `build-oci-image.yml` against the container registry, which is a separate endpoint and was never failing. ## Test plan - [ ] Next `main` push: `build-desktop-linux.yml` and `build-desktop-windows.yml` complete and produce `${ORG}/generic/lets-chat/latest/lets-chat-desktop-{linux,windows}-x86_64[.exe]` in the Generic Packages UI. - [ ] Re-run with the same head SHA succeeds (DELETE removes the prior upload before PUT). - [ ] `curl -L "${GITHUB_SERVER_URL}/api/packages/${ORG}/generic/lets-chat/latest/lets-chat-desktop-linux-x86_64" -o /tmp/lcd && file /tmp/lcd` shows an ELF binary. - [ ] Future `v*` tag push: `publish-release.yml` succeeds end-to-end including the `latest/latest.json` upload.
fix(ci): switch generic-packages upload auth to HTTP Basic with owner:token
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 2m35s
bff7fb4a25
The first live runs of `build-desktop-{linux,windows}.yml` (#110) returned 401 on both DELETE and PUT against `dev.a8n.run/api/packages/a8n-tools-private/generic/lets-chat/latest/...`. The auth pattern I'd written, copied from `da-os/.forgejo/workflows/build-{linux,windows}.yml`, uses `--header "Authorization: token $FORGEJO_TOKEN"`. That bearer-style header is documented but is not what this org's Forgejo accepts for the Generic Packages PUT/DELETE endpoint - it rejects with 401 before checking whether the target path exists. (da-os's workflow has presumably never run successfully against the same endpoint, or runs against a different namespace; either way `da-os` is the wrong reference for the auth shape.)

The pattern that does work, and the pattern every other passing workflow in `~/projects/a8n-run/` uses for the same endpoint, is HTTP Basic auth with the package owner as the username (see `eform/.forgejo/workflows/build-oci-image.yml::Publish binary as Generic Package`, and structurally the same shape as the `docker login --username $OWNER --password $PAT` flow that `build-oci-image.yml` already uses successfully).

Apply the eform pattern to every workflow in this repo that talks to the Generic Packages API:

- `.forgejo/workflows/build-desktop-linux.yml`
- `.forgejo/workflows/build-desktop-windows.yml`
- `.forgejo/workflows/publish-release.yml`

In each file: the `Authorization: token ...` header is replaced with `--user "${PACKAGE_OWNER}:${FORGEJO_TOKEN}"` on both the best-effort DELETE and the PUT. The PUT is switched from `--fail` to `--fail-with-body` so any future Forgejo rejection surfaces the response body rather than just the curl error code. The `--output /dev/null` + `--write-out "%{http_code}\n"` scaffolding on the DELETE is dropped; we already rely on `--silent` not printing on 404, and any non-404 failure is no longer interesting to surface (the PUT immediately after exposes the real failure if there is one). Multi-line curl invocations collapsed into the one-line `^curl --silent --show-error --user $userpass ...` shape eform uses, to keep the three files visually identical and easy to diff against.

Audit. `grep -rn 'Authorization: token\|--user\|--header' .forgejo/workflows/` after the change shows zero remaining `--header` lines, zero remaining `Authorization: token` auth (the only matches are now comments explaining why we are not using that shape), and a third `--user` callsite besides the two desktop workflows in `publish-release.yml`. No workflow file in this repo is on the bearer pattern anymore. The unique `--user --password` flow for `docker login` against the container registry in `build-oci-image.yml` is untouched - that endpoint is separate and was never failing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
David merged commit 5f1a0a953d into main 2026-05-15 03:04:45 +02:00
David deleted branch fix/generic-packages-basic-auth 2026-05-15 03:04:45 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!111
No description provided.