name: No important files changed

on:
  pull_request:
    types: [opened]
    branches: [main]

permissions:
  pull-requests: write

jobs:
  no_important_files_changed:
    name: No important files changed
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout code
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

      - name: Check if important files changed
        id: check
        run: |
          set -exo pipefail

          # fetch a ref to the main branch so we can diff against it
          git remote set-branches origin main
          git fetch --depth 1 origin main

          for changed_file in $(git diff --diff-filter=M --name-only origin/main); do
            if ! echo "$changed_file" | grep --quiet --extended-regexp 'exercises/(practice|concept)' ; then
              continue
            fi
            slug="$(echo "$changed_file" | sed --regexp-extended 's#exercises/[^/]+/([^/]+)/.*#\1#' )"
            path_before_slug="$(echo "$changed_file" | sed --regexp-extended "s#(.*)/$slug/.*#\\1#" )"
            path_after_slug="$( echo "$changed_file" | sed --regexp-extended "s#.*/$slug/(.*)#\\1#" )"

            if ! [ -f "$path_before_slug/$slug/.meta/config.json" ]; then
              # cannot determine if important files changed without .meta/config.json
              continue
            fi

            #  returns 0 if the filter matches, 1 otherwise
            #  | contains($path_after_slug)
            if jq --exit-status \
              --arg path_after_slug "$path_after_slug" \
              '[.files.test, .files.invalidator, .files.editor] | flatten | index($path_after_slug)' \
              "$path_before_slug/$slug/.meta/config.json" \
              > /dev/null;
            then
              echo "important_files_changed=true" >> "$GITHUB_OUTPUT"
              exit 0
            fi
          done

          echo "important_files_changed=false" >> "$GITHUB_OUTPUT"

      - name: Suggest to add [no important files changed]
        if: steps.check.outputs.important_files_changed == 'true'
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
        with:
          github-token: ${{ github.token }}
          script: |
            const body = "This PR touches files which potentially affect the outcome of the tests of an exercise. This will cause all students' solutions to affected exercises to be re-tested.\n\nIf this PR does **not** affect the result of the test (or, for example, adds an edge case that is not worth rerunning all tests for), **please add the following to the merge-commit message** which will stops student's tests from re-running. Please copy-paste to avoid typos.\n```\n[no important files changed]\n```\n\n For more information, refer to the [documentation](https://exercism.org/docs/building/tracks#h-avoiding-triggering-unnecessary-test-runs). If you are unsure whether to add the message or not, please ping `@exercism/maintainers-admin` in a comment. Thank you!"
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: body
            })
