Images: ghcr.io from GitHub, the forge registry from .forgejo

7005ebf · Gabe Morell · 2026-10-27 02:21

6 files +67 -57
Message
{commit_body(@commit)}

Files changed

added .forgejo/workflows/image.yml
+58 −0
@@ -0,0 +1,58 @@
1 +# The forge's copy of the image publish. .github/workflows/ci.yml's
2 +# image job pushes to ghcr.io (and the other public registries), but only
3 +# when it runs on GitHub; here the image goes to the forge's bundled
4 +# registry (CI_REGISTRY), as camerite and gitgud do: <registry>/<owner>/<repo>.
5 +#
6 +# No secrets. The forge injects CI_REGISTRY and accepts the per-job
7 +# github.token for push to this repository's own image path.
8 +#
9 +# No test gate: this workflow can't `needs:` ci.yml's test job (mix precommit),
10 +# and the Dockerfile compiles the release itself.
11 +name: image
12 +
13 +on:
14 + push:
15 + branches: [master]
16 + tags: ['v*']
17 + workflow_dispatch:
18 +
19 +jobs:
20 + image:
21 + if: github.server_url != 'https://github.com'
22 + runs-on: arc-runner-set
23 + permissions:
24 + contents: read
25 + packages: write
26 + steps:
27 + - uses: actions/checkout@v4
28 + - uses: docker/setup-buildx-action@v3
29 +
30 + # The username is ignored by the token endpoint, but login-action
31 + # requires it to be non-empty.
32 + - name: Log in to the forge registry
33 + uses: docker/login-action@v3
34 + with:
35 + registry: ${{ vars.CI_REGISTRY }}
36 + username: gitgud-actions
37 + password: ${{ github.token }}
38 +
39 + - id: meta
40 + uses: docker/metadata-action@v5
41 + with:
42 + images: ${{ vars.CI_REGISTRY }}/${{ github.repository }}
43 + tags: |
44 + type=ref,event=branch
45 + type=semver,pattern={{version}}
46 + type=semver,pattern={{major}}.{{minor}}
47 + type=sha
48 + type=raw,value=latest,enable={{is_default_branch}}
49 +
50 + - uses: docker/build-push-action@v6
51 + with:
52 + context: .
53 + platforms: linux/amd64
54 + push: true
55 + tags: ${{ steps.meta.outputs.tags }}
56 + labels: ${{ steps.meta.outputs.labels }}
57 + cache-from: type=registry,ref=${{ vars.CI_REGISTRY }}/${{ github.repository }}:buildcache
58 + cache-to: type=registry,ref=${{ vars.CI_REGISTRY }}/${{ github.repository }}:buildcache,mode=max
modified .github/workflows/ci.yml
+9 −57
@@ -67,7 +67,11 @@ jobs:
67 67 # format, test (which creates + migrates the test DB).
68 68 - run: mix precommit
69 69
70 + # The public registries from GitHub only. The forge reads
71 + # .github/workflows too, and there .forgejo/workflows/image.yml
72 + # publishes to the forge's own registry instead.
70 73 image:
74 + if: github.server_url == 'https://github.com'
71 75 needs: test
72 76 runs-on: arc-runner-set
73 77 permissions:
@@ -77,55 +81,7 @@ jobs:
77 81 - uses: actions/checkout@v4
78 82 - uses: docker/setup-buildx-action@v3
79 83
80 − # The forge's own registry, when this is running on one. Unlike the
81 − # three public registries below it needs no stored credentials: the
82 − # per-job token is already authorized to push to this repository's
83 − # own image path and nowhere else.
84 − #
85 − # `vars.CI_REGISTRY` is what says whether there is one -- on a forge
86 − # that doesn't set it, or on GitHub, every forge step below drops
87 − # out and the public registries are unaffected.
88 − - name: Resolve the forge registry
89 − id: forge
90 − env:
91 − CI_REGISTRY: ${{ vars.CI_REGISTRY }}
92 − run: |
93 − set -euo pipefail
94 −
95 − images=(
96 − "ghcr.io/$GITHUB_REPOSITORY"
97 − "docker.io/neiam/diogramos"
98 − "quay.io/neiam/diogramos"
99 − )
100 −
101 − if [ -n "${CI_REGISTRY:-}" ]; then
102 − forge_image="$CI_REGISTRY/$GITHUB_REPOSITORY"
103 − echo "publishing to the forge registry at $forge_image"
104 −
105 − images+=("$forge_image")
106 − echo "registry=$CI_REGISTRY" >> "$GITHUB_OUTPUT"
107 − echo "image=$forge_image" >> "$GITHUB_OUTPUT"
108 − else
109 − echo "No CI_REGISTRY variable set -- skipping the forge registry."
110 − fi
111 −
112 − {
113 − echo "images<<IMAGES_EOF"
114 − printf '%s\n' "${images[@]}"
115 − echo "IMAGES_EOF"
116 − } >> "$GITHUB_OUTPUT"
117 −
118 − # The token endpoint ignores the username but login-action requires
119 − # it to be non-empty.
120 − - name: Log in to the forge registry
121 − if: steps.forge.outputs.registry != '' && github.event_name != 'pull_request'
122 − uses: docker/login-action@v3
123 − with:
124 − registry: ${{ steps.forge.outputs.registry }}
125 − username: gitgud-actions
126 − password: ${{ github.token }}
127 −
128 − # GHCR uses the built-in token. Docker Hub and Quay creds come from
84 + # GHCR uses a stored token (GHCR_TOKEN). Docker Hub and Quay creds come from
129 85 # org-wide secrets (DOCKERHUB_USER/DOCKERHUB_TOKEN, QUAY_USERNAME/QUAY_TOKEN).
130 86 - name: Log in to GHCR
131 87 if: github.event_name != 'pull_request'
@@ -154,7 +110,10 @@ jobs:
154 110 - id: meta
155 111 uses: docker/metadata-action@v5
156 112 with:
157 − images: ${{ steps.forge.outputs.images }}
113 + images: |
114 + ghcr.io/${{ github.repository }}
115 + docker.io/neiam/diogramos
116 + quay.io/neiam/diogramos
158 117 tags: |
159 118 type=ref,event=branch
160 119 type=ref,event=pr
@@ -163,11 +122,6 @@ jobs:
163 122 type=sha
164 123 type=raw,value=latest,enable={{is_default_branch}}
165 124
166 − # The layer cache lives in the forge registry alongside the image.
167 − # `type=gha` is not an option here: the forge's RunnerJwt carries no
168 − # `ac` claim, so the Actions cache service rejects it. Writing the
169 − # cache is gated on a real push -- a pull request's token can read
170 − # that path but not write it.
171 125 - uses: docker/build-push-action@v6
172 126 with:
173 127 context: .
@@ -175,8 +129,6 @@ jobs:
175 129 push: ${{ github.event_name != 'pull_request' }}
176 130 tags: ${{ steps.meta.outputs.tags }}
177 131 labels: ${{ steps.meta.outputs.labels }}
178 − cache-from: ${{ steps.forge.outputs.image != '' && format('type=registry,ref={0}:buildcache', steps.forge.outputs.image) || '' }}
179 − cache-to: ${{ steps.forge.outputs.image != '' && github.event_name != 'pull_request' && format('type=registry,ref={0}:buildcache,mode=max', steps.forge.outputs.image) || '' }}
180 132
181 133 # The Android client, published to the forge's own F-Droid repository.
182 134 #

Parents: 2d0bead