Skip to content

ci: Gate the Legacy Mirror Behind an Environment - #328

Merged
danny-avila merged 1 commit into
mainfrom
danny-avila/mirror-environment
Sep 24, 2026
Merged

danny-avila merged 1 commit into
mainfrom
danny-avila/mirror-environment

Conversation

@danny-avila

Copy link
Copy Markdown
Collaborator

Summary

The legacy-namespace mirror reads LEGACY_GHCR_TOKEN, a credential that can write packages under another account. As a repository secret read from inside the build job, every workflow in this repository can reach it, including one added on any branch.

This moves the mirror into its own job that declares the legacy-mirror environment, in both images.yaml and the reusable docker-build-workflow.yaml. Once the secret lives on that environment rather than the repository, only workflows running on the branches the environment allows can read it. Published images and tags are unchanged.

How it works

build (per image, amd64 + arm64)     ghcr.io/librechat-ai/<image>:{sha,tag}
  mirror (per image)                 environment: legacy-mirror -> ghcr.io/danny-avila/<image>

The mirror job recomputes the image names from the owner and the matrix, so it needs nothing from the build job beyond ordering. Its guards are unchanged: it skips when the legacy owner matches the publishing owner, and warns and exits 0 when the secret is missing.

Separating it also isolates failure. continue-on-error now sits on the job, so a mirror problem — including an environment that refuses the branch — leaves the publish green.

Turning it on

  1. Create an environment named legacy-mirror, with a deployment branch policy allowing main and tags, and no required reviewers (reviewers would stall every image build).
  2. Add LEGACY_GHCR_TOKEN as an environment secret there, and delete the repository-level secret. Until that move, the job still reads the repository secret and the gate does nothing.
  3. Ideally the token belongs to a machine account holding Write on only the legacy packages, with write:packages and no delete:packages, and an expiry matching the deprecation window.

Testing

  • actionlint 1.7.7 reports nothing new; the only findings are the pre-existing docker/login-action@v2 warnings.
  • The parsed job graph in both files is buildmirror, with mirror carrying environment: legacy-mirror, continue-on-error: true and the vars.LEGACY_GHCR_OWNER != '' guard.
  • I ran the job's shell body with post-move values: it resolves ghcr.io/librechat-ai/librechat-rag-api-dev:{abc1234,latest} to the matching ghcr.io/danny-avila/... tags.
  • The mirror logic is unchanged from run 35769542750, which published to the org and copied identical digests to the old namespace.

@danny-avila
danny-avila merged commit c4e5cbf into main Sep 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant