diff --git a/.gitea/workflows/build-containers-on-demand.yml b/.gitea/workflows/build-containers-on-demand.yml index 484fec4..c1f79a0 100644 --- a/.gitea/workflows/build-containers-on-demand.yml +++ b/.gitea/workflows/build-containers-on-demand.yml @@ -231,12 +231,51 @@ jobs: if: steps.img.outputs.changed != 'true' run: echo "${{ matrix.description }} image tag unchanged; skipping build." - - name: Set up Buildx + - name: Check if image exists on registry if: steps.img.outputs.changed == 'true' + id: check_image + shell: bash + run: | + set -euo pipefail + new_repo="${{ steps.img.outputs.new_repo }}" + new_tag="${{ steps.img.outputs.new_tag }}" + registry_user="${{ secrets.REGISTRY_USER }}" + registry_password="${{ secrets.REGISTRY_PASSWORD }}" + + # Extract registry host and image name + registry_host=$(echo "$new_repo" | cut -d/ -f1) + image_path=$(echo "$new_repo" | cut -d/ -f2-) + + echo "Checking if $new_repo:$new_tag exists on registry $registry_host" + + # Use Docker Registry API v2 to check manifest + # Format: https://registry/v2/{image_path}/manifests/{tag} + manifest_url="https://${registry_host}/v2/${image_path}/manifests/${new_tag}" + + # Check with authentication + http_code=$(curl -s -o /dev/null -w "%{http_code}" \ + -u "${registry_user}:${registry_password}" \ + -H "Accept: application/vnd.docker.distribution.manifest.v2+json,application/vnd.docker.distribution.manifest.list.v2+json" \ + "$manifest_url" || echo "000") + + if [ "$http_code" = "200" ]; then + echo "Image already exists on registry (HTTP $http_code)" + echo "exists=true" >> "$GITHUB_OUTPUT" + else + echo "Image does not exist on registry (HTTP $http_code)" + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Skip if image already exists + if: steps.img.outputs.changed == 'true' && steps.check_image.outputs.exists == 'true' + run: echo "${{ matrix.description }} image ${{ steps.img.outputs.new_image }} already exists on registry; skipping build." + + - name: Set up Buildx + if: steps.img.outputs.changed == 'true' && steps.check_image.outputs.exists == 'false' uses: docker/setup-buildx-action@v3 - name: Log in to registry - if: steps.img.outputs.changed == 'true' + if: steps.img.outputs.changed == 'true' && steps.check_image.outputs.exists == 'false' uses: docker/login-action@v3 with: registry: ${{ steps.img.outputs.registry }} @@ -244,7 +283,7 @@ jobs: password: ${{ secrets.REGISTRY_PASSWORD }} - name: Build and push ${{ matrix.description }} (exact tag from deployment) - if: steps.img.outputs.changed == 'true' + if: steps.img.outputs.changed == 'true' && steps.check_image.outputs.exists == 'false' uses: docker/build-push-action@v6 with: context: ${{ matrix.build_context }}