when using labels across multiple tags, the label is only applied to 1 of the tags (at random)
Contributing guidelines
- [x] I've read the contributing guidelines and wholeheartedly agree
I've found a bug, and:
- [x] The documentation does not mention anything about my problem
- [x] There are no open or closed issues that are related to my problem
Description
Using this code:
- name: Set container metadata (for releases, 183d expiry)
id: meta-release
if: ${{ env.REF_NAME_SHORT != 'next' }}
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}
tags: |
type=raw,value=${{ env.REF_NAME }}
type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }}
type=raw,value=${{ env.REF_NAME_SHORT }}
type=raw,value=${{ env.REF_NAME_SHORT }}-${{ env.SHORT_SHA }}
labels: |
quay.expires-after=183d
in this workflow:
https://github.com/redhat-developer/rhdh/blob/main/.github/workflows/next-build-image.yaml#L194-L206
when pushing a tag to the repo results in 4 correctly created tags, but ONLY ONE of them has the quay.expires-after=183d label applied; the other 3 have no tag expiration set.
You can see the created tags here https://quay.io/repository/rhdh-community/rhdh?tab=tags
Related downstream issue (in case this is a configuration problem or I've done something wrong): https://issues.redhat.com/browse/RHIDP-8270
Expected behaviour
all tags in a given push should get the same labels applied, not just whichever one is found first in the hashmap/array
Actual behaviour
only 1 of 4 tags has the correct expiration date set
Repository URL
https://github.com/redhat-developer/rhdh/actions/workflows/next-build-image.yaml
Workflow run URL
https://github.com/redhat-developer/rhdh/actions/runs/16476194526/job/46583106978
YAML workflow
name: Build Next and Tag Image
on:
# workflow_dispatch so that it can be triggered manually if needed
workflow_dispatch:
schedule:
# run at 3:18 UTC every day
- cron: "18 3 * * *"
# in addition to building multi-arch :next images daily,
# also build multi-arch images for any x.y or x.y.z tag pushed to the repo
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
REGISTRY: quay.io
REGISTRY_IMAGE: rhdh-community/rhdh
jobs:
build-image:
name: Build Image
strategy:
fail-fast: false
matrix:
os:
- ubuntu-24.04-arm
- ubuntu-24.04
runs-on: ${{ matrix.os }}
timeout-minutes: 720 # Set to 12 hours instead of default 360 = 6hrs
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Prepare
run: |
if [ "${{ matrix.os }}" == "ubuntu-24.04" ]; then
platform="linux/amd64"
elif [ "${{ matrix.os }}" == "ubuntu-24.04-arm" ]; then
platform="linux/arm64"
else
echo "Unknown platform"
exit 1
fi
ref_name=${{ github.ref_name }}
if [ "$ref_name" == "main" ]; then
ref_name="next"
fi
# from 1.6.1 => 1.6
ref_name_short="${ref_name%.*}"
if [[ $ref_name_short == "1" ]]; then
ref_name_short="${ref_name}"
fi
echo "REF_NAME=$ref_name" >> $GITHUB_ENV
echo "REF_NAME_SHORT=${ref_name_short}" >> $GITHUB_ENV
echo "PLATFORM=$platform" >> $GITHUB_ENV
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
echo "PLATFORM_ARCH=${platform#*/}" >> $GITHUB_ENV
- name: Get the last commit short SHA
uses: ./.github/actions/get-sha
- name: Build and Push with Buildx (for :next builds, 14d expiry)
uses: ./.github/actions/docker-build
id: build-next
if: ${{ env.REF_NAME_SHORT == 'next' }}
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
imageName: ${{ env.REGISTRY_IMAGE }}
imageTags: |
type=raw,value=${{ env.REF_NAME }}-${{ env.PLATFORM_ARCH }}
type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }}-${{ env.PLATFORM_ARCH }}
imageLabels: quay.expires-after=14d
push: true
platform: ${{ env.PLATFORM }}
- name: Build and Push with Buildx (for releases, 183d expiry)
uses: ./.github/actions/docker-build
id: build-release
if: ${{ env.REF_NAME_SHORT != 'next' }}
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
imageName: ${{ env.REGISTRY_IMAGE }}
imageTags: |
type=raw,value=${{ env.REF_NAME }}-${{ env.PLATFORM_ARCH }}
type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }}-${{ env.PLATFORM_ARCH }}
imageLabels: quay.expires-after=183d
push: true
platform: ${{ env.PLATFORM }}
- name: Export digest (for :next builds)
id: export-digest-next
if: ${{ env.REF_NAME_SHORT == 'next' }}
run: |
mkdir -p /tmp/digests
digest="${{ steps.build-next.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Export digest (for releases)
id: export-digest-release
if: ${{ env.REF_NAME_SHORT != 'next' }}
run: |
mkdir -p /tmp/digests
digest="${{ steps.build-release.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
needs:
- build-image
steps:
- name: Prepare
run: |
ref_name=${{ github.ref_name }}
if [ "$ref_name" == "main" ]; then
ref_name="next"
fi
# from 1.6.1 => 1.6
ref_name_short="${ref_name%.*}"
if [[ $ref_name_short == "1" ]]; then
ref_name_short="${ref_name}"
fi
echo "REF_NAME=$ref_name" >> $GITHUB_ENV
echo "REF_NAME_SHORT=${ref_name_short}" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Get the last commit short SHA
uses: ./.github/actions/get-sha
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set container metadata (for :next builds, 14d expiry)
id: meta-next
if: ${{ env.REF_NAME_SHORT == 'next'}}
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}
tags: |
type=raw,value=${{ env.REF_NAME }}
type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }}
labels: |
quay.expires-after=14d
- name: Set container metadata (for releases, 183d expiry)
id: meta-release
if: ${{ env.REF_NAME_SHORT != 'next' }}
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}
tags: |
type=raw,value=${{ env.REF_NAME }}
type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }}
type=raw,value=${{ env.REF_NAME_SHORT }}
type=raw,value=${{ env.REF_NAME_SHORT }}-${{ env.SHORT_SHA }}
labels: |
quay.expires-after=183d
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image (for :next builds)
id: inspect-next
if: ${{ env.REF_NAME_SHORT == 'next'}}
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}:${{ steps.meta-next.outputs.version }}
- name: Inspect image (for releases)
id: inspect-release
if: ${{ env.REF_NAME_SHORT != 'next'}}
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}:${{ steps.meta-release.outputs.version }}
Workflow logs
Problem occurs in the merge step but I've attached all three logs in case you want them
2_merge.txt 1_Build Image (ubuntu-24.04-arm).txt 0_Build Image (ubuntu-24.04).txt
BuildKit logs
Additional info
No response
FWIW the reason I think this the label is only being applied to the first item in the map is that earlier today when I was playing with 14d expiration dates, I had a different tag get the expiration:
I mean, it could be the last item in the map, but it seems clear that the order of items being pushed to quay varies, despite the order of them listed in my GH action workflow yaml.
Doesn't seem related to this action but this flow https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners where metadata are merged when creating the manifest list in merge job. In this flow we could probably use the --annotation flag of buildx imagetools create. Although only annotations are supported not labels. Does quay support annotations?
Also similar to https://github.com/docker/build-push-action/discussions/1022