name: Build Multi-Architecture Docker Images

on:
  workflow_dispatch:

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          # backend
          - image: backend
            file: ./Dockerfile.backend
            tag: phact/openrag-backend
            platform: linux/amd64
            arch: amd64
            runs-on: ubuntu-latest
          - image: backend
            file: ./Dockerfile.backend
            tag: phact/openrag-backend
            platform: linux/arm64
            arch: arm64
            runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-2]

          # frontend
          - image: frontend
            file: ./Dockerfile.frontend
            tag: phact/openrag-frontend
            platform: linux/amd64
            arch: amd64
            runs-on: ubuntu-latest
          - image: frontend
            file: ./Dockerfile.frontend
            tag: phact/openrag-frontend
            platform: linux/arm64
            arch: arm64
            runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-2]

          # langflow
          - image: langflow
            file: ./Dockerfile.langflow
            tag: phact/openrag-langflow
            platform: linux/amd64
            arch: amd64
            runs-on: ubuntu-latest
          - image: langflow
            file: ./Dockerfile.langflow
            tag: phact/openrag-langflow
            platform: linux/arm64
            arch: arm64
            runs-on: self-hosted

          # opensearch
          - image: opensearch
            file: ./Dockerfile
            tag: phact/openrag-opensearch
            platform: linux/amd64
            arch: amd64
            runs-on: ubuntu-latest
          - image: opensearch
            file: ./Dockerfile
            tag: phact/openrag-opensearch
            platform: linux/arm64
            arch: arm64
            runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-2]

    runs-on: ${{ matrix.runs-on }}

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

      - name: Extract version from pyproject.toml
        id: version
        run: |
          VERSION=$(grep '^version = ' pyproject.toml | cut -d '"' -f 2)
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Version: $VERSION"

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

      - name: Login to Docker Hub
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push ${{ matrix.image }} (${{ matrix.arch }})
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ${{ matrix.file }}
          platforms: ${{ matrix.platform }}
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ matrix.tag }}:${{ steps.version.outputs.version }}-${{ matrix.arch }}
          cache-from: type=gha,scope=${{ matrix.image }}-${{ matrix.arch }}
          cache-to: type=gha,mode=max,scope=${{ matrix.image }}-${{ matrix.arch }}

  manifest:
    needs: build
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Extract version from pyproject.toml
        id: version
        run: |
          VERSION=$(grep '^version = ' pyproject.toml | cut -d '"' -f 2)
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Create and push multi-arch manifests
        run: |
          VERSION=${{ steps.version.outputs.version }}

          docker buildx imagetools create -t phact/openrag-backend:$VERSION \
            phact/openrag-backend:$VERSION-amd64 \
            phact/openrag-backend:$VERSION-arm64
          docker buildx imagetools create -t phact/openrag-backend:latest \
            phact/openrag-backend:$VERSION-amd64 \
            phact/openrag-backend:$VERSION-arm64

          docker buildx imagetools create -t phact/openrag-frontend:$VERSION \
            phact/openrag-frontend:$VERSION-amd64 \
            phact/openrag-frontend:$VERSION-arm64
          docker buildx imagetools create -t phact/openrag-frontend:latest \
            phact/openrag-frontend:$VERSION-amd64 \
            phact/openrag-frontend:$VERSION-arm64

          docker buildx imagetools create -t phact/openrag-langflow:$VERSION \
            phact/openrag-langflow:$VERSION-amd64 \
            phact/openrag-langflow:$VERSION-arm64
          docker buildx imagetools create -t phact/openrag-langflow:latest \
            phact/openrag-langflow:$VERSION-amd64 \
            phact/openrag-langflow:$VERSION-arm64

          docker buildx imagetools create -t phact/openrag-opensearch:$VERSION \
            phact/openrag-opensearch:$VERSION-amd64 \
            phact/openrag-opensearch:$VERSION-arm64
          docker buildx imagetools create -t phact/openrag-opensearch:latest \
            phact/openrag-opensearch:$VERSION-amd64 \
            phact/openrag-opensearch:$VERSION-arm64
