mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
ci: Tag Docker images (#28088)
This commit is contained in:
parent
fef91c97dd
commit
a23fc0a867
26
.github/scripts/docker/docker-tags.mjs
vendored
26
.github/scripts/docker/docker-tags.mjs
vendored
|
|
@ -9,7 +9,7 @@ class TagGenerator {
|
||||||
this.githubOutput = process.env.GITHUB_OUTPUT || null;
|
this.githubOutput = process.env.GITHUB_OUTPUT || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
generate({ image, version, platform, includeDockerHub = false }) {
|
generate({ image, version, platform, includeDockerHub = false, sha = '' }) {
|
||||||
let imageName = image;
|
let imageName = image;
|
||||||
let versionSuffix = '';
|
let versionSuffix = '';
|
||||||
|
|
||||||
|
|
@ -27,6 +27,21 @@ class TagGenerator {
|
||||||
};
|
};
|
||||||
|
|
||||||
tags.all = [...tags.ghcr, ...tags.docker];
|
tags.all = [...tags.ghcr, ...tags.docker];
|
||||||
|
|
||||||
|
// Generate additional SHA-based tags for immutable references
|
||||||
|
if (sha) {
|
||||||
|
const shaVersion = `${version}-${sha}`;
|
||||||
|
const shaPlatformTag = `${shaVersion}${versionSuffix}${platformSuffix}`;
|
||||||
|
const shaGhcr = [`ghcr.io/${this.githubOwner}/${imageName}:${shaPlatformTag}`];
|
||||||
|
const shaDocker = includeDockerHub
|
||||||
|
? [`${this.dockerUsername}/${imageName}:${shaPlatformTag}`]
|
||||||
|
: [];
|
||||||
|
tags.all = [...tags.all, ...shaGhcr, ...shaDocker];
|
||||||
|
tags.ghcr = [...tags.ghcr, ...shaGhcr];
|
||||||
|
tags.docker = [...tags.docker, ...shaDocker];
|
||||||
|
tags.shaPrimaryTag = shaGhcr[0].replace(/-amd64$|-arm64$/, '');
|
||||||
|
}
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,18 +55,21 @@ class TagGenerator {
|
||||||
`${prefixStr}docker_tag=${tags.docker[0] || ''}`,
|
`${prefixStr}docker_tag=${tags.docker[0] || ''}`,
|
||||||
`${prefixStr}primary_tag=${primaryTag}`,
|
`${prefixStr}primary_tag=${primaryTag}`,
|
||||||
];
|
];
|
||||||
|
if (tags.shaPrimaryTag) {
|
||||||
|
outputs.push(`${prefixStr}sha_primary_tag=${tags.shaPrimaryTag}`);
|
||||||
|
}
|
||||||
appendFileSync(this.githubOutput, outputs.join('\n') + '\n');
|
appendFileSync(this.githubOutput, outputs.join('\n') + '\n');
|
||||||
} else {
|
} else {
|
||||||
console.log(JSON.stringify(tags, null, 2));
|
console.log(JSON.stringify(tags, null, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateAll({ version, platform, includeDockerHub = false }) {
|
generateAll({ version, platform, includeDockerHub = false, sha = '' }) {
|
||||||
const images = ['n8n', 'runners', 'runners-distroless'];
|
const images = ['n8n', 'runners', 'runners-distroless'];
|
||||||
const results = {};
|
const results = {};
|
||||||
|
|
||||||
for (const image of images) {
|
for (const image of images) {
|
||||||
const tags = this.generate({ image, version, platform, includeDockerHub });
|
const tags = this.generate({ image, version, platform, includeDockerHub, sha });
|
||||||
const prefix = image.replace('-distroless', '_distroless');
|
const prefix = image.replace('-distroless', '_distroless');
|
||||||
results[prefix] = tags;
|
results[prefix] = tags;
|
||||||
|
|
||||||
|
|
@ -86,6 +104,7 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
version,
|
version,
|
||||||
platform: getArg('platform'),
|
platform: getArg('platform'),
|
||||||
includeDockerHub: hasFlag('include-docker'),
|
includeDockerHub: hasFlag('include-docker'),
|
||||||
|
sha: getArg('sha') || '',
|
||||||
});
|
});
|
||||||
if (!generator.githubOutput) {
|
if (!generator.githubOutput) {
|
||||||
console.log(JSON.stringify(results, null, 2));
|
console.log(JSON.stringify(results, null, 2));
|
||||||
|
|
@ -101,6 +120,7 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
version,
|
version,
|
||||||
platform: getArg('platform'),
|
platform: getArg('platform'),
|
||||||
includeDockerHub: hasFlag('include-docker'),
|
includeDockerHub: hasFlag('include-docker'),
|
||||||
|
sha: getArg('sha') || '',
|
||||||
});
|
});
|
||||||
generator.output(tags);
|
generator.output(tags);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
.github/workflows/docker-build-push.yml
vendored
25
.github/workflows/docker-build-push.yml
vendored
|
|
@ -79,6 +79,9 @@ jobs:
|
||||||
primary_ghcr_manifest_tag: ${{ steps.determine-tags.outputs.n8n_primary_tag }}
|
primary_ghcr_manifest_tag: ${{ steps.determine-tags.outputs.n8n_primary_tag }}
|
||||||
runners_primary_ghcr_manifest_tag: ${{ steps.determine-tags.outputs.runners_primary_tag }}
|
runners_primary_ghcr_manifest_tag: ${{ steps.determine-tags.outputs.runners_primary_tag }}
|
||||||
runners_distroless_primary_ghcr_manifest_tag: ${{ steps.determine-tags.outputs.runners_distroless_primary_tag }}
|
runners_distroless_primary_ghcr_manifest_tag: ${{ steps.determine-tags.outputs.runners_distroless_primary_tag }}
|
||||||
|
n8n_sha_manifest_tag: ${{ steps.determine-tags.outputs.n8n_sha_primary_tag }}
|
||||||
|
runners_sha_manifest_tag: ${{ steps.determine-tags.outputs.runners_sha_primary_tag }}
|
||||||
|
runners_distroless_sha_manifest_tag: ${{ steps.determine-tags.outputs.runners_distroless_sha_primary_tag }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
|
@ -101,6 +104,7 @@ jobs:
|
||||||
--all \
|
--all \
|
||||||
--version "${{ needs.determine-build-context.outputs.n8n_version }}" \
|
--version "${{ needs.determine-build-context.outputs.n8n_version }}" \
|
||||||
--platform "${{ matrix.docker_platform }}" \
|
--platform "${{ matrix.docker_platform }}" \
|
||||||
|
--sha "${GITHUB_SHA::7}" \
|
||||||
${{ needs.determine-build-context.outputs.push_to_docker == 'true' && '--include-docker' || '' }}
|
${{ needs.determine-build-context.outputs.push_to_docker == 'true' && '--include-docker' || '' }}
|
||||||
|
|
||||||
echo "=== Generated Docker Tags ==="
|
echo "=== Generated Docker Tags ==="
|
||||||
|
|
@ -228,6 +232,11 @@ jobs:
|
||||||
create_manifest "runners" "${{ needs.build-and-push-docker.outputs.runners_primary_ghcr_manifest_tag }}"
|
create_manifest "runners" "${{ needs.build-and-push-docker.outputs.runners_primary_ghcr_manifest_tag }}"
|
||||||
create_manifest "runners-distroless" "${{ needs.build-and-push-docker.outputs.runners_distroless_primary_ghcr_manifest_tag }}"
|
create_manifest "runners-distroless" "${{ needs.build-and-push-docker.outputs.runners_distroless_primary_ghcr_manifest_tag }}"
|
||||||
|
|
||||||
|
# Create SHA-tagged manifests (immutable references for deployments)
|
||||||
|
create_manifest "n8n (sha)" "${{ needs.build-and-push-docker.outputs.n8n_sha_manifest_tag }}"
|
||||||
|
create_manifest "runners (sha)" "${{ needs.build-and-push-docker.outputs.runners_sha_manifest_tag }}"
|
||||||
|
create_manifest "runners-distroless (sha)" "${{ needs.build-and-push-docker.outputs.runners_distroless_sha_manifest_tag }}"
|
||||||
|
|
||||||
- name: Create Docker Hub manifests
|
- name: Create Docker Hub manifests
|
||||||
if: needs.determine-build-context.outputs.push_to_docker == 'true'
|
if: needs.determine-build-context.outputs.push_to_docker == 'true'
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -241,6 +250,8 @@ jobs:
|
||||||
["runners-distroless"]="${VERSION}-distroless"
|
["runners-distroless"]="${VERSION}-distroless"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SHORT_SHA="${GITHUB_SHA::7}"
|
||||||
|
|
||||||
for image in "${!images[@]}"; do
|
for image in "${!images[@]}"; do
|
||||||
TAG_SUFFIX="${images[$image]}"
|
TAG_SUFFIX="${images[$image]}"
|
||||||
IMAGE_NAME="${image//-distroless/}" # Remove -distroless from image name
|
IMAGE_NAME="${image//-distroless/}" # Remove -distroless from image name
|
||||||
|
|
@ -250,6 +261,20 @@ jobs:
|
||||||
--tag "${DOCKER_BASE}/${IMAGE_NAME}:${TAG_SUFFIX}" \
|
--tag "${DOCKER_BASE}/${IMAGE_NAME}:${TAG_SUFFIX}" \
|
||||||
"${DOCKER_BASE}/${IMAGE_NAME}:${TAG_SUFFIX}-amd64" \
|
"${DOCKER_BASE}/${IMAGE_NAME}:${TAG_SUFFIX}-amd64" \
|
||||||
"${DOCKER_BASE}/${IMAGE_NAME}:${TAG_SUFFIX}-arm64"
|
"${DOCKER_BASE}/${IMAGE_NAME}:${TAG_SUFFIX}-arm64"
|
||||||
|
|
||||||
|
# Create SHA-tagged manifest (immutable reference)
|
||||||
|
# For distroless, insert SHA between version and -distroless suffix
|
||||||
|
# to match docker-tags.mjs format: nightly-abc1234-distroless (not nightly-distroless-abc1234)
|
||||||
|
if [[ "$image" == *"-distroless"* ]]; then
|
||||||
|
SHA_SUFFIX="${VERSION}-${SHORT_SHA}-distroless"
|
||||||
|
else
|
||||||
|
SHA_SUFFIX="${TAG_SUFFIX}-${SHORT_SHA}"
|
||||||
|
fi
|
||||||
|
echo "Creating Docker Hub SHA manifest for $image: ${SHA_SUFFIX}"
|
||||||
|
docker buildx imagetools create \
|
||||||
|
--tag "${DOCKER_BASE}/${IMAGE_NAME}:${SHA_SUFFIX}" \
|
||||||
|
"${DOCKER_BASE}/${IMAGE_NAME}:${SHA_SUFFIX}-amd64" \
|
||||||
|
"${DOCKER_BASE}/${IMAGE_NAME}:${SHA_SUFFIX}-arm64"
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Get manifest digests for attestation
|
- name: Get manifest digests for attestation
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user