Compare commits
1
Commits
f32eb93289
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76bd7d0b70 |
@@ -141,6 +141,9 @@ jobs:
|
||||
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
permissions:
|
||||
contents: read
|
||||
# Kept as a statement of intent, but it does not grant what this job
|
||||
# needs: on Gitea the registry does not accept the Actions token at all,
|
||||
# so `packages: write` on it authorises nothing. See the login step.
|
||||
packages: write
|
||||
steps:
|
||||
- uses: https://github.com/actions/checkout@v4
|
||||
@@ -166,11 +169,40 @@ jobs:
|
||||
echo "host=${host}" >> "$GITHUB_OUTPUT"
|
||||
echo "name=${host}/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Why not `secrets.GITHUB_TOKEN`, which is what this was and what the
|
||||
# GHCR version used: a Gitea package belongs to a **user or org owner,
|
||||
# not to a repository**, so the ephemeral repo-scoped Actions token
|
||||
# carries no authority over it and the registry refuses it. GitLab hands
|
||||
# out working per-job registry credentials ($CI_REGISTRY_PASSWORD, which
|
||||
# .gitlab-ci.yml uses) and Gitea deliberately does not, so this needs a
|
||||
# real access token with package write scope, stored as REGISTRY_TOKEN.
|
||||
#
|
||||
# The username must be the token's owner, hence repository_owner rather
|
||||
# than github.actor: the image is pushed into the owner's namespace, and
|
||||
# actor is whoever happened to trigger the run — a different person on a
|
||||
# dispatch, and the wrong account entirely on a fork.
|
||||
- name: Check the registry credential exists
|
||||
# Without this the failure is a bare `unauthorized` from the daemon,
|
||||
# which says nothing about what to do. It also tells us something we do
|
||||
# not currently know: whether the old token was rejected or was simply
|
||||
# never set.
|
||||
env:
|
||||
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
if [ -z "${REGISTRY_TOKEN:-}" ]; then
|
||||
echo "::error::REGISTRY_TOKEN is not set. Create an access token at" \
|
||||
"${{ github.server_url }}/user/settings/applications with the" \
|
||||
"package read+write scope, then add it to this repository under" \
|
||||
"Settings → Actions → Secrets as REGISTRY_TOKEN."
|
||||
exit 1
|
||||
fi
|
||||
echo "REGISTRY_TOKEN is set (${#REGISTRY_TOKEN} chars)"
|
||||
|
||||
- uses: https://github.com/docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ steps.img.outputs.host }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- uses: https://github.com/docker/build-push-action@v6
|
||||
with:
|
||||
|
||||
@@ -358,6 +358,22 @@ The image lands at `gitea.lucaswinther.info/lucasw89/gacha-event-tracker`, tagge
|
||||
the commit SHA. The registry host is derived from `github.server_url` rather than hardcoded, so a
|
||||
fork on another instance pushes to its own registry.
|
||||
|
||||
**Pushing the image needs one one-time step CI cannot do for itself.** A Gitea package belongs to a
|
||||
*user or org owner*, not to a repository, so the ephemeral Actions token has no authority over it and
|
||||
the registry refuses it — `secrets.GITHUB_TOKEN` does not work here, unlike on GHCR and unlike
|
||||
GitLab's `$CI_REGISTRY_PASSWORD`. So:
|
||||
|
||||
1. Create an access token at **Settings → Applications** with the **package** read + write scope.
|
||||
2. Add it to the repository under **Settings → Actions → Secrets** as **`REGISTRY_TOKEN`**.
|
||||
|
||||
The `image` job checks for that secret before it tries to log in, and fails with those instructions
|
||||
rather than a bare `unauthorized` from the Docker daemon. The username it logs in with is
|
||||
`github.repository_owner`, not `github.actor` — the image goes to the owner's namespace, and the
|
||||
actor is merely whoever triggered the run.
|
||||
|
||||
One consequence of packages being owner-scoped: the pushed image is **not** automatically associated
|
||||
with this repository. Linking it is a manual step on the package's own settings page.
|
||||
|
||||
The feed job fails if the event count collapses, or if any single source parses to nothing — nine
|
||||
healthy sources hide a tenth that has gone quiet, and the total stays comfortably over the floor
|
||||
while one game shows an empty calendar. That is the failure mode a parser-only pipeline is most
|
||||
|
||||
Reference in New Issue
Block a user