From 99f2c746efb016a74d71e491a44187231a6b4352 Mon Sep 17 00:00:00 2001 From: You-Sheng Yang Date: Tue, 9 Apr 2024 22:08:19 +0800 Subject: [PATCH] ci: build multiarched docker images Signed-off-by: You-Sheng Yang --- .github/workflows/ci.yml | 68 +++++++++++++++++++ .github/workflows/per-suite.yml | 112 ++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/per-suite.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..0b1bac0f1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +name: Container Images + +on: + pull_request: + branches: + - main + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + matrix: + name: Build Matrix + runs-on: ubuntu-latest + outputs: + full_json: ${{ steps.releases.outputs.json }} + codenames: ${{ steps.pp.outputs.codenames }} + codename_arch: ${{ steps.pp.outputs.codename_arch }} + steps: + - name: Releases Info + id: releases + uses: vicamo/actions-library/debian-releases@v1 + + - name: Post Processing + id: pp + env: + FULL_JSON: ${{ steps.releases.outputs.json }} + run: | + disabled='["hurd-amd64", "hurd-i386", "ia64", "kfreebsd-amd64", "kfreebsd-i386"]' + + codenames="$(echo "${FULL_JSON}" | \ + jq -c -M '[ .[] | {"distribution":.distribution,"codename":.codename,"suite":.suite,"architectures":(.architectures - '"${disabled}"' | tostring)} ]')" + echo "::group::Built JSON(codenames)" + echo "${codenames}" | jq + echo "::endgroup::" + + codename_arch="$(echo "${FULL_JSON}" | \ + jq -c -M '[ .[] as $s | ($s.architectures - '"${disabled}"') | {"distribution":$s.distribution,"codename":$s.codename,"suite":$s.suite,"architectures":.} ]')" + echo "::group::Built JSON(codename and architectures)" + echo "${codename_arch}" | jq + echo "::endgroup::" + + { \ + echo "codenames=${codenames}"; \ + echo "codename_arch=${codename_arch}"; \ + } | tee -a "${GITHUB_OUTPUT}" + + per-suite: + name: Per Suite + needs: + - matrix + strategy: + fail-fast: false + matrix: + include: ${{ fromJSON(needs.matrix.outputs.codenames) }} + uses: ./.github/workflows/per-suite.yml + with: + distribution: ${{ matrix.distribution }} + codename: ${{ matrix.codename }} + suite: ${{ matrix.suite }} + architectures: ${{ matrix.architectures }} diff --git a/.github/workflows/per-suite.yml b/.github/workflows/per-suite.yml new file mode 100644 index 000000000..598443060 --- /dev/null +++ b/.github/workflows/per-suite.yml @@ -0,0 +1,112 @@ +--- +name: Build Suite +on: + workflow_call: + inputs: + distribution: + description: 'Distribution name, e.g. debian.' + type: string + required: true + codename: + description: 'Debian codename.' + type: string + required: true + suite: + description: 'Debian suite.' + type: string + required: true + architectures: + description: 'Architectures in JSON array' + type: string + required: true + +permissions: + contents: read + +jobs: + per-arch: + runs-on: ubuntu-latest + strategy: + matrix: + arch: ${{ fromJSON(inputs.architectures) }} + env: + DISTRO: ${{ inputs.distribution }} + CODENAME: ${{ inputs.codename }} + ARCH: ${{ matrix.arch }} + steps: + - name: Translate docker platform + id: translate + run: | + platform= + case "${ARCH}" in + amd64) platform=linux/amd64;; + arm) platform=linux/arm;; + arm64) platform=linux/arm64/v8;; + armel) platform=linux/arm/v5;; + armhf) platform=linux/arm/v7;; + i386) platform=linux/386;; + loong64) platform=linux/loong64;; + mips64el) platform=linux/mips64le;; + ppc64el) platform=linux/ppc64le;; + riscv64) platform=linux/riscv64;; + s390x) platform=linux/s390x;; + + # Also in github.com/containerd/containerd/platforms/database + mips) platform=linux/mips;; + mipsel) platform=linux/mipsle;; + powerpc) platform=linux/ppc;; + ppc64) platform=linux/ppc64;; + s390) platform=linux/s390;; + sparc) platform=linux/sparc;; + sparc64) platform=linux/sparc64;; + x32) platform=linux/amd64p32;; + + # Other architectures supported by QEMU + alpha) platform=linux/alpha;; + hppa) platform=linux/hppa;; + m68k) platform=linux/m68k;; + sh4) platform=linux/sh4;; + + *) + echo "Unsupported arch '${ARCH}'" >&2 + exit 1 + ;; + esac + + echo "platform=${platform}" | tee -a "${GITHUB_OUTPUT}" + + - # Add support for more platforms with QEMU (optional) + # https://github.com/docker/setup-qemu-action + name: Set up QEMU + if: matrix.arch != 'amd64' && matrix.arch != 'i386' + uses: docker/setup-qemu-action@v3 + with: + image: vicamo/binfmt + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: v0.12.0 + + - name: Check Availability + id: avail + env: + PLATFORM: ${{ steps.translate.outputs.platform }} + run: | + image="${DISTRO}:${CODENAME}" + + # generate: linux/amd64:docker.io/library/ubuntu:noble@sha256:69ce9399... + manifest="$(docker buildx imagetools inspect "${image}" | \ + awk '/Name: +\S+@sha256:/ { digest=$2; getline; getline; platform=$2; print platform ":" digest}' | \ + grep '^${PLATFORM}:' || true)" + if [ -z "manifest" ]; then + manifest="$(docker buildx imagetools inspect "vicamo/${image}" | \ + awk '/Name: +\S+@sha256:/ { digest=$2; getline; getline; platform=$2; print platform ":" digest}' | \ + grep '^${PLATFORM}:' || true)" + if [ -z "manifest" ]; then + digest="$(docker buildx imagetools inspect "vicamo/${image}-${ARCH}" | \ + awk '/Name: +\S+/ { image=$2; getline; getline; digest=$2; print image "@" digest}')" + manifest="${PLATFORM}:${digest}" + fi + fi + + echo "digest=${manifest#*:}" | tee -a "${GITHUB_OUTPUT}"