docker / build-push-action

GitHub Action to build and push Docker images with Buildx
https://github.com/marketplace/actions/build-and-push-docker-images
Apache License 2.0
4.24k stars 541 forks source link

buildx failing to solve: no match for platform in manifest #913

Closed xthursdayx closed 1 year ago

xthursdayx commented 1 year ago

Behaviour

I use a GitHub workflow with build-push-action to build and push my multi-arch docker image. This has always worked in the past, however starting yesterday the job which builds the arm32v7 version of my image no longer is able to match the correct platform in the Dockerfile baseimage - even though it exists and is the correct platform.

Steps to reproduce this issue

  1. Run workflow to build docker image.

Expected behaviour

In the past this workflow has always correctly pulled the right base image for the platform specified in my Dockerfile and then built the image and pushed it to Docker Hub.

Actual behaviour

As above, the build and push action seems to not be able to recognize that my Dockerfile base image is the correct platform for the Docker image version it is supposed to build.

Configuration

---
# Builds our multi-arch Docker images for p7zip and unarr versions of YACReaderLibraryServer
name: Build and push images
on:
  release:
    types: [published]  
  workflow_dispatch:

env:
  DOCKERHUB_SLUG: xthursdayx/yacreaderlibrary-server-docker
  GHCR_SLUG: ghcr.io/xthursdayx/yacreaderlibrary-server-docker

jobs:
  build-unarr-amd64:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout repo
        uses: actions/checkout@v3

      - name: Docker meta
        id: dh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Docker meta
        id: gh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.GHCR_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v4
        with:
          context: unarr
          file: unarr/Dockerfile
          platforms: linux/amd64
          push: true
          provenance: false
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:unarr-amd64
            ${{ env.DOCKERHUB_SLUG }}:latest-amd64
            ${{ env.GHCR_SLUG }}:unarr-amd64
            ${{ env.GHCR_SLUG }}:latest-amd64
            ${{ steps.dh-meta.outputs.tags }}-amd64
            ${{ steps.gh-meta.outputs.tags }}-amd64
          labels: ${{ steps.dh-meta.outputs.labels }}

  build-unarr-arm64v8:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Docker meta
        id: dh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Docker meta
        id: gh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.GHCR_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v4
        with:
          push: true
          provenance: false
          context: unarr
          file: unarr/Dockerfile.aarch64
          platforms: linux/arm64/v8
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:unarr-arm64v8
            ${{ env.DOCKERHUB_SLUG }}:latest-arm64v8
            ${{ env.GHCR_SLUG }}:unarr-arm64v8
            ${{ env.GHCR_SLUG }}:latest-arm64v8
            ${{ steps.dh-meta.outputs.tags }}-arm64v8
            ${{ steps.gh-meta.outputs.tags }}-arm64v8
          labels: ${{ steps.dh-meta.outputs.labels }}

  build-unarr-arm32v7:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Docker meta
        id: dh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Docker meta
        id: gh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.GHCR_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v4
        with:
          push: true
          provenance: false
          context: unarr
          file: unarr/Dockerfile.armhf
          platforms: linux/arm/v7
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:unarr-arm32v7
            ${{ env.DOCKERHUB_SLUG }}:latest-arm32v7
            ${{ env.GHCR_SLUG }}:unarr-arm32v7
            ${{ env.GHCR_SLUG }}:latest-arm32v7
            ${{ steps.dh-meta.outputs.tags }}-arm32v7
            ${{ steps.gh-meta.outputs.tags }}-arm32v7
          labels: ${{ steps.dh-meta.outputs.labels }}

  build-p7zip-amd64:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout repo
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v4
        with:
          push: true
          provenance: false
          context: p7zip
          file: p7zip/Dockerfile
          platforms: linux/amd64
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:p7zip-amd64
            ${{ env.GHCR_SLUG }}:p7zip-amd64

  build-p7zip-arm64v8:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v4
        with:
          push: true
          provenance: false
          context: p7zip
          file: p7zip/Dockerfile.aarch64
          platforms: linux/arm64/v8
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:p7zip-arm64v8
            ${{ env.GHCR_SLUG }}:p7zip-arm64v8

  build-p7zip-arm32v7:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v4
        with:
          push: true
          provenance: false
          context: p7zip
          file: p7zip/Dockerfile.armhf
          platforms: linux/arm/v7
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:p7zip-arm32v7
            ${{ env.GHCR_SLUG }}:p7zip-arm32v7

  push-manifest:
    needs: [build-unarr-amd64, build-unarr-arm64v8, build-unarr-arm32v7, build-p7zip-amd64, build-p7zip-arm64v8, build-p7zip-arm32v7]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Docker meta
        id: dh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Docker meta
        id: gh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.GHCR_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Create manifest for multi-arch images @ Docker Hub
        run: |
          # get artifacts from previous steps and integrate into one multi-arch manifest
          docker pull --platform=linux/amd64 ${{ env.DOCKERHUB_SLUG }}:unarr-amd64
          docker pull --platform=linux/arm64 ${{ env.DOCKERHUB_SLUG }}:unarr-arm64v8
          docker pull --platform=linux/arm/v7 ${{ env.DOCKERHUB_SLUG }}:unarr-arm32v7
          docker pull --platform=linux/amd64 ${{ env.DOCKERHUB_SLUG }}:latest-amd64
          docker pull --platform=linux/arm64 ${{ env.DOCKERHUB_SLUG }}:latest-arm64v8
          docker pull --platform=linux/arm/v7 ${{ env.DOCKERHUB_SLUG }}:latest-arm32v7
          docker pull --platform=linux/amd64 ${{ env.DOCKERHUB_SLUG }}:p7zip-amd64
          docker pull --platform=linux/arm64 ${{ env.DOCKERHUB_SLUG }}:p7zip-arm64v8
          docker pull --platform=linux/arm/v7 ${{ env.DOCKERHUB_SLUG }}:p7zip-arm32v7
          docker pull --platform=linux/amd64 ${{ steps.dh-meta.outputs.tags }}-amd64
          docker pull --platform=linux/arm64 ${{ steps.dh-meta.outputs.tags }}-arm64v8
          docker pull --platform=linux/arm/v7 ${{ steps.dh-meta.outputs.tags }}-arm32v7
          docker manifest create ${{ env.DOCKERHUB_SLUG }}:latest ${{ env.DOCKERHUB_SLUG }}:latest-amd64 ${{ env.DOCKERHUB_SLUG }}:latest-arm64v8 ${{ env.DOCKERHUB_SLUG }}:latest-arm32v7
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:latest --os linux --arch amd64 ${{ env.DOCKERHUB_SLUG }}:latest-amd64
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:latest --os linux --arch arm64 --variant v8 ${{ env.DOCKERHUB_SLUG }}:latest-arm64v8
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:latest --os linux --arch arm --variant v7 ${{ env.DOCKERHUB_SLUG }}:latest-arm32v7 
          docker manifest push ${{ env.DOCKERHUB_SLUG }}:latest        
          docker manifest create ${{ env.DOCKERHUB_SLUG }}:unarr ${{ env.DOCKERHUB_SLUG }}:unarr-amd64 --amend ${{ env.DOCKERHUB_SLUG }}:unarr-arm64v8 --amend ${{ env.DOCKERHUB_SLUG }}:unarr-arm32v7
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:unarr --os linux --arch amd64 ${{ env.DOCKERHUB_SLUG }}:unarr-amd64
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:unarr --os linux --arch arm64 --variant v8 ${{ env.DOCKERHUB_SLUG }}:unarr-arm64v8
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:unarr --os linux --arch arm --variant v7 ${{ env.DOCKERHUB_SLUG }}:unarr-arm32v7
          docker manifest push ${{ env.DOCKERHUB_SLUG }}:unarr
          docker manifest create ${{ env.DOCKERHUB_SLUG }}:p7zip ${{ env.DOCKERHUB_SLUG }}:p7zip-amd64 ${{ env.DOCKERHUB_SLUG }}:p7zip-arm64v8 ${{ env.DOCKERHUB_SLUG }}:p7zip-arm32v7
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:p7zip --os linux --arch amd64 ${{ env.DOCKERHUB_SLUG }}:p7zip-amd64
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:p7zip --os linux --arch arm64 --variant v8 ${{ env.DOCKERHUB_SLUG }}:p7zip-arm64v8
          docker manifest annotate ${{ env.DOCKERHUB_SLUG }}:p7zip --os linux --arch arm --variant v7 ${{ env.DOCKERHUB_SLUG }}:p7zip-arm32v7
          docker manifest push ${{ env.DOCKERHUB_SLUG }}:p7zip
          docker manifest create ${{ steps.dh-meta.outputs.tags }} ${{ steps.dh-meta.outputs.tags }}-amd64 ${{ steps.dh-meta.outputs.tags }}-arm64v8 ${{ steps.dh-meta.outputs.tags }}-arm32v7
          docker manifest annotate ${{ steps.dh-meta.outputs.tags }} --os linux --arch amd64 ${{ steps.dh-meta.outputs.tags }}-amd64
          docker manifest annotate ${{ steps.dh-meta.outputs.tags }} --os linux --arch arm64 --variant v8 ${{ steps.dh-meta.outputs.tags }}-arm64v8
          docker manifest annotate ${{ steps.dh-meta.outputs.tags }} --os linux --arch arm --variant v7 ${{ steps.dh-meta.outputs.tags }}-arm32v7
          docker manifest push ${{ steps.dh-meta.outputs.tags }}

      - name: Create manifest for multi-arch images @ GHCR
        run: |
          docker pull --platform=linux/amd64 ${{ env.GHCR_SLUG }}:unarr-amd64
          docker pull --platform=linux/arm64 ${{ env.GHCR_SLUG }}:unarr-arm64v8
          docker pull --platform=linux/arm/v7 ${{ env.GHCR_SLUG }}:unarr-arm32v7
          docker pull --platform=linux/amd64 ${{ env.GHCR_SLUG }}:latest-amd64
          docker pull --platform=linux/arm64 ${{ env.GHCR_SLUG }}:latest-arm64v8
          docker pull --platform=linux/arm/v7 ${{ env.GHCR_SLUG }}:latest-arm32v7
          docker pull --platform=linux/amd64 ${{ env.GHCR_SLUG }}:p7zip-amd64
          docker pull --platform=linux/arm64 ${{ env.GHCR_SLUG }}:p7zip-arm64v8
          docker pull --platform=linux/arm/v7 ${{ env.GHCR_SLUG }}:p7zip-arm32v7
          docker pull --platform=linux/amd64 ${{ steps.gh-meta.outputs.tags }}-amd64
          docker pull --platform=linux/arm64 ${{ steps.gh-meta.outputs.tags }}-arm64v8
          docker pull --platform=linux/arm/v7 ${{ steps.gh-meta.outputs.tags }}-arm32v7
          docker manifest create -a ${{ env.GHCR_SLUG }}:unarr ${{ env.GHCR_SLUG }}:unarr-amd64 ${{ env.GHCR_SLUG }}:unarr-arm64v8 ${{ env.GHCR_SLUG }}:unarr-arm32v7
          docker manifest annotate ${{ env.GHCR_SLUG }}:unarr --os linux --arch amd64 ${{ env.GHCR_SLUG }}:unarr-amd64
          docker manifest annotate ${{ env.GHCR_SLUG }}:unarr --os linux --arch arm64 --variant v8 ${{ env.GHCR_SLUG }}:unarr-arm64v8
          docker manifest annotate ${{ env.GHCR_SLUG }}:unarr --os linux --arch arm --variant v7 ${{ env.GHCR_SLUG }}:unarr-arm32v7
          docker manifest push ${{ env.GHCR_SLUG }}:unarr
          docker manifest create ${{ env.GHCR_SLUG }}:p7zip ${{ env.GHCR_SLUG }}:p7zip-amd64 ${{ env.GHCR_SLUG }}:p7zip-arm64v8 ${{ env.GHCR_SLUG }}:p7zip-arm32v7
          docker manifest annotate ${{ env.GHCR_SLUG }}:p7zip --os linux --arch amd64 ${{ env.GHCR_SLUG }}:p7zip-amd64
          docker manifest annotate ${{ env.GHCR_SLUG }}:p7zip --os linux --arch arm64 --variant v8 ${{ env.GHCR_SLUG }}:p7zip-arm64v8
          docker manifest annotate ${{ env.GHCR_SLUG }}:p7zip --os linux --arch arm --variant v7 ${{ env.GHCR_SLUG }}:p7zip-arm32v7
          docker manifest push ${{ env.GHCR_SLUG }}:p7zip
          docker manifest create ${{ env.GHCR_SLUG }}:latest ${{ env.GHCR_SLUG }}:latest-amd64 ${{ env.GHCR_SLUG }}:latest-arm64v8 ${{ env.GHCR_SLUG }}:latest-arm32v7
          docker manifest annotate ${{ env.GHCR_SLUG }}:latest --os linux --arch amd64 ${{ env.GHCR_SLUG }}:latest-amd64
          docker manifest annotate ${{ env.GHCR_SLUG }}:latest --os linux --arch arm64 --variant v8 ${{ env.GHCR_SLUG }}:latest-arm64v8
          docker manifest annotate ${{ env.GHCR_SLUG }}:latest --os linux --arch arm --variant v7 ${{ env.GHCR_SLUG }}:latest-arm32v7
          docker manifest push ${{ env.GHCR_SLUG }}:latest
          docker manifest create ${{ steps.gh-meta.outputs.tags }} ${{ steps.gh-meta.outputs.tags }}-amd64 ${{ steps.gh-meta.outputs.tags }}-arm64v8 ${{ steps.gh-meta.outputs.tags }}-arm32v7
          docker manifest annotate ${{ steps.gh-meta.outputs.tags }} --os linux --arch amd64 ${{ steps.gh-meta.outputs.tags }}-amd64
          docker manifest annotate ${{ steps.gh-meta.outputs.tags }} --os linux --arch arm64 --variant v8 ${{ steps.gh-meta.outputs.tags }}-arm64v8
          docker manifest annotate ${{ steps.gh-meta.outputs.tags }} --os linux --arch arm --variant v7 ${{ steps.gh-meta.outputs.tags }}-arm32v7
          docker manifest push ${{ steps.gh-meta.outputs.tags }} 

Logs

logs_1469.zip

crazy-max commented 1 year ago

Looking at https://github.com/xthursdayx/yacreaderlibrary-server-docker/blob/df45f059eaf714b0ddc52d49d07807e82ef74731/p7zip/Dockerfile#L1C1-L1C48

The ghcr.io/linuxserver/baseimage-ubuntu:jammy image doesn't support linux/arm/v7:

docker buildx imagetools inspect ghcr.io/linuxserver/baseimage-ubuntu:jammy
Name:      ghcr.io/linuxserver/baseimage-ubuntu:jammy
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:5ff7c87f9dfa5e2dca10656c96dd24dcd1586a59ed474283568006aa9bb4e446

Manifests:
  Name:      ghcr.io/linuxserver/baseimage-ubuntu:jammy@sha256:193695d5050e983344bacf67f26f74ecd103ee304707e379dadafbadc59166e7
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

  Name:      ghcr.io/linuxserver/baseimage-ubuntu:jammy@sha256:9555f33d2ef00be17f24fa628ba9502fe47647202e3cce5f7d3cbf3c1aa4c392
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64/v8

Looks like linuxserver.io has dropped support for armhf: https://www.linuxserver.io/blog/a-farewell-to-arm-hf. This might be linked, suggest to contact them.

Also your workflow could be way more simple if you want to distribute multi-platform build across runners. See https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners

xthursdayx commented 1 year ago

Thanks for that @crazy-max - I hadn't seen that linuxserver dropped armhf support. Cheers.

xthursdayx commented 1 year ago

This might be going off topic, but in terms of running the build and push process across runners, I'm having a little trouble figuring out how to do that for this my image, which I release with two different backend compression versions (unarr and p7zip) and multiple tags per version (e.g. latest, unarr, v1.6.1, unarr-latest, v1.6.1-amd64, unarr-amd64, unarr-arm64v8, etc)...I also think I'd need to separate out DockerHub and GHCR into two separate jobs. The example in doc you linked shows the build-push-action step using outputs while my original workflow uses tags to specify the unique tags for each platform and backend compression version. I've tried to create a new workflow utilizing matrix and the buildx imagetools manifest creation, push and merge steps from the docs. Does this (partial) workflow look like it will work correctly?

# Builds our multi-arch Docker images for p7zip and unarr versions of YACReaderLibraryServer
name: Build and push images
on:
  release:
    types: [published]  
  workflow_dispatch:

env:
  DOCKERHUB_SLUG: xthursdayx/yacreaderlibrary-server-docker
  GHCR_SLUG: ghcr.io/xthursdayx/yacreaderlibrary-server-docker

jobs:
  build-and-push-unarr-image-DH:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    strategy:
      fail-fast: false
      matrix:
        platform: [linux/amd64, linux/arm64]
        file: [unarr/Dockerfile, unarr/Dockerfile.aarch64]
        tag: [amd64, arm64v8]
        exclude:
          - platform: linux/amd64
            file: unarr/Dockerfile.aarch64
            tag: arm64v8
          - platform: linux/arm64
            file: unarr/Dockerfile
            tag: amd64
    steps:
      - name: Checkout repo
        uses: actions/checkout@v3

      - name: Docker meta
        id: dh-meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
          flavor: latest=false
          tags: |
            type=ref,event=tag

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Dockerhub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push by digest
        uses: docker/build-push-action@v4
        with:
          context: unarr
          file: ${{matrix.file}}
          platforms: ${{matrix.platform}}
          labels: ${{ steps.dh-meta.outputs.labels }}
          outputs: type=image,name=${{ env.DOCKERHUB_SLUG }},push-by-digest=true,name-canonical=true,push=true,provenance=false
          tags: |
            ${{ env.DOCKERHUB_SLUG }}:unarr-${{matrix.tag}}
            ${{ env.DOCKERHUB_SLUG }}:latest-${{matrix.tag}}
            ${{ steps.dh-meta.outputs.tags }}-${{matrix.tag}}

      - name: Upload digest
        uses: actions/upload-artifact@v3
        with:
          name: digests
          path: /tmp/digests/*
          if-no-files-found: error
          retention-days: 1

  merge-unarr-DH:
    runs-on: ubuntu-latest
    needs:
      - build
    steps:
      -
        name: Download digests
        uses: actions/download-artifact@v3
        with:
          name: digests
          path: /tmp/digests
      -
        name: Set up Docker Buildxdocker 
        uses: docker/setup-buildx-action@v2
      -
        name: Docker meta
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: ${{ env.REGISTRY_IMAGE }}
      -
        name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_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.DOCKERHUB_SLUG }}@sha256:%s ' *)
      -
        name: Inspect image
        run: |
          docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.tags }}