Skip to content

Commit a767acb

Browse files
ten9876claude
andcommitted
ci(ghcr): publish the CI image to the org namespace
The CI image has not published since 2026-05-04. Every run since fails at the push: #9 pushing ghcr.io/ten9876/aethersdr-ci:latest with docker #9 ERROR: denied: permission_denied: The requested installation does not exist. The build itself is fine — all layers complete, and the Dockerfile builds clean locally. The failure is purely one of namespace. This repository is owned by the `aethersdr` org, so `secrets.GITHUB_TOKEN` is scoped to `aethersdr/AetherSDR`; the package lives in the personal `ten9876` namespace, which that token has no write access to. `packages: write` in the workflow grants nothing outside the token's own namespace. This was not a regression from any Dockerfile change. #4656 adding `ccache` was simply the first Dockerfile push after the access broke, which is why it looked like the culprit. Move the package to `ghcr.io/aethersdr/aethersdr-ci`, alongside the repository that builds it, so the default token can publish it and the image cannot be orphaned again by an ownership change. The digest-pin step's regex now matches either owner and always rewrites to the org path, so a consumer left on the old namespace by a long-lived branch is normalised rather than pinned to a digest under a namespace this token cannot publish to. Sequencing note: consumers move in this same commit, so the org package must exist and be PUBLIC before this merges. `workflow_dispatch` runs the workflow as defined on the chosen ref, so dispatching docker-ci-image.yml on this branch publishes the org image first; the package then has to be flipped to public by hand, because GHCR creates new packages private and the `container:` jobs pull unauthenticated — the current ten9876 package is public, which is why no `credentials:` block was ever needed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 1931227 commit a767acb

4 files changed

Lines changed: 12 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ permissions:
3030
jobs:
3131
build:
3232
runs-on: ubuntu-latest
33-
container: ghcr.io/ten9876/aethersdr-ci:latest
33+
container: ghcr.io/aethersdr/aethersdr-ci:latest
3434

3535
# Explicit CCACHE_DIR: the job runs as root inside a container, so `~`
3636
# resolves to /root and an actions/cache `path:` of `~/.cache/ccache` would

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ permissions:
6969
jobs:
7070
analyze:
7171
runs-on: ubuntu-latest
72-
container: ghcr.io/ten9876/aethersdr-ci:latest
72+
container: ghcr.io/aethersdr/aethersdr-ci:latest
7373

7474
strategy:
7575
matrix:

.github/workflows/docker-ci-image.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
with:
4242
context: .github/docker
4343
push: true
44-
tags: ghcr.io/ten9876/aethersdr-ci:latest
44+
tags: ghcr.io/aethersdr/aethersdr-ci:latest
4545

4646
- name: Update workflow consumers to new digest
4747
id: pin
@@ -58,12 +58,18 @@ jobs:
5858
# run swaps the legacy ":latest" reference cleanly.
5959
# The `[ -f ]` guard lets the loop run cleanly even if a consumer
6060
# file isn't on main yet (e.g. sanitizers.yml until PR #2866 lands).
61+
#
62+
# The owner alternation matches the pre-move `ten9876` namespace as
63+
# well as the current `aethersdr` one, and always rewrites to the
64+
# latter. That way a consumer left on the old namespace by a
65+
# long-lived branch is normalised rather than pinned to a digest
66+
# under a namespace this token cannot publish to.
6167
for f in .github/workflows/ci.yml \
6268
.github/workflows/codeql.yml \
6369
.github/workflows/sanitizers.yml; do
6470
[ -f "$f" ] || continue
6571
sed -i -E \
66-
"s#(ghcr\.io/ten9876/aethersdr-ci)(@sha256:[a-f0-9]+|:[A-Za-z0-9._-]+)#\1@${DIGEST}#g" \
72+
"s#ghcr\.io/(ten9876|aethersdr)/aethersdr-ci(@sha256:[a-f0-9]+|:[A-Za-z0-9._-]+)#ghcr.io/aethersdr/aethersdr-ci@${DIGEST}#g" \
6773
"$f"
6874
done
6975
echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT"
@@ -83,7 +89,7 @@ jobs:
8389
publishing a new CI image from the current
8490
`.github/docker/Dockerfile`.
8591
86-
Updates the `ghcr.io/ten9876/aethersdr-ci` reference in
92+
Updates the `ghcr.io/aethersdr/aethersdr-ci` reference in
8793
`ci.yml`, `codeql.yml`, and `sanitizers.yml` (where present) to:
8894
8995
${{ steps.pin.outputs.digest }}

.github/workflows/sanitizers.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
sanitize:
2020
name: ${{ matrix.sanitizer.label }}
2121
runs-on: ubuntu-latest
22-
container: ghcr.io/ten9876/aethersdr-ci:latest
22+
container: ghcr.io/aethersdr/aethersdr-ci:latest
2323
strategy:
2424
fail-fast: false
2525
matrix:

0 commit comments

Comments
 (0)