7070 - name : 🔨 Set up Docker Buildx
7171 uses : docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
7272
73- # Logins and metadata are only needed in push mode
73+ # GHCR login runs before the build — needed to pull ghcr.io/astral-sh/uv.
7474 - name : Login to GHCR
7575 if : inputs.push
7676 uses : docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
@@ -79,12 +79,11 @@ jobs:
7979 username : ${{ github.actor }}
8080 password : ${{ github.token }}
8181
82- - name : Login to Docker Hub
83- if : inputs.push
84- uses : docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
85- with :
86- username : ${{ secrets.DOCKERHUB_USERNAME }}
87- password : ${{ secrets.DOCKERHUB_TOKEN }}
82+ # Docker Hub login is deferred until after the build and tests.
83+ # A repo-scoped Docker Hub token (socketdev/socket-basics only) would cause
84+ # 401s if active during the build, since BuildKit uses it for ALL Docker Hub
85+ # requests including pulling public base images (python, trivy, trufflehog).
86+ # Those public images pull fine without auth; only the push needs credentials.
8887
8988 - name : Extract image metadata
9089 if : inputs.push
@@ -141,6 +140,16 @@ jobs:
141140 --image-tag ${{ inputs.name }}:pipeline-test
142141
143142 # ── Step 4: Push to registries (publish mode only) ─────────────────────
143+ # Docker Hub login happens here — after build and tests, immediately before
144+ # push. Keeping it here prevents the repo-scoped token from interfering
145+ # with public image pulls during the build step.
146+ - name : Login to Docker Hub
147+ if : inputs.push
148+ uses : docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
149+ with :
150+ username : ${{ secrets.DOCKERHUB_USERNAME }}
151+ password : ${{ secrets.DOCKERHUB_TOKEN }}
152+
144153 # All layers are in the GHA cache from step 1 — this is just an upload.
145154 - name : 🚀 Push to registries
146155 if : inputs.push
0 commit comments