Skip to content

fix(CI): Reduces CI time. Fixes #11768 #5

fix(CI): Reduces CI time. Fixes #11768

fix(CI): Reduces CI time. Fixes #11768 #5

Workflow file for this run

name: Build and Push images

Check failure on line 1 in .github/workflows/build-and-push.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/build-and-push.yml

Invalid workflow file

(Line: 115, Col: 9): Unrecognized named-value: 'env'. Located at position 16 within expression: inputs.push && env.SOURCE_BRANCH
run-name: Build images
on:
workflow_call:
inputs:
src_branch:
type: string
default: ''
description: 'Source branch to build KFP from'
required: false
target_tag:
type: string
default: 'X.Y.Z'
description: 'Target Image Tag'
required: true
overwrite_imgs:
type: string
default: 'true'
description: 'Overwrite images in GHCR if they already exist for this tag.'
required: false
set_latest:
type: string
default: 'true'
description: 'Set latest tag on build images.'
required: false
add_sha_tag:
type: string
default: 'true'
description: 'Add a sha image tag.'
required: false
app_to_build:
type: string
default: ''
description: 'Provide the app name to build'
required: true
image_context:
type: string
default: ''
description: 'Provide the docker file path'
required: true
docker_file:
type: string
default: ''
description: 'Provide the docker file name'
required: true
push:
type: boolean
default: false
description: 'Whether to push image to CR or not'
required: false
workflow_dispatch:
inputs:
src_branch:
type: string
default: ''
description: 'Source branch to build KFP from'
required: true
target_tag:
type: string
default: 'X.Y.Z'
description: 'Target Image Tag'
required: true
fail_fast:
type: string
default: 'true'
description: 'Stop running entire Workflow if a single build fails'
required: true
overwrite_imgs:
type: string
default: 'true'
description: 'Overwrite images in GHCR if they already exist for this tag.'
required: true
set_latest:
type: string
default: 'true'
description: 'Set latest tag on build images.'
required: true
add_sha_tag:
type: string
default: 'true'
description: 'Add a sha image tag.'
required: false
app_to_build:
type: string
default: ''
description: 'Provide the app name to build'
required: true
image_context:
type: string
default: ''
description: 'Provide the docker file path'
required: true
docker_file:
type: string
default: ''
description: 'Provide the docker file name'
required: true
push:
type: boolean
default: false
description: 'Whether to push image to CR or not'
required: true
env:
SOURCE_BRANCH: ${{ inputs.src_branch }}
TARGET_IMAGE_TAG: ${{ inputs.target_tag }}
OVERWRITE_IMAGES: ${{ inputs.overwrite_imgs }}
IMAGE_REGISTRY: ghcr.io
IMAGE_ORG: ${{ github.repository }}
SET_LATEST: ${{ inputs.set_latest }}
ADD_SHA_TAG: ${{ inputs.add_sha_tag }}
CACHE_PATH: '/tmp/.buildx-cache'
jobs:
build-and-push-images:
if: inputs.push && env.SOURCE_BRANCH
continue-on-error: false
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check if image tag already exists
id: check_tag
env:
IMAGE: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ inputs.app_to_build }}:${{env.TARGET_IMAGE_TAG}}
OVERWRITE: ${{ env.OVERWRITE_IMAGES }}
run: |
if docker manifest inspect ${IMAGE} > /dev/null 2>&1; then
echo "Image tag already exists!"
if [ "$OVERWRITE" == "false" ]; then
echo "Overwrite is set to false, exiting."
exit 1
else
echo "Overwrite is set to true, proceeding with push."
fi
else
echo "No tag conflict, safe to push."
fi
# This step uses docker/metadata-action to extract tags and labels
# that will be applied to the specified image. The id "meta" allows
# the output of this step to be referenced in a subsequent step.
# The images value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Build
id: meta
uses: docker/metadata-action@v5
if: steps.check_tag.outcome == 'success'
with:
images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ inputs.app_to_build }}
tags: |
type=raw,value=${{env.TARGET_IMAGE_TAG}}
type=raw,value=latest,enable=${{ env.SET_LATEST == 'true'}}
type=sha,enable=${{ env.ADD_SHA_TAG == 'true' }}
# Build the image. If the build succeeds, it pushes the image to GitHub
# Packages. It uses the context parameter to define the build's context
# as the set of files located in the specified path.
- name: Build and push Image
id: push
uses: docker/build-push-action@v6
if: steps.check_tag.outcome == 'success'
with:
context: ${{ inputs.image_context }}
file: ${{ inputs.docker_file }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# This step generates an artifact attestation for the image,
# which is an unforgeable statement about where and how it was built.
# It increases supply chain security for people who consume the
# image.
# Ref: https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
if: steps.check_tag.outcome == 'success'
with:
subject-name: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_ORG }}/${{ inputs.app_to_build }}
subject-digest: ${{ steps.push.outputs.digest }}
build-and-cache-images:
if: inputs.push
continue-on-error: false
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: ${{ env.CACHE_PATH }}
key: ${{ runner.os }}-kfp-docker-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-docker-buildx-
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ${{ inputs.image_context }}
file: ${{ inputs.docker_file }}
push: false
tags: ${{ inputs.app_to_build }}:${{env.TARGET_IMAGE_TAG}}
cache-from: type=local,src=${{ env.CACHE_PATH }}
cache-to: type=local,dest=${{ env.CACHE_PATH }},mode=max