ci: merge images

This commit is contained in:
Emrik Östling
2025-05-23 12:24:47 +02:00
committed by C4illin
parent 2c87a6c8c2
commit 00f95b6daa

View File

@@ -1,88 +1,164 @@
name: Docker name: Docker
# This workflow uses actions that are not certified by GitHub. # thanks to https://github.com/sredevopsorg/multi-arch-docker-github-workflow
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on: on:
push: push:
branches: [ "main" ] branches: ["main"]
# Publish semver tags as releases. tags: ["v*.*.*"]
tags: [ 'v*.*.*' ]
pull_request: pull_request:
branches: [ "main" ] branches: ["main"]
workflow_dispatch: workflow_dispatch:
env: env:
# Use docker.io for Docker Hub if empty GHCR_IMAGE: ghcr.io/c4illin/convertx
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }} IMAGE_NAME: ${{ github.repository }}
DOCKERHUB_USERNAME: c4illin DOCKERHUB_USERNAME: c4illin
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
build: # The build job builds the Docker image for each platform specified in the matrix.
runs-on: ${{ matrix.runner }} build:
strategy: strategy:
fail-fast: false
matrix: matrix:
platform: [amd64, arm64] platform:
include: - linux/amd64
- platform: amd64 - linux/arm64
runner: ubuntu-24.04
- platform: arm64
runner: ubuntu-24.04-arm
permissions: permissions:
contents: read contents: write
packages: write packages: write
attestations: write
checks: write
actions: read
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-24.04' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }}
name: Build Docker image for ${{ matrix.platform }}
steps: steps:
- name: Prepare environment for current platform
# This step sets up the environment for the current platform being built.
# It replaces the '/' character in the platform name with '-' and sets it as an environment variable.
# This is useful for naming artifacts and other resources that cannot contain '/'.
# The environment variable PLATFORMS_PAIR will be used later in the workflow.
id: prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
# Workaround: https://github.com/docker/build-push-action/issues/461 - name: Docker meta default
- name: Setup Docker buildx id: meta
uses: docker/setup-buildx-action@v3 uses: docker/metadata-action@v5
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} images: ${{ env.GHCR_IMAGE }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.10.0
with:
platforms: ${{ matrix.platform }}
- name: Login to GitHub Container Registry
# here we only login to ghcr.io since the this only pushes internal images
uses: docker/login-action@v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker - name: Build and push by digest
# https://github.com/docker/metadata-action id: build
uses: docker/build-push-action@v6.16.0
env:
DOCKER_BUILDKIT: 1
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true,oci-mediatypes=true
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
name: Merge Docker manifests
runs-on: ubuntu-latest
permissions:
attestations: write
contents: read
packages: write
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Extract Docker metadata - name: Extract Docker metadata
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: | images: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} ${{ env.GHCR_IMAGE }}
${{ env.IMAGE_NAME }} ${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR) - name: Set up Docker Buildx
# https://github.com/docker/build-push-action uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
id: build-and-push - name: Login to GitHub Container Registry
uses: docker/build-push-action@v6 uses: docker/login-action@v3
with: with:
context: . registry: ghcr.io
platforms: linux/${{ matrix.platform }} username: ${{ github.actor }}
push: ${{ github.event_name != 'pull_request' }} password: ${{ secrets.GITHUB_TOKEN }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} - name: Login to Docker Hub
cache-from: type=gha uses: docker/login-action@v3
cache-to: type=gha,mode=max with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Get execution timestamp with RFC3339 format
id: timestamp
run: |
echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
- 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") \
--annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \
--annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \
--annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \
--annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect '${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}'