name: Publish Docker

on:
  push:
    tags:
      - "*"
  workflow_dispatch:
    inputs:
      branch:
        description: "Branch to run the action on"
        default: "main"
        required: true

jobs:
  build_and_publish_platform_containers:
    name: Build and publish platform containers
    runs-on: ${{ matrix.os }}
    permissions:
      packages: write
    strategy:
      fail-fast: false
      matrix:
        os:
          - warp-ubuntu-latest-x64-2x
          - warp-ubuntu-latest-arm64-2x
        app:
          - name: unsend
            dockerfile: ./docker/Dockerfile
            context: .
          - name: smtp-proxy
            dockerfile: ./apps/smtp-server/Dockerfile
            context: ./apps/smtp-server

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

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

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

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

      - name: Build the docker image
        env:
          BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-2x' && 'arm64' || 'amd64' }}
          APP: ${{ matrix.app.name }}
          DOCKER_FILE: ${{ matrix.app.dockerfile }}
          CONTEXT: ${{ matrix.app.context }}
        run: |
          APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
          GIT_SHA="$(git rev-parse HEAD)"

          docker build \
            -f "$DOCKER_FILE" \
            --progress=plain \
            -t "unsend/$APP-$BUILD_PLATFORM:latest" \
            -t "unsend/$APP-$BUILD_PLATFORM:$GIT_SHA" \
            -t "unsend/$APP-$BUILD_PLATFORM:$APP_VERSION" \
            -t "ghcr.io/unsend-dev/$APP-$BUILD_PLATFORM:latest" \
            -t "ghcr.io/unsend-dev/$APP-$BUILD_PLATFORM:$GIT_SHA" \
            -t "ghcr.io/unsend-dev/$APP-$BUILD_PLATFORM:$APP_VERSION" \
            "$CONTEXT"

      - name: Push the docker image to DockerHub
        run: docker push --all-tags "unsend/$APP-$BUILD_PLATFORM"
        env:
          BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-2x' && 'arm64' || 'amd64' }}
          APP: ${{ matrix.app.name }}
          DOCKER_FILE: ${{ matrix.app.dockerfile }}
          CONTEXT: ${{ matrix.app.context }}

      - name: Push the docker image to GitHub Container Registry
        run: docker push --all-tags "ghcr.io/unsend-dev/$APP-$BUILD_PLATFORM"
        env:
          BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-2x' && 'arm64' || 'amd64' }}
          APP: ${{ matrix.app.name }}

  create_and_publish_manifest:
    name: Create and publish manifest
    runs-on: ubuntu-latest
    permissions:
      packages: write
    needs: build_and_publish_platform_containers
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

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

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

      - name: Create and push DockerHub manifest
        run: |
          APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
          GIT_SHA="$(git rev-parse HEAD)"

          for APP_NAME in unsend smtp-proxy; do
            docker manifest create \
              unsend/$APP_NAME:latest \
              --amend unsend/$APP_NAME-amd64:latest \
              --amend unsend/$APP_NAME-arm64:latest

            docker manifest create \
              unsend/$APP_NAME:$GIT_SHA \
              --amend unsend/$APP_NAME-amd64:$GIT_SHA \
              --amend unsend/$APP_NAME-arm64:$GIT_SHA

            docker manifest create \
              unsend/$APP_NAME:$APP_VERSION \
              --amend unsend/$APP_NAME-amd64:$APP_VERSION \
              --amend unsend/$APP_NAME-arm64:$APP_VERSION

            docker manifest push unsend/$APP_NAME:latest
            docker manifest push unsend/$APP_NAME:$GIT_SHA
            docker manifest push unsend/$APP_NAME:$APP_VERSION
          done

      - name: Create and push GitHub Container Registry manifest
        run: |
          APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
          GIT_SHA="$(git rev-parse HEAD)"

          for APP_NAME in unsend smtp-proxy; do
            docker manifest create \
              ghcr.io/unsend-dev/$APP_NAME:latest \
              --amend ghcr.io/unsend-dev/$APP_NAME-amd64:latest \
              --amend ghcr.io/unsend-dev/$APP_NAME-arm64:latest

            docker manifest create \
              ghcr.io/unsend-dev/$APP_NAME:$GIT_SHA \
              --amend ghcr.io/unsend-dev/$APP_NAME-amd64:$GIT_SHA \
              --amend ghcr.io/unsend-dev/$APP_NAME-arm64:$GIT_SHA

            docker manifest create \
              ghcr.io/unsend-dev/$APP_NAME:$APP_VERSION \
              --amend ghcr.io/unsend-dev/$APP_NAME-amd64:$APP_VERSION \
              --amend ghcr.io/unsend-dev/$APP_NAME-arm64:$APP_VERSION

            docker manifest push ghcr.io/unsend-dev/$APP_NAME:latest
            docker manifest push ghcr.io/unsend-dev/$APP_NAME:$GIT_SHA
            docker manifest push ghcr.io/unsend-dev/$APP_NAME:$APP_VERSION
          done
