From 3531f1966851da18a131b3280990d40410dbdc78 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Mon, 27 Apr 2026 15:15:46 -0700 Subject: [PATCH] =?UTF-8?q?fix(publish-image):=20drop=20pull=5Frequest=20t?= =?UTF-8?q?rigger=20=E2=80=94=20leaks=20PR=20builds=20to=20GHCR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `on: pull_request:` was the only template-repo with this trigger out of the 8 (other 7 trigger only on push:main, repository_dispatch, workflow_dispatch). The reusable publish-template-image workflow has no PR-skip guard, so the PR trigger fired every time a PR was opened or updated and pushed both `:latest` (clobbering the production tag with unmerged code) and `:sha-<7>` (a stable tag for an unmerged commit) to GHCR. Verification at PR time already happens via the validate-workspace-template workflow's "Docker build smoke test" step, which builds the image but does NOT push. That's the right place for PR-time verification. Removing the trigger here aligns claude-code with the canonical 7 templates and stops the GHCR leak. While here, updated the runtime_version comment to drop the now- stale "/PR" reference. --- .github/workflows/publish-image.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-image.yml b/.github/workflows/publish-image.yml index 69052f1..54ce7cc 100644 --- a/.github/workflows/publish-image.yml +++ b/.github/workflows/publish-image.yml @@ -14,7 +14,12 @@ on: types: [runtime-published] push: branches: [main] - pull_request: + # NOTE: do NOT add `pull_request:` here. The reusable + # publish-template-image workflow has no PR-skip guard, so a PR + # trigger pushes per-PR :latest clobbers and sha-<7> tags for + # unmerged code to GHCR. PRs already get a Dockerfile build smoke + # test from the validate-workspace-template workflow (no push) — + # that's the right place for PR-time verification. workflow_dispatch: inputs: runtime_version: @@ -35,6 +40,6 @@ jobs: # exact version PyPI just published. Forwarded to the reusable # workflow as a docker --build-arg so the cache key changes # per-version and pip install resolves freshly. - # On other events (push/PR/manual without input), this is empty - # and the Dockerfile's default (requirements.txt pin) applies. + # On other events (push to main / manual without input), this is + # empty and the Dockerfile's default (requirements.txt pin) applies. runtime_version: ${{ github.event.client_payload.runtime_version || inputs.runtime_version || '' }}