name: Check mergeability

on: pull_request_target

permissions:
  pull-requests: write
  checks: write
  statuses: write

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - name: Check if there is already a block on this PR
        id: blocked
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        env:
          issue_number:  ${{ github.event.number }}
        with:
          script: |
            const { data: reviews } = await github.rest.pulls.listReviews({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: process.env.issue_number,
            });

            for (const review of reviews) {
              if (review.user.login === 'github-actions[bot]' && review.state === 'CHANGES_REQUESTED') {
                return 'true'
              }
            }
            return 'false'
          result-encoding: string

      - name: Get changed files in the .changeset folder
        id: changed-files
        uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
        if: steps.blocked.outputs.result != 'true'
        with:
          files: |
            .changeset/**/*.md
      - name: Check if any changesets contain minor or major changes
        id: check
        if: steps.changed-files.outputs.any_changed == 'true'
        env:
          ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        with:
          script: |
            core.setOutput('found', 'false');

            const regex = /["']astro["']: (minor|major)/;
            const changedFiles = process.env.ALL_CHANGED_FILES.split(/\s+/).filter(Boolean);
            const { owner, name: repo } = context.payload.pull_request.head.repo;
            const ref = context.payload.pull_request.head.sha;

            for (const file of changedFiles) {
              const { data } = await github.rest.repos.getContent({
                owner: owner.login,
                repo,
                path: file,
                ref,
              });

              if (Array.isArray(data) || !('content' in data)) {
                continue;
              }

              const contents = Buffer.from(data.content, 'base64').toString('utf8');
              const match = contents.match(regex);

              if (match) {
                const version = match[1];
                core.setOutput('version', version);
                core.setOutput('found', 'true');
                console.log(`${file} has a ${version} release tag`);
                break;
              }
            }

      - name: Add label
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        if: steps.check.outputs.found == 'true'
        env:
          issue_number: ${{ github.event.number }}
        with:
          script: |
            github.rest.issues.addLabels({
              issue_number: process.env.issue_number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              labels: ['semver: ${{ steps.check.outputs.version }}']
            });

      - name: Change PR Status
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        if: steps.check.outputs.found == 'true'
        env:
          issue_number: ${{ github.event.number }}
        with:
          script: |
            github.rest.pulls.createReview({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: process.env.issue_number,
              event: 'REQUEST_CHANGES',
              body: 'This PR is blocked because it contains a `${{ steps.check.outputs.version }}` changeset. A reviewer will merge this at the next release if approved.'
            });
