mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
perf(ci): pull from GHCR when image exists instead of just skipping
When a base or app image already exists in GHCR, pull it to the local runner rather than exiting after the manifest check. This makes the image immediately available for any downstream steps (security scanning, smoke tests, dependent builds) without a rebuild. Flow per image job: exists=true → docker pull <image>:<branch> (fast, ~seconds) exists=false → full build + push to GHCR Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
72
.github/workflows/gated-pipeline.yml
vendored
72
.github/workflows/gated-pipeline.yml
vendored
@@ -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 }}
|
||||
|
||||
Reference in New Issue
Block a user