diff --git a/.github/workflows/gated-pipeline.yml b/.github/workflows/gated-pipeline.yml index cf488966a..697bc4700 100644 --- a/.github/workflows/gated-pipeline.yml +++ b/.github/workflows/gated-pipeline.yml @@ -1421,6 +1421,12 @@ jobs: echo "Image $IMAGE not found — will build" fi + - name: Pull existing image from GHCR + if: steps.check.outputs.exists == 'true' + shell: bash + run: | + docker pull "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }}" + - name: Extract metadata (tags, labels) id: meta if: steps.check.outputs.exists != 'true' @@ -1446,7 +1452,9 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha,scope=${{ matrix.image }} + cache-from: | + type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }} + type=gha,scope=${{ matrix.image }} cache-to: type=gha,mode=max,scope=${{ matrix.image }} build-args: | BUILD_DATE=${{ github.event.head_commit.timestamp || github.run_started_at }} @@ -1506,6 +1514,12 @@ jobs: echo "Image $IMAGE not found — will build" fi + - name: Pull existing image from GHCR + if: steps.check.outputs.exists == 'true' + shell: bash + run: | + docker pull "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }}" + - name: Extract metadata (tags, labels) id: meta if: steps.check.outputs.exists != 'true' @@ -1531,7 +1545,9 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha,scope=${{ matrix.image }} + cache-from: | + type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }} + type=gha,scope=${{ matrix.image }} cache-to: type=gha,mode=max,scope=${{ matrix.image }} build-args: | BASE_REGISTRY=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -1569,8 +1585,28 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Check if image already exists in GHCR + id: check + shell: bash + run: | + IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/devcontainer:${{ github.ref_name }}" + if docker manifest inspect "$IMAGE" > /dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "Image $IMAGE already exists — skipping build" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + echo "Image $IMAGE not found — will build" + fi + + - name: Pull existing image from GHCR + if: steps.check.outputs.exists == 'true' + shell: bash + run: | + docker pull "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/devcontainer:${{ github.ref_name }}" + - name: Extract metadata (tags, labels) id: meta + if: steps.check.outputs.exists != 'true' uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/devcontainer @@ -1584,6 +1620,7 @@ jobs: - name: Build and push Docker image id: build + if: steps.check.outputs.exists != 'true' uses: docker/build-push-action@v6 with: context: . @@ -1592,7 +1629,9 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha,scope=devcontainer + cache-from: | + type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/devcontainer:${{ github.ref_name }} + type=gha,scope=devcontainer cache-to: type=gha,mode=max,scope=devcontainer build-args: | BASE_REGISTRY=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -1600,6 +1639,7 @@ jobs: VCS_REF=${{ github.sha }} - name: Generate artifact attestation + if: steps.check.outputs.exists != 'true' uses: actions/attest-build-provenance@v4 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/devcontainer @@ -1657,8 +1697,28 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Check if image already exists in GHCR + id: check + shell: bash + run: | + IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }}" + if docker manifest inspect "$IMAGE" > /dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "Image $IMAGE already exists — skipping build" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + echo "Image $IMAGE not found — will build" + fi + + - name: Pull existing image from GHCR + if: steps.check.outputs.exists == 'true' + shell: bash + run: | + docker pull "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }}" + - name: Extract metadata (tags, labels) id: meta + if: steps.check.outputs.exists != 'true' uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }} @@ -1672,6 +1732,7 @@ jobs: - name: Build and push Docker image id: build + if: steps.check.outputs.exists != 'true' uses: docker/build-push-action@v6 with: context: ${{ matrix.context }} @@ -1679,7 +1740,9 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha,scope=${{ matrix.image }} + cache-from: | + type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}:${{ github.ref_name }} + type=gha,scope=${{ matrix.image }} cache-to: type=gha,mode=max,scope=${{ matrix.image }} build-args: | BASE_REGISTRY=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -1688,6 +1751,7 @@ jobs: VERSION=${{ steps.meta.outputs.version }} - name: Generate artifact attestation + if: steps.check.outputs.exists != 'true' uses: actions/attest-build-provenance@v4 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.image }}