name: App Version CI/CD

on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened

env:
  GH_TOKEN: ${{ github.token }}
  PR_NUMBER: ${{ github.event.pull_request.number }}

jobs:
  get-latest-commit-author:
    name: Get Latest Commit Author
    runs-on: ubuntu-latest
    outputs:
      latest_commit_author: ${{ steps.latest-commit-author.outputs.latest_commit_author }}
    steps:
      - name: Get latest commit author
        id: latest-commit-author
        run: |
          resp=$(gh api \
            -H "Accept: application/vnd.github+json" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            /repos/${{ github.repository}}/commits/${{ github.event.pull_request.head.ref }})
          author=$(echo "$resp" | jq -r '.author.login // empty')
          echo "the Author of Latest Commit on Head Branch: $author"
          echo "latest_commit_author=$author" >> $GITHUB_OUTPUT

  update-app-version:
    name: Update App Version
    needs: get-latest-commit-author
    if: |
      github.actor == 'renovate[bot]' &&
      github.triggering_actor == 'renovate[bot]' &&
      needs.get-latest-commit-author.outputs.latest_commit_author != github.repository_owner &&
      startsWith(github.head_ref, 'renovate/')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      statuses: write
    steps:
      - name: Checkout
        uses: actions/checkout@v5.0.0
        with:
          fetch-depth: 0
          ref: ${{ github.head_ref }}

      - uses: actions/setup-python@main
        with:
          python-version: 3.x
          pip-install: PyYAML

      - name: Configure repo
        run: |
          git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"

      - name: Get list of updated files by the last commit in this branch separated by space
        id: updated-files
        run: |
          # 当触发工作流的事件为 pull_request 时，github.sha 值为 github.ref 分支上的最后一次合并提交
          files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.pull_request.head.sha }} | tr '\n' ' ')
          if [ -z "$files" ]; then
            echo "❌ 错误：没有检测到文件变更"
            echo "github.sha = ${{ github.sha }}"
            echo "github.event.pull_request.head.sha = ${{ github.event.pull_request.head.sha }}"
            echo "当前分支最新的提交SHA: $(git rev-parse HEAD)"
            echo "💡 最近三次提交："
            echo "   $(git log -3)"
            exit 1
          else
            echo "files=$files" >> $GITHUB_OUTPUT
          fi

      - name: Run renovate-app-version.py on updated files
        run: |
          IFS=' ' read -ra files <<< "${{ steps.updated-files.outputs.files }}"

          for file in "${files[@]}"; do
            if [[ $file == *"docker-compose.yml"* ]]; then
              app_name=$(echo $file | cut -d'/' -f 2)
              old_version=$(echo $file | cut -d'/' -f 3)
              python3 .github/workflows/renovate-app-version.py $app_name $old_version
            fi
          done

      - name: Commit & Push Changes
        run: |
          IFS=' ' read -ra files <<< "${{ steps.updated-files.outputs.files }}"
          commits_counter=0
          for file in "${files[@]}"; do
            if [[ $file == *"docker-compose.yml"* ]]; then
              app_name=$(echo $file | cut -d'/' -f 2)
              old_version=$(echo $file | cut -d'/' -f 3)
              if [ -f "apps/$app_name/${old_version}.version" ]; then
                new_version=$(cat "apps/$app_name/${old_version}.version")
                rm -f "apps/$app_name/${old_version}.version"
                echo "处理: $app_name - $old_version → $new_version"
                if [ ! -d "apps/$app_name/$old_version" ]; then
                  echo "✅ 旧目录不存在: apps/$app_name/$old_version"
                fi
                if [ -d "apps/$app_name/$new_version" ]; then
                  echo "✅ 新目录存在: apps/$app_name/$new_version"
                else
                  echo "⚠️ 新目录不存在: apps/$app_name/$new_version"
                  exit 1
                fi
                git reset
                git rm -r "apps/$app_name/$old_version"
                git add "apps/$app_name/$new_version"
                if git diff --cached --quiet; then
                  echo "⚠️ 没有检测到文件变更，跳过提交"
                else
                  git commit -m "🔧 chore($app_name): update app version from $old_version to $new_version" --no-verify
                  echo "✅ 已提交: $old_version → $new_version"
                  commits_counter=$((commits_counter + 1))
                  echo "第 $commits_counter 个提交"
                fi
              else
                echo "处理: $app_name - $old_version"
                echo "⚠️ 没有找到版本标记文件: apps/$app_name/${old_version}.version"
              fi
            fi
          done
          if [ $commits_counter -gt 0 ]; then
            echo "推送 $commits_counter 个提交到远程仓库..."
            git push
            gh api --silent --method POST -H "Accept: application/vnd.github+json" \
              -H "X-GitHub-Api-Version: 2022-11-28" \
              /repos/${{ github.repository }}/statuses/$(git show -s --format=%H) \
              -f 'state=success' \
              -f 'target_url=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' \
              -f 'description=CI/CD' \
              -f 'context=${{ github.workflow}}'
          else
            echo "没有提交需要推送"
          fi

  check-labels:
    name: Check labels
    if: |
      github.actor == 'renovate[bot]' &&
      github.triggering_actor == 'renovate[bot]'
    runs-on: ubuntu-latest
    outputs:
      enable: ${{ steps.check-labels.outputs.enable }}
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Check for major label
        id: check-labels
        run: |
          pr_labels='${{ join(github.event.pull_request.labels.*.name, ',') }}'
          if [[ $pr_labels =~ "major" ]]; then
            echo "❌ PR has major label"
            echo "enable=false" >> $GITHUB_OUTPUT
          else
            echo "✅ PR does not have major label"
            echo "enable=true" >> $GITHUB_OUTPUT
          fi
      
      # - name: Add reviewer and comment for major PR
      #   if: steps.check-labels.outputs.enable == 'false'
      #   run: |
      #     gh pr edit $PR_NUMBER --add-reviewer ${{ github.repository_owner }}
      #     gh pr edit $PR_NUMBER --add-assignee ${{ github.repository_owner }}
      
      - name: remove labels
        run: |
          pr_labels='${{ join(github.event.pull_request.labels.*.name, ',') }}'
          IFS=',' read -ra labels_array <<< "$pr_labels"
          for label in "${labels_array[@]}"; do
            echo "Removing label: $label"
            gh pr edit $PR_NUMBER --remove-label="$label"
          done

  merge-prs:
    name: Auto Merge the PR
    runs-on: ubuntu-latest
    needs: 
      - update-app-version
      - check-labels
    if: |
      needs.check-labels.outputs.enable == 'true' &&
      (needs.update-app-version.result == 'success' || needs.update-app-version.result == 'skipped')
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5
        with:
          ref: ${{ github.base_ref }}
      
      - name: Merge PR
        run: |
          max_attempts=5
          for attempt in $(seq 1 $max_attempts); do
            if gh pr merge $PR_NUMBER --squash --delete-branch --body ""; then
              echo "✅ Merge PR #$PR_NUMBER Success"
              exit 0
            else
              echo "⚠️ Merge PR #$PR_NUMBER Failed ($attempt / $max_attempts)"
              sleep 5
            fi
          done
