# This template is taken from the cruft example code, for further information please see:
# https://cruft.github.io/cruft/#automating-updates-with-github-actions
name: Automatic Update from package template

on:
  # Allow manual runs through the web UI
  workflow_dispatch:
  schedule:
    #        ┌───────── minute (0 - 59)
    #        │ ┌───────── hour (0 - 23)
    #        │ │ ┌───────── day of the month (1 - 31)
    #        │ │ │ ┌───────── month (1 - 12 or JAN-DEC)
    #        │ │ │ │ ┌───────── day of the week (0 - 6 or SUN-SAT)
    - cron: '0 7 * * 1'  # Every Monday at 7am UTC

permissions: {}

jobs:
  update:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v6  # zizmor: ignore[unpinned-uses]
        with:
          persist-credentials: false

      - uses: actions/setup-python@v6  # zizmor: ignore[unpinned-uses]
        with:
          python-version: "3.14"

      - name: Install Cruft
        run: python -m pip install git+https://github.com/Cadair/cruft@patch-p1

      - name: Check if update is available
        continue-on-error: false
        id: check
        run: |
          CHANGES=0
          if [ -f .cruft.json ]; then
            if ! cruft check; then
              CHANGES=1
            fi
          else
            echo "No .cruft.json file"
          fi

          echo "has_changes=$CHANGES" >> "$GITHUB_OUTPUT"

      - name: Run update if available
        id: cruft_update
        if: steps.check.outputs.has_changes == '1'
        run: |
          git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
          git config --global user.name "${GITHUB_ACTOR}"

          cruft_output=$(cruft update --skip-apply-ask --refresh-private-variables)
          echo $cruft_output
          git restore --staged .

          if [[ "$cruft_output" == *"Failed to cleanly apply the update, there may be merge conflicts."* ]]; then
            echo merge_conflicts=1 >> $GITHUB_OUTPUT
          else
            echo merge_conflicts=0 >> $GITHUB_OUTPUT
          fi

      - name: Check if only .cruft.json is modified
        id: cruft_json
        if: steps.check.outputs.has_changes == '1'
        run: |
          git status --porcelain=1
          if [[ "$(git status --porcelain=1)" == " M .cruft.json" ]]; then
            echo "Only .cruft.json is modified. Exiting workflow early."
            echo "has_changes=0" >> "$GITHUB_OUTPUT"
          else
            echo "has_changes=1" >> "$GITHUB_OUTPUT"
          fi

      - name: Create pull request
        if: steps.cruft_json.outputs.has_changes == '1'
        uses: peter-evans/create-pull-request@v8  # zizmor: ignore[unpinned-uses]
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          add-paths: "."
          commit-message: "Automatic package template update"
          branch: "cruft/update"
          delete-branch: true
          draft: ${{ steps.cruft_update.outputs.merge_conflicts == '1' }}
          title: "Updates from the package template"
          labels: |
            backport 7.0
            No Changelog Entry Needed
          body: |
            This is an autogenerated PR, which will applies the latest changes from the [SunPy Package Template](https://github.com/sunpy/package-template).
            If this pull request has been opened as a draft there are conflicts which need fixing.

            **To run the CI on this pull request you will need to close it and reopen it.**

  report-fail:
    if: failure()
    needs: [update]
    runs-on: ubuntu-latest
    permissions:
      issues: write
    steps:
      - name: Open an issue if workflow fails
        uses: actions/github-script@v7  # zizmor: ignore[unpinned-uses]
        with:
          github-token: ${{ github.token }}
          # This script is adapted from https://github.com/scientific-python/issue-from-pytest-log-action
          # Under MIT license (c) Scientific Python Developers
          script: |
            const fs = require('fs');

            // Edit these if needed for your repo
            const variables = {
              owner: context.repo.owner,
              name: context.repo.repo,
              label: "Infrastructure",
              creator: "app/github-actions",
              title: "SunPy Package Template auto-update failed."
            };

            const logs = 'The package update workflow failed.'
            const workflow_url = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
            const issue_body = `[Workflow Run URL](${workflow_url})\n${logs}`;

            const query_string = `repo:${variables.owner}/${variables.name} author:${variables.creator} label:${variables.label} is:open in:title ${variables.title}`;

            // Run GraphQL query against GitHub API to find the most recent open issue used for reporting failures
            const query = `query {
              search(query: "${query_string}", type:ISSUE, first: 1) {
                edges {
                  node {
                    ... on Issue {
                      body
                      id
                      number
                    }
                  }
                }
              }
            }`;

            const result = await github.graphql(query);

            // If no issue is open, create a new issue,
            // else update the body of the existing issue.
            if (result.search.edges.length === 0) {
              await github.rest.issues.create({
                owner: variables.owner,
                repo: variables.name,
                body: issue_body,
                title: variables.title,
                labels: [variables.label, "pre-commit.ci autofix"],
              });
            } else {
              await github.rest.issues.update({
                owner: variables.owner,
                repo: variables.name,
                issue_number: result.search.edges[0].node.number,
                body: issue_body
              });
            }
