Skip to content

Commit 266f585

Browse files
committed
fix: use crane copy for multi-arch image promotion
Replace skopeo with crane for copying images between registries. Crane preserves multi-arch manifests by default and avoids credential leakage by using docker/login-action instead of inline --dest-creds.
1 parent 6c2090f commit 266f585

1 file changed

Lines changed: 18 additions & 11 deletions

File tree

.github/workflows/promote-docker-image.yml

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,32 +82,39 @@ jobs:
8282
needs: [validate-inputs]
8383
runs-on: ubuntu-latest
8484
steps:
85-
- name: Copy image to production registry
85+
- name: Log in to Docker Hub
86+
uses: docker/login-action@v3
87+
with:
88+
username: ${{ secrets.DOCKERHUB_USERNAME }}
89+
password: ${{ secrets.DOCKERHUB_TOKEN }}
90+
91+
- name: Install crane
92+
run: |
93+
curl -sL https://github.com/google/go-containerregistry/releases/latest/download/go-containerregistry_Linux_x86_64.tar.gz | tar xz crane
94+
sudo mv crane /usr/local/bin/
95+
96+
- name: Promote image
8697
uses: actions/github-script@v8
8798
env:
8899
SOURCE_TAG: ${{ needs.validate-inputs.outputs.source-tag-safe }}
89100
TARGET_TAGS: ${{ needs.validate-inputs.outputs.target-tags-safe }}
90101
IMAGE_NAME: ${{ inputs.image-name }}
91-
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
92-
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
93102
with:
94103
script: |
95104
const { execSync } = require('child_process');
96105
const sourceTag = process.env.SOURCE_TAG;
97106
const targetTags = JSON.parse(process.env.TARGET_TAGS);
98107
const imageName = process.env.IMAGE_NAME;
99-
const source = `docker://temporaliotest/${imageName}:${sourceTag}`;
100-
const destCreds = `--dest-creds=${process.env.DOCKERHUB_USERNAME}:${process.env.DOCKERHUB_TOKEN}`;
108+
const source = `temporaliotest/${imageName}:${sourceTag}`;
101109
102110
core.info(`Promoting ${imageName} image...`);
103-
core.info(` From: temporaliotest/${imageName}:${sourceTag}`);
111+
core.info(` From: ${source}`);
104112
core.info(` To: ${targetTags.map(t => `temporalio/${imageName}:${t}`).join(', ')}`);
105113
106-
// Use skopeo copy --all to preserve the full manifest list (multi-arch) and all labels/annotations
107-
for (const targetTag of targetTags) {
108-
const target = `docker://temporalio/${imageName}:${targetTag}`;
114+
for (const tag of targetTags) {
115+
const target = `temporalio/${imageName}:${tag}`;
109116
core.info(`Copying ${source} -> ${target}`);
110-
execSync(`docker run --rm -i quay.io/skopeo/stable copy ${destCreds} --all ${source} ${target}`, { stdio: 'inherit' });
117+
execSync(`crane copy ${source} ${target}`, { stdio: 'inherit' });
111118
}
112119
113-
core.info(`${imageName} image promoted successfully to all tags`);
120+
core.info(`${imageName} image promoted successfully to all tags`);

0 commit comments

Comments
 (0)