name: build

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

on:
  workflow_dispatch:
  push:
    branches:
      - 'master'
      - 'v[0-9]*'
    tags:
      - 'v*'
  pull_request:
    paths-ignore:
      - '.github/releases.json'
      - 'README.md'
      - 'docs/**'

env:
  BUILDX_VERSION: "latest"
  BUILDKIT_IMAGE: "moby/buildkit:latest"
  REPO_SLUG: "docker/buildx-bin"
  DESTDIR: "./bin"

jobs:
  test:
    runs-on: ubuntu-22.04
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
        with:
          version: ${{ env.BUILDX_VERSION }}
          driver-opts: image=${{ env.BUILDKIT_IMAGE }}
          buildkitd-flags: --debug
      -
        name: Test
        uses: docker/bake-action@v3
        with:
          targets: test
          set: |
            *.cache-from=type=gha,scope=test
            *.cache-to=type=gha,scope=test
      -
        name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          directory: ${{ env.DESTDIR }}/coverage

  prepare:
    runs-on: ubuntu-22.04
    outputs:
      matrix: ${{ steps.platforms.outputs.matrix }}
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Create matrix
        id: platforms
        run: |
          echo "matrix=$(docker buildx bake binaries-cross --print | jq -cr '.target."binaries-cross".platforms')" >>${GITHUB_OUTPUT}
      -
        name: Show matrix
        run: |
          echo ${{ steps.platforms.outputs.matrix }}

  binaries:
    runs-on: ubuntu-22.04
    needs:
      - prepare
    strategy:
      fail-fast: false
      matrix:
        platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
    steps:
      -
        name: Prepare
        run: |
          platform=${{ matrix.platform }}
          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
      -
        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
        with:
          version: ${{ env.BUILDX_VERSION }}
          driver-opts: image=${{ env.BUILDKIT_IMAGE }}
          buildkitd-flags: --debug
      -
        name: Build
        run: |
          make release
        env:
          PLATFORMS: ${{ matrix.platform }}
          CACHE_FROM: type=gha,scope=binaries-${{ env.PLATFORM_PAIR }}
          CACHE_TO: type=gha,scope=binaries-${{ env.PLATFORM_PAIR }},mode=max
      -
        name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: buildx
          path: ${{ env.DESTDIR }}/*
          if-no-files-found: error

  bin-image:
    runs-on: ubuntu-22.04
    if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/buildx' }}
    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
        with:
          version: ${{ env.BUILDX_VERSION }}
          driver-opts: image=${{ env.BUILDKIT_IMAGE }}
          buildkitd-flags: --debug
      -
        name: Docker meta
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ env.REPO_SLUG }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
          bake-target: meta-helper
      -
        name: Login to DockerHub
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push image
        uses: docker/bake-action@v3
        with:
          files: |
            ./docker-bake.hcl
            ${{ steps.meta.outputs.bake-file }}
          targets: image-cross
          push: ${{ github.event_name != 'pull_request' }}
          sbom: true
          set: |
            *.cache-from=type=gha,scope=bin-image
            *.cache-to=type=gha,scope=bin-image,mode=max

  release:
    runs-on: ubuntu-22.04
    needs:
      - binaries
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Download binaries
        uses: actions/download-artifact@v3
        with:
          name: buildx
          path: ${{ env.DESTDIR }}
      -
        name: Create checksums
        run: ./hack/hash-files
      -
        name: List artifacts
        run: |
          tree -nh ${{ env.DESTDIR }}
      -
        name: Check artifacts
        run: |
          find ${{ env.DESTDIR }} -type f -exec file -e ascii -- {} +
      -
        name: GitHub Release
        if: startsWith(github.ref, 'refs/tags/v')
        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          draft: true
          files: ${{ env.DESTDIR }}/*

  buildkit-edge:
    runs-on: ubuntu-22.04
    continue-on-error: true
    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
        with:
          version: ${{ env.BUILDX_VERSION }}
          driver-opts: image=moby/buildkit:master
          buildkitd-flags: --debug
      -
        # Just run a bake target to check eveything runs fine
        name: Build
        uses: docker/bake-action@v3
        with:
          targets: binaries