name: Build FastGPT images

on:
  workflow_dispatch:
  push:
    paths:
      - "projects/app/**"
      - "packages/**"
    tags:
      - "v*"

jobs:
  build-fastgpt-images:
    permissions:
      packages: write
      contents: read
      attestations: write
      id-token: write
    strategy:
      matrix:
        sub_routes:
          - repo: fastgpt
            base_url: ""
          - repo: fastgpt-sub-route
            base_url: "/fastai"
          - repo: fastgpt-sub-route-gchat
            base_url: "/gchat"
        archs:
          - arch: amd64
          - arch: arm64
            runs-on: ubuntu-24.04-arm
    runs-on: ${{ matrix.archs.runs-on || 'ubuntu-24.04' }}
    steps:
      # install env
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver-opts: network=host

      - name: Cache Docker layers
        uses: actions/cache@v4
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-${{ matrix.archs.arch }}-${{ matrix.sub_routes.repo }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.archs.arch }}-${{ matrix.sub_routes.repo }}-buildx-

      # login docker
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Login to Ali Hub
        uses: docker/login-action@v3
        with:
          registry: registry.cn-hangzhou.aliyuncs.com
          username: ${{ secrets.ALI_HUB_USERNAME }}
          password: ${{ secrets.ALI_HUB_PASSWORD }}
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_NAME }}
          password: ${{ secrets.DOCKER_HUB_PASSWORD }}

      - name: Build for ${{ matrix.archs.arch }}
        id: build
        uses: docker/build-push-action@v6
        with:
          context: .
          file: projects/app/Dockerfile
          platforms: linux/${{ matrix.archs.arch }}
          build-args: |
            ${{ matrix.sub_routes.base_url && format('base_url={0}', matrix.sub_routes.base_url) || '' }}
          labels: |
            org.opencontainers.image.source=https://github.com/${{ github.repository }}
            org.opencontainers.image.description=${{ matrix.sub_routes.repo }} image
          outputs: type=image,"name=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }},${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }},${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}",push-by-digest=true,push=true
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache

      - name: Export digest
        run: |
          mkdir -p ${{ runner.temp }}/digests/${{ matrix.sub_routes.repo }}
          digest="${{ steps.build.outputs.digest }}"
          touch "${{ runner.temp }}/digests/${{ matrix.sub_routes.repo }}/${digest#sha256:}"

      - name: Upload digest
        uses: actions/upload-artifact@v4
        with:
          name: digests-${{ matrix.sub_routes.repo }}-${{ github.sha }}-${{ matrix.archs.arch }}
          path: ${{ runner.temp }}/digests/${{ matrix.sub_routes.repo }}/*
          if-no-files-found: error
          retention-days: 1

  release-fastgpt-images:
    permissions:
      packages: write
      contents: read
      attestations: write
      id-token: write
    needs: build-fastgpt-images
    strategy:
      matrix:
        sub_routes:
          - repo: fastgpt
          - repo: fastgpt-sub-route
          - repo: fastgpt-sub-route-gchat
    runs-on: ubuntu-24.04
    steps:
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Login to Ali Hub
        uses: docker/login-action@v3
        with:
          registry: registry.cn-hangzhou.aliyuncs.com
          username: ${{ secrets.ALI_HUB_USERNAME }}
          password: ${{ secrets.ALI_HUB_PASSWORD }}
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_NAME }}
          password: ${{ secrets.DOCKER_HUB_PASSWORD }}

      - name: Download digests
        uses: actions/download-artifact@v4
        with:
          path: ${{ runner.temp }}/digests
          pattern: digests-${{ matrix.sub_routes.repo }}-${{ github.sha }}-*
          merge-multiple: true

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

      - name: Set image name and tag
        run: |
          if [[ "${{ github.ref_name }}" == "main" ]]; then
            echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
          else
            echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:${{ github.ref_name }}" >> $GITHUB_ENV
            echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:${{ github.ref_name }}" >> $GITHUB_ENV
            echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
            echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:${{ github.ref_name }}" >> $GITHUB_ENV
            echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
          fi

      - name: Create manifest list and push
        working-directory: ${{ runner.temp }}/digests
        run: |
          TAGS="$(echo -e "${Git_Tag}\n${Git_Latest}\n${Ali_Tag}\n${Ali_Latest}\n${Docker_Hub_Tag}\n${Docker_Hub_Latest}")"
          for TAG in $TAGS; do
            docker buildx imagetools create -t $TAG \
              $(printf 'ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}@sha256:%s ' *)
            sleep 5
          done
