Optimize container workflow with artifact transfer between jobs

Eliminate duplicate builds by transferring built images via artifacts:
  - Build job: Export multi-platform image as OCI archive artifact
  - Push job: Download and push pre-built image (no rebuild)

  Additional performance improvements:
  - Upgrade docker/build-push-action from v5 to v6
  - Change cache scoping from SHA-based to branch-based
    - Previous: scope=build-${{ github.sha }} (per commit)
    - New: scope=build-${{ github.ref_name }} (per branch)
  - Add multi-source cache fallback (current branch → main)
  - Set artifact retention to 1 day

  Impact:
  - Push job no longer rebuilds - just loads and pushes artifact
  - Subsequent commits on same branch share cache
  - New branches leverage main branch cache
  - Significant reduction in total workflow time
This commit is contained in:
Christian Schoch
2025-12-27 00:36:21 +01:00
parent a05510c575
commit 36c056a8e0

View File

@@ -88,7 +88,7 @@ jobs:
id: buildx
uses: docker/setup-buildx-action@v3
- name: Build Image
- name: Build Image and Export
uses: docker/build-push-action@v6
with:
build-args: REPO=${{ github.repository }}
@@ -99,45 +99,42 @@ jobs:
cache-to: type=gha,mode=max,scope=build-${{ github.ref_name }}
file: Dockerfile
platforms: ${{ env.BUILD_PLATFORM }}
push: false
outputs: type=oci,dest=/tmp/image.tar
target: runtime-image
# Build and push image to GitHub Packages.
# See also https://docs.docker.com/docker-hub/builds/
- name: Upload image artifact
uses: actions/upload-artifact@v4
with:
name: docker-image
path: /tmp/image.tar
retention-days: 1
# Load artifact and push to registry
push:
runs-on: ubuntu-latest
if: github.event_name == 'push'
needs: [prepare, build]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Download image artifact
uses: actions/download-artifact@v4
with:
name: docker-image
path: /tmp
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Log into registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build Runtime Image and Push
uses: docker/build-push-action@v6
with:
build-args: REPO=${{ github.repository }}
context: .
cache-from: |
type=gha,scope=build-${{ github.ref_name }}
type=gha,scope=build-main
cache-to: type=gha,mode=max,scope=build-${{ github.ref_name }}
file: Dockerfile
platforms: ${{ env.BUILD_PLATFORM }}
push: true
tags: |
${{ needs.prepare.outputs.DOCKER_REPOSITORY }}:${{ needs.prepare.outputs.DOCKER_TAG }}
${{ needs.prepare.outputs.DOCKER_REPOSITORY }}:${{ github.sha }}
target: runtime-image
- name: Load and Push Image
run: |
docker load --input /tmp/image.tar
docker tag $(docker images -q | head -n1) ${{ needs.prepare.outputs.DOCKER_REPOSITORY }}:${{ needs.prepare.outputs.DOCKER_TAG }}
docker tag $(docker images -q | head -n1) ${{ needs.prepare.outputs.DOCKER_REPOSITORY }}:${{ github.sha }}
docker push ${{ needs.prepare.outputs.DOCKER_REPOSITORY }}:${{ needs.prepare.outputs.DOCKER_TAG }}
docker push ${{ needs.prepare.outputs.DOCKER_REPOSITORY }}:${{ github.sha }}
- name: Inspect image
if: success()