Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/build-docker-artifacts-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
"type": "string",
"description": "ECR repository to push the image to"
},
"image_tag_suffix": {
"type": "string",
"description": "Suffix to append to the image tag"
},
"image_tag_prefix": {
"type": "string",
"description": "Prefix to prepend to the image tag"
},
"scan_high_severity": {
"type": "boolean",
"default": true,
Expand Down Expand Up @@ -95,6 +103,14 @@
"type": "object",
"additionalProperties": false,
"properties": {
"image_tag_suffix": {
"type": "string",
"description": "Suffix to append to the image tag"
},
"image_tag_prefix": {
"type": "string",
"description": "Prefix to prepend to the image tag"
},
"source_repository": {
"type": "string",
"description": "Internal ECR repository name"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-docker-artifacts-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ jobs:
const filteredRepositories = customer.repositories.filter(repo => !repo.skip);

// Comma separated list of source images, incl. registry, repository and tag
const sourceImages = filteredRepositories.map(repo => `${process.env.SOURCE_ECR_REGISTRY}/${repo.source_repository}:${repo.source_image_tag || process.env.IMAGE_TAG}`).join(',');
const destinationImages = filteredRepositories.map(repo => `${customer.registry}/${repo.target_repository}:${repo.target_image_tag || process.env.IMAGE_TAG}`).join(',');
const sourceImages = filteredRepositories.map(repo => `${process.env.SOURCE_ECR_REGISTRY}/${repo.source_repository}:${repo.image_tag_prefix || ''}${repo.source_image_tag || process.env.IMAGE_TAG}${repo.image_tag_suffix || ''}`).join(',');
const destinationImages = filteredRepositories.map(repo => `${customer.registry}/${repo.target_repository}:${repo.image_tag_prefix || ''}${repo.target_image_tag || process.env.IMAGE_TAG}${repo.image_tag_suffix || ''}`).join(',');

const result = {
customer,
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-docker-artifacts-trigger-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ jobs:

const customers = process.env.PUSH_TO ? process.env.PUSH_TO.split(',') : Object.keys(config.push || {});

const imageTagBranchName = "${{ github.ref }}".replace('refs/heads/', '').replace('refs/tags/', '').replace(/[^a-zA-Z0-9._-]/g, '-');
const imageTagAfterRetag = "${{ github.ref }}".replace('refs/heads/', '').replace('refs/tags/', '').replace(/[^a-zA-Z0-9._-]/g, '-');

const result = customers.map((c) => ({
repository: process.env.REPOSITORY,
customer: c,
customer_json: JSON.stringify(config.push[c]),
image_tag: imageTagBranchName,
image_tag: imageTagAfterRetag,
}));
console.log(result);
return result;
Expand Down
42 changes: 21 additions & 21 deletions .github/workflows/build-docker-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ jobs:
const config = require('./deploy/build/config.json');

const buildTime = new Date().toISOString().replace(/:/g, '').replace(/\..+/, 'Z');
const imageTagBranchName = "${{ github.ref }}".replace('refs/heads/', '').replace('refs/tags/', '').replace(/[^a-zA-Z0-9._-]/g, '-');
const imageTag = `tagged-${imageTagBranchName}-${buildTime}`;

const builds = process.env.BUILDS ? process.env.BUILDS.split(',') : Object.keys(config.build);
const push_to = process.env.PUSH_TO ? process.env.PUSH_TO.split(',') : Object.keys(config.push || {});
Expand All @@ -116,9 +114,6 @@ jobs:
skip_retag: skip_push,
// Add metadata to the flavor object (will be used as matrix input)
build_time: buildTime,
image_tag: imageTag,
image_tag_branch_name: imageTagBranchName,
ecr_repositories: flavor.components.map(component => component.ecr_repository),
test_images: {
enabled: testImageEnabled,
script_path: testImagesHookScript,
Expand All @@ -129,6 +124,9 @@ jobs:
const formattedBuildArgs = component.build_args ?
Object.entries(component.build_args).map(([key, value]) => `${key}=${value}`).join('\n') : '';

const imageTagAfterRetag = (component.image_tag_prefix || '') + "${{ github.ref }}".replace('refs/heads/', '').replace('refs/tags/', '').replace(/[^a-zA-Z0-9._-]/g, '-') + (component.image_tag_suffix || '');
const imageTagBeforeRetag = `tagged-${imageTagAfterRetag}-${buildTime}`;
Comment on lines +127 to +128
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suffix and prefix are being applied in the wrong order when computing the "before retag" tag. The prefix/suffix should only be applied to the final tag (after retag), not to the temporary "tagged-" version.

Currently, the code creates:

  • imageTagBeforeRetag = "tagged-{prefix}{branch}{suffix}-{buildTime}"
  • imageTagAfterRetag = "{prefix}{branch}{suffix}"

This means the temporary build tag includes the prefix/suffix, which will cause issues during the retag operation since the retag process expects the build tag to follow the pattern tagged-{branch}-{buildTime}, and then applies the prefix/suffix only to the final tag.

The correct logic should be:

  • imageTagBeforeRetag = "tagged-{branch}-{buildTime}"
  • imageTagAfterRetag = "{prefix}{branch}{suffix}"

This way, the temporary build tag remains consistent with the existing pattern, and only the final retagged image gets the custom prefix/suffix.

Suggested change
const imageTagAfterRetag = (component.image_tag_prefix || '') + "${{ github.ref }}".replace('refs/heads/', '').replace('refs/tags/', '').replace(/[^a-zA-Z0-9._-]/g, '-') + (component.image_tag_suffix || '');
const imageTagBeforeRetag = `tagged-${imageTagAfterRetag}-${buildTime}`;
const branchTag = "${{ github.ref }}".replace('refs/heads/', '').replace('refs/tags/', '').replace(/[^a-zA-Z0-9._-]/g, '-');
const imageTagAfterRetag = (component.image_tag_prefix || '') + branchTag + (component.image_tag_suffix || '');
const imageTagBeforeRetag = `tagged-${branchTag}-${buildTime}`;

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that's correct, isn't it? The retag action reads from the variable, so no assumption is done...


return {
...component,
// We can skip the push only if we don't want to test the image below
Expand All @@ -138,9 +136,9 @@ jobs:
flavor_id: id,
flavor_directory: `./deploy/build/${flavor.directory}`,
build_time: buildTime,
image_tag: imageTag,
image_ref: `${{ vars.DV_AWS_ECR_REGISTRY }}/${component.ecr_repository}:${imageTag}`,
image_tag_branch_name: imageTagBranchName,
image_tag_before_retag: imageTagBeforeRetag,
image_ref: `${{ vars.DV_AWS_ECR_REGISTRY }}/${component.ecr_repository}:${imageTagBeforeRetag}`,
image_tag_after_retag: imageTagAfterRetag,
formatted_build_args: formattedBuildArgs,
};
}),
Expand All @@ -163,7 +161,7 @@ jobs:
PUSH_TO: ${{ inputs.push_to }}

build-flavors:
name: Build ${{ matrix.component.directory }} of ${{ matrix.component.flavor.directory }} (${{ matrix.component.ecr_repository }}:${{ matrix.component.image_tag }})
name: Build ${{ matrix.component.directory }} of ${{ matrix.component.flavor.directory }} (${{ matrix.component.ecr_repository }}:${{ matrix.component.image_tag_before_retag }})
needs: get-flavors
strategy:
fail-fast: ${{ inputs.fail_fast }}
Expand Down Expand Up @@ -247,6 +245,8 @@ jobs:
# Disable provenance as it creates weird multi-arch images: https://github.com/docker/build-push-action/issues/755
provenance: false
# Disable the cache to avoid outdated (base) images
# TODO: are we sure we want this? We might benefit a lot from caching! But also, our base images like datavisyn/base/python:main are updated frequently and have no version tag...
# maybe no-cache-filters works? Or we do this on our self-hosted runners: https://docs.docker.com/build/ci/github-actions/cache/#local-cache
no-cache: true
build-args: |
GIT_BRANCH=${{ steps.get-branch.outputs.branch }}
Expand All @@ -265,12 +265,12 @@ jobs:
${{ matrix.component.image_ref }}
labels: |
name=${{ matrix.component.ecr_repository }}
version=${{ matrix.component.image_tag_branch_name }}
version=${{ matrix.component.image_tag_after_retag }}
org.opencontainers.image.description=Image for ${{ matrix.component.ecr_repository }}
org.opencontainers.image.source=${{ github.event.repository.html_url }}
org.opencontainers.image.url=${{ github.event.repository.html_url }}
org.opencontainers.image.title=${{ matrix.component.ecr_repository }}
org.opencontainers.image.version=${{ matrix.component.image_tag_branch_name }}
org.opencontainers.image.version=${{ matrix.component.image_tag_after_retag }}
org.opencontainers.image.created=${{ matrix.component.build_time }}
org.opencontainers.image.revision=${{ github.sha }}
env:
Expand Down Expand Up @@ -426,19 +426,19 @@ jobs:
- name: Retag images
shell: bash
run: |
image_tag="${{ matrix.flavor.image_tag }}"
image_tag_branch_name="${{ matrix.flavor.image_tag_branch_name }}"
for component in $(jq -c '.components[]' <<< "$FLAVOR"); do
repository_name=$(jq -r '.ecr_repository' <<< "$component")
image_tag_before_retag=$(jq -r '.image_tag_before_retag' <<< "$component")
image_tag_after_retag=$(jq -r '.image_tag_after_retag' <<< "$component")

echo "image_tag=$image_tag"
echo "image_tag_branch_name=$image_tag_branch_name"
echo "Processing repository: $repository_name, image_tag_before_retag: $image_tag_before_retag, image_tag_after_retag: $image_tag_after_retag"

for repository_name in $(jq -r '.ecr_repositories[]' <<< "$FLAVOR"); do
IMAGE_META=$(aws ecr describe-images --repository-name "$repository_name" --image-ids imageTag="$image_tag" --output json | jq --arg var "${image_tag_branch_name}" '.imageDetails[0].imageTags | index( $var )')
if [[ -z "${IMAGE_META}" || ${IMAGE_META} == "null" ]]; then
MANIFEST=$(aws ecr batch-get-image --repository-name "$repository_name" --image-ids imageTag="$image_tag" --output json | jq --raw-output --join-output '.images[0].imageManifest')
aws ecr put-image --repository-name "$repository_name" --image-tag "$image_tag_branch_name" --image-manifest "$MANIFEST"
IMAGE_META=$(aws ecr describe-images --repository-name "$repository_name" --image-ids imageTag="$image_tag_before_retag" --output json | jq --arg var "${image_tag_after_retag}" '.imageDetails[0].imageTags | index($var)')
if [[ -z "${IMAGE_META}" || "${IMAGE_META}" == "null" ]]; then
MANIFEST=$(aws ecr batch-get-image --repository-name "$repository_name" --image-ids imageTag="$image_tag_before_retag" --output json | jq --raw-output --join-output '.images[0].imageManifest')
aws ecr put-image --repository-name "$repository_name" --image-tag "$image_tag_after_retag" --image-manifest "$MANIFEST"
else
echo "image already tagged!"
echo "Image already tagged for repository: $repository_name!"
fi
done;
env:
Expand Down