name: Update vcpkg Baseline

on:
  schedule:
    - cron: "0 2 * * *"
  workflow_dispatch:

concurrency:
  group: update-vcpkg-baseline
  cancel-in-progress: false

jobs:
  update-baseline-on-main:
    runs-on: ubuntu-latest
    permissions:
      actions: write
      contents: write
      pull-requests: write
    if: github.ref == 'refs/heads/main'
    outputs:
      tag: ${{ steps.vcpkg.outputs.tag }}
      baseline: ${{ steps.vcpkg.outputs.baseline }}
      needs_update: ${{ steps.vcpkg.outputs.needs_update }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          ref: main

      - name: Get latest vcpkg release
        id: vcpkg
        shell: bash
        run: |
          set -euo pipefail
          latest_tag="$(curl -s https://api.github.com/repos/microsoft/vcpkg/releases/latest | jq -r '.tag_name')"
          echo "Latest tag: ${latest_tag}"

          latest_baseline="$(git ls-remote https://github.com/microsoft/vcpkg.git "refs/tags/${latest_tag}^{}" | awk '{print $1}')"
          if [[ -z "${latest_baseline}" ]]; then
            latest_baseline="$(git ls-remote https://github.com/microsoft/vcpkg.git "refs/tags/${latest_tag}" | awk '{print $1}')"
          fi

          echo "Baseline SHA: ${latest_baseline}"
          if [[ -z "${latest_baseline}" || "${latest_baseline}" == "null" ]]; then
            echo "Error: invalid baseline detected"
            exit 1
          fi

          current_baseline="$(jq -r '."builtin-baseline"' vcpkg.json)"

          echo "tag=${latest_tag}" >> "${GITHUB_OUTPUT}"
          echo "baseline=${latest_baseline}" >> "${GITHUB_OUTPUT}"
          echo "current=${current_baseline}" >> "${GITHUB_OUTPUT}"

          if [[ "${latest_baseline}" != "${current_baseline}" ]]; then
            echo "needs_update=true" >> "${GITHUB_OUTPUT}"
          else
            echo "needs_update=false" >> "${GITHUB_OUTPUT}"
          fi

      - name: Create or update single baseline PR
        if: steps.vcpkg.outputs.needs_update == 'true'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          RELEASE_TAG: ${{ steps.vcpkg.outputs.tag }}
          PREVIOUS: ${{ steps.vcpkg.outputs.current }}
          NEW_BASELINE: ${{ steps.vcpkg.outputs.baseline }}
        shell: bash
        run: |
          set -euo pipefail
          branch_name="chore/update-vcpkg-baseline"

          trigger_ci() {
            echo "Dispatching CI workflow for ${branch_name}"
            gh workflow run ci.yml --ref "${branch_name}"
          }

          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          existing_pr="$(gh pr list --state open --json number,headRefName | jq -r '.[] | select(.headRefName == "'"${branch_name}"'") | .number')"

          if [[ -n "${existing_pr}" ]]; then
            echo "Found existing baseline PR #${existing_pr}, updating it"
            git fetch origin "${branch_name}"
            git checkout "${branch_name}"

            current_in_branch="$(jq -r '."builtin-baseline"' vcpkg.json)"
            if [[ "${current_in_branch}" == "${NEW_BASELINE}" ]]; then
              echo "PR #${existing_pr} already has baseline ${NEW_BASELINE}"
              trigger_ci
              exit 0
            fi

            jq --arg baseline "${NEW_BASELINE}" '."builtin-baseline" = $baseline' vcpkg.json > vcpkg.json.tmp
            mv vcpkg.json.tmp vcpkg.json

            if git diff --quiet -- vcpkg.json; then
              echo "No baseline change to commit on ${branch_name}"
            else
              git add vcpkg.json
              git commit -m "chore: update vcpkg baseline to ${RELEASE_TAG}"
              git push origin "${branch_name}"
            fi

            gh pr edit "${existing_pr}" --title "chore: Update vcpkg baseline to ${RELEASE_TAG}"

            printf -v comment_body 'Updated to vcpkg **%s**\n\n**Previous baseline:** `%s`\n**New baseline:** `%s`\n\n**Release notes:** https://github.com/microsoft/vcpkg/releases/tag/%s' \
              "${RELEASE_TAG}" "${current_in_branch}" "${NEW_BASELINE}" "${RELEASE_TAG}"

            gh pr comment "${existing_pr}" --body "${comment_body}"
            trigger_ci
          else
            echo "No existing baseline PR found, creating new one"

            if git ls-remote --heads origin "${branch_name}" | grep -q "${branch_name}"; then
              git fetch origin "${branch_name}"
              git checkout "${branch_name}"
            else
              git checkout -b "${branch_name}"
            fi

            jq --arg baseline "${NEW_BASELINE}" '."builtin-baseline" = $baseline' vcpkg.json > vcpkg.json.tmp
            mv vcpkg.json.tmp vcpkg.json

            if git diff --quiet -- vcpkg.json; then
              echo "No baseline change to commit on ${branch_name}"
            else
              git add vcpkg.json
              git commit -m "chore: update vcpkg baseline to ${RELEASE_TAG}"
              git push --force-with-lease origin "${branch_name}"
            fi

            printf -v pr_body '## vcpkg Baseline Update\n\nThis PR updates the vcpkg baseline to the latest release.\n\n**Release:** `%s`\n**Previous:** `%s`\n**New:** `%s`\n\n**Release notes:** https://github.com/microsoft/vcpkg/releases/tag/%s\n\n---\nThis PR is automatically updated when new vcpkg releases are published.' \
              "${RELEASE_TAG}" "${PREVIOUS}" "${NEW_BASELINE}" "${RELEASE_TAG}"

            gh pr create \
              --title "chore: Update vcpkg baseline to ${RELEASE_TAG}" \
              --body "${pr_body}" \
              --base main \
              --head "${branch_name}"

            trigger_ci
          fi
