name: Pre-commit auto-update

on:
  # every day at midnight
  schedule:
    - cron: "0 0 * * *"
  # on demand
  workflow_dispatch:

permissions:
  contents: read

jobs:
  auto-update:
    permissions:
      # Needed for peter-evans/create-pull-request to create branch
      contents: write
      # Needed for peter-evans/create-pull-request to create a PR
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

      - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
        id: app-token
        with:
          app-id: ${{ vars.SLICER_APP_ID }}
          private-key: ${{ secrets.SLICER_APP_PRIVATE_KEY }}

      - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: 3.12

      - run: pip install pre-commit

      - name: pre-commit autoupdate
        run: |
          # To ensure the output only contain lines like the following:
          #  `Updating https://github.com/org/user ... updating v1.2.3 -> v1.2.4`
          # without interleaved string like the following:
          #  `[INFO] Initializing environment for https://github.com/org/user.`
          # we perform the autoupdate twice. This ensures the second run can easily be parsed.
          pre-commit autoupdate --config .pre-commit-config.yaml > /dev/null 2>&1
          git checkout -- .pre-commit-config.yaml
          pre-commit autoupdate --config .pre-commit-config.yaml | tee /tmp/pre-commit-autoupdate.log

      - name: Save parse-autoupdate.py
        run: |
          cat <<EOF >> /tmp/parse-autoupdate.py
          import re
          import sys

          for line in sys.stdin:
              match = re.match(r"\[https://github.com/([^/]+/[^/]+)\] updating (v?[\d.]+) -> (v?[\d.]+)", line.strip())
              if match:
                  repo_url = match.group(1)
                  old_version = match.group(2)
                  new_version = match.group(3)
                  print(f"- [{repo_url}: {old_version} -> {new_version}](https://github.com/{repo_url}/compare/{old_version}...{new_version})")
          EOF

      - name: Parse autoupdate output
        id: parse-autoupdate
        run: |
          {
            echo 'AUTOUPDATE_LOG<<EOF'
            echo "updates:"
            cat /tmp/pre-commit-autoupdate.log | python /tmp/parse-autoupdate.py
            echo EOF
          } >> "$GITHUB_OUTPUT"
        shell: bash

      - uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
        with:
          token: ${{ steps.app-token.outputs.token }}
          commit-message: |
            ENH: Update pre-commit hooks

            ${{ steps.parse-autoupdate.outputs.AUTOUPDATE_LOG }}
          committer: slicer-app[bot] <163601113+slicer-app[bot]@users.noreply.github.com>
          author: slicer-app[bot] <163601113+slicer-app[bot]@users.noreply.github.com>
          signoff: false
          branch: update/pre-commit-hooks
          delete-branch: true
          title: "ENH: Update pre-commit hooks"
          body: |
            <!--pre-commit autoupdate log start-->
            ${{ steps.parse-autoupdate.outputs.AUTOUPDATE_LOG }}
            <!--pre-commit autoupdate log start-->

            This pull-request was auto-generated by the [pre-commit-autoupdate][1] GitHub action workflow.

            [1]: https://github.com/${{ github.repository }}/blob/main/.github/workflows/pre-commit-autoupdate.yml
          draft: false
