name: Verify Changeset
on:
  pull_request:
    types: [opened, reopened, synchronize, ready_for_review, labeled]
    paths:
      - "src/**"
      - "tsconfig.*"
      - "package.json"
  workflow_dispatch:

jobs:
  verify-changeset:
    if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-changeset') && !startsWith(github.head_ref, 'release/') && !startsWith(github.head_ref, 'conflict/') && !github.event.pull_request.draft }}
    name: Verify
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write
      contents: read
    steps:
      - name: Verify changeset included
        uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
        with:
          script: |
            const dir = '.changeset/';
            const pr = context.payload.pull_request;
            const files = await github.paginate(
              github.rest.pulls.listFiles,
              { owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, per_page: 100 }
            );
            const ok = files.some(f =>
              f.filename.startsWith(dir) &&
              ['added','modified','renamed'].includes(f.status)
            );
            if (ok) {
              core.info(`Changeset found under ${dir}.`);
            } else {
              core.setFailed(`No changeset added to ${dir}.`);
            }
            core.setOutput('ok', ok ? 'true' : 'false');
      - name: Add or update changeset comment on failure
        uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
        if: failure()
        with:
          script: |
            const pr = context.payload.pull_request;
            const marker = '<!-- changeset-bot-comment -->';
            const body = [
              marker,
              "❌ **Changeset file missing for PR**",
              "",
              "All changes should include an associated changeset file.",
              "Please use `knope document-change` to create a changeset. (installation instructions: https://knope.tech/installation/)"
            ].join("\n");

            const comments = await github.paginate(
              github.rest.issues.listComments,
              { owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number }
            );
            const existing = comments.find(c => c.body.includes(marker));

            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body: body
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                body: body
              });
            }

      - name: Add or update changeset comment on success
        uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
        if: success()
        with:
          script: |
            const pr = context.payload.pull_request;
            const marker = '<!-- changeset-bot-comment -->';
            const body = [
              marker,
              "✅ **Changeset file added - thank you!**"
            ].join("\n");

            const comments = await github.paginate(
              github.rest.issues.listComments,
              { owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number }
            );
            const existing = comments.find(c => c.body.includes(marker));

            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body: body
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                body: body
              });
            }

  handle-skip-label:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'skip-changeset') && github.head_ref != 'release' && !startsWith(github.head_ref, 'release/') && !startsWith(github.head_ref, 'conflict/') && !github.event.pull_request.draft }}
    name: Handle Skip Label
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write
    steps:
      - name: Add or update comment to show skipped
        uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
        with:
          script: |
            const pr = context.payload.pull_request;
            const marker = '<!-- changeset-bot-comment -->';
            const body = [
              marker,
              "⏭️ **Changeset check skipped via label**"
            ].join("\n");

            const comments = await github.paginate(
              github.rest.issues.listComments,
              { owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number }
            );
            const existing = comments.find(c => c.body.includes(marker));

            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body: body
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                body: body
              });
            }
