From 419bdd0c830a0f8f504f323c4dfa3e1bc05f231b Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sun, 31 May 2026 13:57:58 +0200 Subject: [PATCH 1/2] ci: parallelise container builds using matrix and manifest merge --- .github/workflows/ci.yml | 89 ++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ad2505..1f408aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,14 +45,26 @@ jobs: - 'Containerfile' - '.github/workflows/ci.yml' - publish: - name: Build & Publish Containers + build-arch: + name: Build & Publish (${{ matrix.platform }}) needs: [lint, detect-changes] if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') || needs.detect-changes.outputs.container == 'true' - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + suffix: amd64 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + suffix: arm64 + runs-on: ${{ matrix.runner }} permissions: contents: read packages: write + outputs: + push: ${{ steps.resolve.outputs.push }} steps: - name: Checkout Code uses: actions/checkout@v6 @@ -89,18 +101,17 @@ jobs: echo "sha-tag=sha-$SHORT_SHA" >> "$GITHUB_OUTPUT" - - name: Build Flatpak Base Image id: build-flatpak uses: redhat-actions/buildah-build@v2 with: context: . containerfiles: ./Containerfile - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} image: ghcr.io/aetherpak/flatpak tags: | - ${{ steps.resolve.outputs.tags }} - ${{ steps.resolve.outputs.sha-tag }} + ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} + ${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} extra-args: --target flatpak oci: true @@ -109,24 +120,25 @@ jobs: uses: redhat-actions/push-to-registry@v2 with: image: ${{ steps.build-flatpak.outputs.image }} - tags: ${{ steps.resolve.outputs.tags }} + tags: | + ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} + ${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} registry: ghcr.io extra-args: | --tls-verify=true - - name: Build Flatpak Builder Image id: build-builder uses: redhat-actions/buildah-build@v2 with: context: . containerfiles: ./Containerfile - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} image: ghcr.io/aetherpak/flatpak-builder - tags: ${{ steps.resolve.outputs.tags }} + tags: ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} extra-args: | --target flatpak-builder - --build-arg BASE_IMAGE=ghcr.io/aetherpak/flatpak:${{ steps.resolve.outputs.sha-tag }} + --build-arg BASE_IMAGE=ghcr.io/aetherpak/flatpak:${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} oci: true - name: Push Flatpak Builder Image @@ -134,7 +146,58 @@ jobs: uses: redhat-actions/push-to-registry@v2 with: image: ${{ steps.build-builder.outputs.image }} - tags: ${{ steps.resolve.outputs.tags }} + tags: ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} registry: ghcr.io extra-args: | --tls-verify=true + + merge-manifests: + name: Merge Multi-Arch Manifests + needs: build-arch + if: ${{ needs.build-arch.result == 'success' && needs.build-arch.outputs.push == 'true' }} + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Log in to the Container registry + uses: redhat-actions/podman-login@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Create and Push Manifest Lists + shell: bash + run: | + set -euo pipefail + REF_NAME="${{ github.ref_name }}" + SHA="${{ github.sha }}" + SHORT_SHA="${SHA:0:7}" + SHA_TAG="sha-${SHORT_SHA}" + + if [ "$REF_NAME" = "main" ]; then + TAGS="latest" + elif [[ "$REF_NAME" =~ ^v[0-9] ]]; then + TAGS="$REF_NAME" + else + TAGS="sha-${SHORT_SHA}" + fi + + # Merge flatpak base image (both main tag and sha-tag) + for tag in $TAGS $SHA_TAG; do + echo "=== Merging Flatpak Base Image tag: ${tag} ===" + podman manifest create "ghcr.io/aetherpak/flatpak:${tag}" + podman manifest add "ghcr.io/aetherpak/flatpak:${tag}" "docker://ghcr.io/aetherpak/flatpak:${tag}-amd64" + podman manifest add "ghcr.io/aetherpak/flatpak:${tag}" "docker://ghcr.io/aetherpak/flatpak:${tag}-arm64" + podman manifest push --tls-verify=true "ghcr.io/aetherpak/flatpak:${tag}" + done + + # Merge flatpak-builder image + for tag in $TAGS; do + echo "=== Merging Flatpak Builder Image tag: ${tag} ===" + podman manifest create "ghcr.io/aetherpak/flatpak-builder:${tag}" + podman manifest add "ghcr.io/aetherpak/flatpak-builder:${tag}" "docker://ghcr.io/aetherpak/flatpak-builder:${tag}-amd64" + podman manifest add "ghcr.io/aetherpak/flatpak-builder:${tag}" "docker://ghcr.io/aetherpak/flatpak-builder:${tag}-arm64" + podman manifest push --tls-verify=true "ghcr.io/aetherpak/flatpak-builder:${tag}" + done From 9ba76ac1cd078128cac97e191d0fab25abd6b7c8 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sun, 31 May 2026 14:02:45 +0200 Subject: [PATCH 2/2] ci: implement atomic tag promotion for container builds --- .github/workflows/ci.yml | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f408aa..e182eff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,7 +110,6 @@ jobs: platforms: ${{ matrix.platform }} image: ghcr.io/aetherpak/flatpak tags: | - ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} ${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} extra-args: --target flatpak oci: true @@ -121,7 +120,6 @@ jobs: with: image: ${{ steps.build-flatpak.outputs.image }} tags: | - ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} ${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} registry: ghcr.io extra-args: | @@ -135,7 +133,7 @@ jobs: containerfiles: ./Containerfile platforms: ${{ matrix.platform }} image: ghcr.io/aetherpak/flatpak-builder - tags: ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} + tags: ${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} extra-args: | --target flatpak-builder --build-arg BASE_IMAGE=ghcr.io/aetherpak/flatpak:${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} @@ -146,7 +144,7 @@ jobs: uses: redhat-actions/push-to-registry@v2 with: image: ${{ steps.build-builder.outputs.image }} - tags: ${{ steps.resolve.outputs.tags }}-${{ matrix.suffix }} + tags: ${{ steps.resolve.outputs.sha-tag }}-${{ matrix.suffix }} registry: ghcr.io extra-args: | --tls-verify=true @@ -188,8 +186,8 @@ jobs: for tag in $TAGS $SHA_TAG; do echo "=== Merging Flatpak Base Image tag: ${tag} ===" podman manifest create "ghcr.io/aetherpak/flatpak:${tag}" - podman manifest add "ghcr.io/aetherpak/flatpak:${tag}" "docker://ghcr.io/aetherpak/flatpak:${tag}-amd64" - podman manifest add "ghcr.io/aetherpak/flatpak:${tag}" "docker://ghcr.io/aetherpak/flatpak:${tag}-arm64" + podman manifest add "ghcr.io/aetherpak/flatpak:${tag}" "docker://ghcr.io/aetherpak/flatpak:${SHA_TAG}-amd64" + podman manifest add "ghcr.io/aetherpak/flatpak:${tag}" "docker://ghcr.io/aetherpak/flatpak:${SHA_TAG}-arm64" podman manifest push --tls-verify=true "ghcr.io/aetherpak/flatpak:${tag}" done @@ -197,7 +195,16 @@ jobs: for tag in $TAGS; do echo "=== Merging Flatpak Builder Image tag: ${tag} ===" podman manifest create "ghcr.io/aetherpak/flatpak-builder:${tag}" - podman manifest add "ghcr.io/aetherpak/flatpak-builder:${tag}" "docker://ghcr.io/aetherpak/flatpak-builder:${tag}-amd64" - podman manifest add "ghcr.io/aetherpak/flatpak-builder:${tag}" "docker://ghcr.io/aetherpak/flatpak-builder:${tag}-arm64" + podman manifest add "ghcr.io/aetherpak/flatpak-builder:${tag}" "docker://ghcr.io/aetherpak/flatpak-builder:${SHA_TAG}-amd64" + podman manifest add "ghcr.io/aetherpak/flatpak-builder:${tag}" "docker://ghcr.io/aetherpak/flatpak-builder:${SHA_TAG}-arm64" podman manifest push --tls-verify=true "ghcr.io/aetherpak/flatpak-builder:${tag}" done + + # Promote single-arch rolling/release tags in registry + for tag in $TAGS; do + echo "=== Promoting single-arch tags for tag: ${tag} ===" + skopeo copy --all --src-creds "${{ github.actor }}:${{ github.token }}" --dest-creds "${{ github.actor }}:${{ github.token }}" "docker://ghcr.io/aetherpak/flatpak:${SHA_TAG}-amd64" "docker://ghcr.io/aetherpak/flatpak:${tag}-amd64" + skopeo copy --all --src-creds "${{ github.actor }}:${{ github.token }}" --dest-creds "${{ github.actor }}:${{ github.token }}" "docker://ghcr.io/aetherpak/flatpak:${SHA_TAG}-arm64" "docker://ghcr.io/aetherpak/flatpak:${tag}-arm64" + skopeo copy --all --src-creds "${{ github.actor }}:${{ github.token }}" --dest-creds "${{ github.actor }}:${{ github.token }}" "docker://ghcr.io/aetherpak/flatpak-builder:${SHA_TAG}-amd64" "docker://ghcr.io/aetherpak/flatpak-builder:${tag}-amd64" + skopeo copy --all --src-creds "${{ github.actor }}:${{ github.token }}" --dest-creds "${{ github.actor }}:${{ github.token }}" "docker://ghcr.io/aetherpak/flatpak-builder:${SHA_TAG}-arm64" "docker://ghcr.io/aetherpak/flatpak-builder:${tag}-arm64" + done