name: Build and Push Docker Images

on:
  push:
    tags:
      - 'v*'  # 只在推送 v 开头的 tag 时触发（如 v1.0.0）
  workflow_dispatch:  # 手动触发

# 并发控制：同一分支只保留最新的构建，取消之前正在运行的
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  REGISTRY: docker.io
  IMAGE_PREFIX: yyhuni

permissions:
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - image: xingrin-server
            dockerfile: docker/server/Dockerfile
            context: .
            platforms: linux/amd64,linux/arm64
          - image: xingrin-frontend
            dockerfile: docker/frontend/Dockerfile
            context: .
            platforms: linux/amd64  # ARM64 构建时 Next.js 在 QEMU 下会崩溃
          - image: xingrin-worker
            dockerfile: docker/worker/Dockerfile
            context: .
            platforms: linux/amd64,linux/arm64
          - image: xingrin-nginx
            dockerfile: docker/nginx/Dockerfile
            context: .
            platforms: linux/amd64,linux/arm64
          - image: xingrin-agent
            dockerfile: docker/agent/Dockerfile
            context: .
            platforms: linux/amd64,linux/arm64

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

      - name: Free disk space (for large builds like worker)
        run: |
          echo "=== Before cleanup ==="
          df -h
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf /usr/local/lib/android
          sudo rm -rf /opt/ghc
          sudo rm -rf /opt/hostedtoolcache/CodeQL
          sudo docker image prune -af
          echo "=== After cleanup ==="
          df -h

      - name: Generate SSL certificates for nginx build
        if: matrix.image == 'xingrin-nginx'
        run: |
          mkdir -p docker/nginx/ssl
          openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
            -keyout docker/nginx/ssl/privkey.pem \
            -out docker/nginx/ssl/fullchain.pem \
            -subj "/CN=localhost"
          echo "SSL certificates generated for CI build"

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

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

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

      - name: Get version from git tag
        id: version
        run: |
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
            echo "IS_RELEASE=true" >> $GITHUB_OUTPUT
          else
            echo "VERSION=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
            echo "IS_RELEASE=false" >> $GITHUB_OUTPUT
          fi

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: ${{ matrix.context }}
          file: ${{ matrix.dockerfile }}
          platforms: ${{ matrix.platforms }}
          push: true
          tags: |
            ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }}
            ${{ steps.version.outputs.IS_RELEASE == 'true' && format('{0}/{1}:latest', env.IMAGE_PREFIX, matrix.image) || '' }}
          build-args: |
            IMAGE_TAG=${{ steps.version.outputs.VERSION }}
          cache-from: type=gha,scope=${{ matrix.image }}
          cache-to: type=gha,mode=max,scope=${{ matrix.image }}
          provenance: false
          sbom: false

  # 所有镜像构建成功后，更新 VERSION 文件
  # 根据 tag 所在的分支更新对应分支的 VERSION 文件
  update-version:
    runs-on: ubuntu-latest
    needs: build
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # 获取完整历史，用于判断 tag 所在分支
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Determine source branch and version
        id: branch
        run: |
          VERSION="${GITHUB_REF#refs/tags/}"
          
          # 查找包含此 tag 的分支
          BRANCHES=$(git branch -r --contains ${{ github.ref_name }})
          echo "Branches containing tag: $BRANCHES"
          
          # 判断 tag 来自哪个分支
          if echo "$BRANCHES" | grep -q "origin/main"; then
            TARGET_BRANCH="main"
            UPDATE_LATEST="true"
          elif echo "$BRANCHES" | grep -q "origin/dev"; then
            TARGET_BRANCH="dev"
            UPDATE_LATEST="false"
          else
            echo "Warning: Tag not found in main or dev branch, defaulting to main"
            TARGET_BRANCH="main"
            UPDATE_LATEST="false"
          fi
          
          echo "BRANCH=$TARGET_BRANCH" >> $GITHUB_OUTPUT
          echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
          echo "UPDATE_LATEST=$UPDATE_LATEST" >> $GITHUB_OUTPUT
          echo "Will update VERSION on branch: $TARGET_BRANCH"

      - name: Checkout target branch
        run: |
          git checkout ${{ steps.branch.outputs.BRANCH }}

      - name: Update VERSION file
        run: |
          VERSION="${{ steps.branch.outputs.VERSION }}"
          echo "$VERSION" > VERSION
          echo "Updated VERSION to $VERSION on branch ${{ steps.branch.outputs.BRANCH }}"

      - name: Commit and push
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add VERSION
          git diff --staged --quiet || git commit -m "chore: bump version to ${{ steps.branch.outputs.VERSION }}"
          git push origin ${{ steps.branch.outputs.BRANCH }}
