diff --git a/.github/workflows/check_latest.yml b/.github/workflows/check_latest.yml new file mode 100644 index 00000000..d5556981 --- /dev/null +++ b/.github/workflows/check_latest.yml @@ -0,0 +1,42 @@ +name: Check if Latest Version + +on: + workflow_call: + outputs: + is_latest: + description: "True if the pushed tag is the highest semver release tag overall." + value: ${{ jobs.check.outputs.is_latest }} + is_latest_major: + description: "True if the pushed tag is the highest release tag within its major version." + value: ${{ jobs.check.outputs.is_latest_major }} + +jobs: + check: + name: Check if Latest Version + runs-on: ubuntu-latest + outputs: + is_latest: ${{ steps.check.outputs.is_latest }} + is_latest_major: ${{ steps.check.outputs.is_latest_major }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if this is the latest semver tag + id: check + run: | + LATEST=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1) + if [[ "$LATEST" == "$GITHUB_REF_NAME" ]]; then + echo "is_latest=true" >> $GITHUB_OUTPUT + else + echo "is_latest=false" >> $GITHUB_OUTPUT + fi + + PUSHED_MAJOR=$(echo "$GITHUB_REF_NAME" | grep -oE '^v[0-9]+') + LATEST_FOR_MAJOR=$(git tag --sort=-version:refname | grep -E "^${PUSHED_MAJOR}\.[0-9]+\.[0-9]+$" | head -1) + if [[ "$LATEST_FOR_MAJOR" == "$GITHUB_REF_NAME" ]]; then + echo "is_latest_major=true" >> $GITHUB_OUTPUT + else + echo "is_latest_major=false" >> $GITHUB_OUTPUT + fi diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml index e08fb83f..b103ab10 100644 --- a/.github/workflows/ghcr.yml +++ b/.github/workflows/ghcr.yml @@ -6,17 +6,24 @@ on: - 'v*' jobs: + check-latest: + name: Check if Latest Version + uses: ./.github/workflows/check_latest.yml + build-base: name: Base Image + needs: check-latest uses: ./.github/workflows/image_base.yml with: platforms: linux/amd64,linux/arm64 + latest: ${{ needs.check-latest.outputs.is_latest == 'true' }} + latest_major: ${{ needs.check-latest.outputs.is_latest_major == 'true' }} secrets: inherit build-app: name: App Image uses: ./.github/workflows/image_app.yml - needs: build-base + needs: [build-base, check-latest] strategy: # Will build all images even if some fail. fail-fast: false @@ -53,4 +60,6 @@ jobs: with: name: ${{ matrix.name }} platforms: ${{ matrix.platforms }} + latest: ${{ needs.check-latest.outputs.is_latest == 'true' }} + latest_major: ${{ needs.check-latest.outputs.is_latest_major == 'true' }} secrets: inherit diff --git a/.github/workflows/ghcr_intel.yml b/.github/workflows/ghcr_intel.yml index 1bc93a31..1c3ea34c 100644 --- a/.github/workflows/ghcr_intel.yml +++ b/.github/workflows/ghcr_intel.yml @@ -6,19 +6,26 @@ on: - 'v*' jobs: + check-latest: + name: Check if Latest Version + uses: ./.github/workflows/check_latest.yml + build-base: name: Base Image + needs: check-latest uses: ./.github/workflows/image_base.yml with: flavor: intel platforms: linux/amd64 dockerfile: Dockerfile.intel + latest: ${{ needs.check-latest.outputs.is_latest == 'true' }} + latest_major: ${{ needs.check-latest.outputs.is_latest_major == 'true' }} secrets: inherit build-app: name: App Image uses: ./.github/workflows/image_app.yml - needs: build-base + needs: [build-base, check-latest] strategy: # Will build all images even if some fail. fail-fast: false @@ -43,4 +50,6 @@ jobs: flavor: intel platforms: ${{ matrix.platforms }} dockerfile: ${{ matrix.dockerfile }} + latest: ${{ needs.check-latest.outputs.is_latest == 'true' }} + latest_major: ${{ needs.check-latest.outputs.is_latest_major == 'true' }} secrets: inherit diff --git a/.github/workflows/ghcr_nvidia.yml b/.github/workflows/ghcr_nvidia.yml index 594241d3..f944617b 100644 --- a/.github/workflows/ghcr_nvidia.yml +++ b/.github/workflows/ghcr_nvidia.yml @@ -6,19 +6,26 @@ on: - 'v*' jobs: + check-latest: + name: Check if Latest Version + uses: ./.github/workflows/check_latest.yml + build-base: name: Base Image + needs: check-latest uses: ./.github/workflows/image_base.yml with: flavor: nvidia platforms: linux/amd64 dockerfile: Dockerfile.nvidia + latest: ${{ needs.check-latest.outputs.is_latest == 'true' }} + latest_major: ${{ needs.check-latest.outputs.is_latest_major == 'true' }} secrets: inherit build-app: name: App Image uses: ./.github/workflows/image_app.yml - needs: build-base + needs: [build-base, check-latest] strategy: # Will build all images even if some fail. fail-fast: false @@ -39,4 +46,6 @@ jobs: flavor: nvidia platforms: ${{ matrix.platforms }} dockerfile: ${{ matrix.dockerfile }} + latest: ${{ needs.check-latest.outputs.is_latest == 'true' }} + latest_major: ${{ needs.check-latest.outputs.is_latest_major == 'true' }} secrets: inherit diff --git a/.github/workflows/image_app.yml b/.github/workflows/image_app.yml index db667538..0b11a0d1 100644 --- a/.github/workflows/image_app.yml +++ b/.github/workflows/image_app.yml @@ -22,6 +22,16 @@ on: type: string default: "Dockerfile" description: "The Dockerfile to use for building the image." + latest: + required: false + type: boolean + default: true + description: "Whether to update the latest tag (set to false for maintenance branches)." + latest_major: + required: false + type: boolean + default: true + description: "Whether to update the major tag (set to false if a newer patch exists in this major)." env: FLAVOR_PREFIX: ${{ inputs.flavor && format('{0}-', inputs.flavor) || '' }} @@ -47,11 +57,13 @@ jobs: id: meta with: images: ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}${{ inputs.name }} + flavor: | + latest=${{ inputs.latest && 'auto' || 'false' }} tags: | type=edge,branch=master type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} + type=semver,pattern={{major}},enable=${{ inputs.latest_major }} type=sha,format=long - name: Log in to the Container registry diff --git a/.github/workflows/image_base.yml b/.github/workflows/image_base.yml index 3ed7432a..18cbb273 100644 --- a/.github/workflows/image_base.yml +++ b/.github/workflows/image_base.yml @@ -18,6 +18,16 @@ on: type: string default: "Dockerfile" description: "The Dockerfile to use for building the image." + latest: + required: false + type: boolean + default: true + description: "Whether to update the latest tag (set to false for maintenance branches)." + latest_major: + required: false + type: boolean + default: true + description: "Whether to update the major tag (set to false if a newer patch exists in this major)." env: FLAVOR_PREFIX: ${{ inputs.flavor && format('{0}-', inputs.flavor) || '' }} @@ -54,11 +64,13 @@ jobs: id: meta with: images: ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}base + flavor: | + latest=${{ inputs.latest && 'auto' || 'false' }} tags: | type=edge,branch=master type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} + type=semver,pattern={{major}},enable=${{ inputs.latest_major }} type=sha,format=long - name: Log in to the Container registry