Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: Build Image

on:
workflow_call:
inputs:
registry:
required: true
type: string
description: "Container registry to use"
platform:
required: true
type: string
description: "Platform to build for (e.g. linux/amd64)"
base:
required: false
type: string
description: "Base image to use (e.g. distroless, alpine)"
default: ""
context:
required: true
type: string
dockerfile:
required: true
type: string
build-args:
required: false
type: string
default: ""
image-suffix:
required: true
type: string
digest-prefix:
required: true
type: string
runs-on:
required: false
type: string
default: "ubuntu-latest"
description: "The OS to run the job on. Defaults to ubuntu-latest."
use-qemu:
required: false
type: boolean
default: false
description: "Whether to use QEMU for cross-platform builds. Defaults to false."

jobs:
build:
runs-on: ${{ inputs.runs-on }}
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
if: ${{ inputs.use-qemu }}
- id: lower-repo
run: |
echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}${{ inputs.image-suffix }}" >> $GITHUB_OUTPUT
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.registry }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registry }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build
if: github.event_name == 'pull_request'
id: build
uses: docker/build-push-action@v5
with:
context: ${{ inputs.context }}
platforms: ${{ inputs.platform }}
file: ${{ inputs.dockerfile }}
push: false
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ inputs.registry }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}
build-args: |
${{ inputs.build-args }}
BASE=${{ inputs.base }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push by digest
if: github.event_name != 'pull_request'
id: build-and-push
uses: docker/build-push-action@v5
with:
context: ${{ inputs.context }}
platforms: ${{ inputs.platform }}
file: ${{ inputs.dockerfile }}
push: true
outputs: type=image,name=${{ inputs.registry }}/${{ steps.lower-repo.outputs.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
labels: ${{ steps.meta.outputs.labels }}
build-args: |
${{ inputs.build-args }}
BASE=${{ inputs.base }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build-and-push.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Set platform name
id: platform
run: |
SAFE_PLATFORM=$(echo "${{ inputs.platform }}" | sed 's|/|-|g')
echo "name=$SAFE_PLATFORM" >> $GITHUB_OUTPUT
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.digest-prefix }}${{ steps.platform.outputs.name }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
129 changes: 29 additions & 100 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: ci
name: CI Pipeline

on:
push:
Expand All @@ -13,124 +13,53 @@ on:
- "main"
- "dev"

env:
REGISTRY: ghcr.io
permissions:
contents: read
packages: write

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
config:
- platform: linux/amd64
base: distroless
runs-on: ubuntu-24.04
use-qemu: false
- platform: linux/arm/v6
base: alpine
runs-on: ubuntu-22.04-arm
use-qemu: true
- platform: linux/arm/v7
base: alpine
runs-on: ubuntu-22.04-arm
use-qemu: true
- platform: linux/arm64
base: distroless
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- id: lower-repo
run: |
echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}" >> $GITHUB_OUTPUT
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build
if: github.event_name == 'pull_request'
id: build
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ matrix.platform }}
file: ./Dockerfile
labels: ${{ steps.meta.outputs.labels }}
outputs: type=docker,name=${{ env.REGISTRY }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}
build-args: BASE=${{ matrix.base }}
- name: Build and push
if: github.event_name != 'pull_request'
id: build_push
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ matrix.platform }}
file: ./Dockerfile
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY }}/${{ steps.lower-repo.outputs.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
build-args: BASE=${{ matrix.base }}
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build_push.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: digests
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
overwrite: true
runs-on: ubuntu-24.04-arm
use-qemu: false
uses: ./.github/workflows/build-image.yml
with:
registry: ghcr.io
platform: ${{ matrix.config.platform }}
base: ${{ matrix.config.base }}
runs-on: ${{ matrix.config.runs-on }}
use-qemu: ${{ matrix.config.use-qemu }}
context: .
dockerfile: ./Dockerfile
image-suffix: ""
digest-prefix: "digests-base-"

merge:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
permissions:
contents: read
packages: write
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
name: digests
path: /tmp/digests
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- id: lower-repo
run: |
echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}" >> $GITHUB_OUTPUT
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
uses: ./.github/workflows/merge-manifests.yml
with:
registry: ghcr.io
image-suffix: ""
digest-prefix: "digests-base-"

lint:
runs-on: ubuntu-latest
Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/merge-manifests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Merge Manifests

on:
workflow_call:
inputs:
registry:
required: true
type: string
description: "Container registry to use"
image-suffix:
required: true
type: string
digest-prefix:
required: true
type: string

jobs:
merge:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
pattern: ${{ inputs.digest-prefix }}*
path: /tmp/digests
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- id: lower-repo
run: |
echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}${{ inputs.image-suffix }}" >> $GITHUB_OUTPUT
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.registry }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}
- name: Log in to Container registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registry }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ inputs.registry }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ inputs.registry }}/${{ steps.lower-repo.outputs.IMAGE_NAME }}:${{ steps.meta.outputs.version }}