Skip to content

when using labels across multiple tags, the label is only applied to 1 of the tags (at random) #534

@nickboldt

Description

@nickboldt

Contributing guidelines

I've found a bug, and:

  • The documentation does not mention anything about my problem
  • 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

Image

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions