Repository navigation
fix(deploy,renovate): forward GITHUB_TOKEN to ghcr.io login on the host - #231
Merged
Merged
Conversation
docker compose pull fails with unauthorized on a private ghcr.io image because the target host's Docker daemon is never authenticated for it. Forward the Actions run's own GITHUB_TOKEN over the existing SSH connection and docker login ghcr.io before pulling, instead of minting and storing a separate long-lived registry credential as a new GitHub Secret. Fixes #230
There was a problem hiding this comment.
🟡 Changes recommended
Docker login persists and overwrites host credentials despite the documented no-disk guarantee.
2 open findings
What changed in this PR
Adds GHCR authentication to deployment and renovation flows so private container images can be pulled.
Changes:
- Forwards
GITHUB_TOKENsecurely over SSH stdin. - Logs hosts into GHCR before image pulls.
- Adds tests and usage documentation.
| File | Description |
|---|---|
README.md |
Documents GHCR authentication. |
AGENTS.md |
Updates deployment architecture guidance. |
.github/workflows/renovate.yml |
Supplies the workflow token. |
.github/actions/renovate/action.yml |
Adds the optional token input. |
.github/actions/renovate/renovate.py |
Implements GHCR login. |
.github/actions/renovate/tests/test_renovate.py |
Tests login and ordering. |
.github/actions/renovate/README.md |
Documents token usage. |
.github/actions/deploy/action.yml |
Expands the token contract. |
.github/actions/deploy/deploy.py |
Adds login before deployment. |
.github/actions/deploy/tests/test_deploy.py |
Tests login and ordering. |
.github/actions/deploy/README.md |
Documents dual token usage. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+156
to
+160
| connection.run( | ||
| f"docker login ghcr.io -u {shlex.quote(actor)} --password-stdin", | ||
| hide=True, | ||
| in_stream=io.StringIO(token), | ||
| ) |
Comment on lines
+61
to
+65
| connection.run( | ||
| f"docker login ghcr.io -u {shlex.quote(actor)} --password-stdin", | ||
| hide=True, | ||
| in_stream=io.StringIO(token), | ||
| ) |
Copilot review on #231 flagged that a plain `docker login` writes into the host's default ~/.docker/config.json, leaving the short-lived GITHUB_TOKEN on disk past the run and silently replacing whatever ghcr.io credential was already configured there. Point DOCKER_CONFIG at a throwaway directory for the login and the pull that follows instead, and remove it in a finally block once done, even if the pull fails. Also drops the #230 cross-references added in the previous commit, per request - the behavior is documented on its own terms instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
docker compose pullfails withunauthorizedon a privateghcr.ioimage, because the target host's Docker daemon is never authenticated for it - no registry login mechanism exists anywhere in the repo today.GITHUB_TOKENover the existing SSH connection anddocker login ghcr.io(via stdin, never on the command line) right beforedocker compose pull- in bothdeploy.py(before pushing the release) andrenovate.py(before each app's pull).ghcr.io- a private image published from a different repo under the same org/user needs that package's own "Manage Actions access" setting to grant read to this workflow's repository, sinceGITHUB_TOKENdoesn't carry further than that by default.deploy'sgithub-tokeninput already existed (used for resolving release refs) and now does double duty.renovate'sgithub-tokeninput is new and optional - skipped entirely when unset, so existing callers are unaffected.Test plan
python3 -m unittest discover -s testspasses in both.github/actions/deploy(59 tests) and.github/actions/renovate(21 tests), including newlogin_registrycoverage (no-op without a token, correctdocker logincommand, token delivered over stdin rather than the command line, default actor fallback, and ordering relative to the pull/push steps).Fixes #230
🤖 Generated with Claude Code