# GitHub actions workflow which builds and publishes the docker images.

name: Build docker images

on:
  push:
    tags: ["v*"]
    branches: [ master, main, develop ]
  workflow_dispatch:

permissions:
  contents: read
  packages: write
  id-token: write # needed for signing the images with GitHub OIDC Token
jobs:
  build:
    runs-on: ubuntu-22.04
    steps:
      - name: Set up QEMU
        id: qemu
        uses: docker/setup-qemu-action@v3
        with:
          platforms: arm64

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

      - name: Inspect builder
        run: docker buildx inspect

      - name: Install Cosign
        uses: sigstore/cosign-installer@v3.8.1

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Extract version from pyproject.toml
        # Note: explicitly requesting bash will mean bash is invoked with `-eo pipefail`, see
        # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
        shell: bash
        run: |
          echo "SYNAPSE_VERSION=$(grep "^version" pyproject.toml | sed -E 's/version\s*=\s*["]([^"]*)["]/\1/')" >> $GITHUB_ENV

      - name: Log in to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Calculate docker image tag
        id: set-tag
        uses: docker/metadata-action@master
        with:
          images: |
            docker.io/matrixdotorg/synapse
            ghcr.io/element-hq/synapse
          flavor: |
            latest=false
          tags: |
            type=raw,value=develop,enable=${{ github.ref == 'refs/heads/develop' }}
            type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
            type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
            type=pep440,pattern={{raw}}

      - name: Build and push all platforms
        id: build-and-push
        uses: docker/build-push-action@v6
        with:
          push: true
          labels: |
            gitsha1=${{ github.sha }}
            org.opencontainers.image.version=${{ env.SYNAPSE_VERSION }}
          tags: "${{ steps.set-tag.outputs.tags }}"
          file: "docker/Dockerfile"
          platforms: linux/amd64,linux/arm64

          # arm64 builds OOM without the git fetch setting. c.f.
          # https://github.com/rust-lang/cargo/issues/10583
          build-args: |
            CARGO_NET_GIT_FETCH_WITH_CLI=true

      - name: Sign the images with GitHub OIDC Token
        env:
          DIGEST: ${{ steps.build-and-push.outputs.digest }}
          TAGS: ${{ steps.set-tag.outputs.tags }}
        run: |
          images=""
          for tag in ${TAGS}; do
            images+="${tag}@${DIGEST} "
          done
          cosign sign --yes ${images}
