name: PR Check Command on: issue_comment: types: [created] jobs: check-pr: # Only run on PR comments that start with /check if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/check') runs-on: ubuntu-latest permissions: pull-requests: write issues: write steps: - name: Check PR requirements uses: actions/github-script@v7 with: script: | const prNumber = context.payload.issue.number; console.log(`Triggered by /check comment on PR #${prNumber}`); // Fetch PR data const { data: pr } = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: prNumber, }); const prBody = pr.body || ''; const prTitle = pr.title || ''; const prAuthor = pr.user.login; // Extract issue numbers const issuePattern = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)?\s*#(\d+)/gi; const allText = `${prTitle} ${prBody}`; const matches = [...allText.matchAll(issuePattern)]; const issueNumbers = [...new Set(matches.map(m => parseInt(m[1], 10)))]; console.log(`PR #${prNumber}:`); console.log(` Author: ${prAuthor}`); console.log(` Found issue references: ${issueNumbers.length > 0 ? issueNumbers.join(', ') : 'none'}`); if (issueNumbers.length === 0) { const message = `## PR Closed - Requirements Not Met This PR has been automatically closed because it doesn't meet the requirements. **Missing:** No linked issue found. **To fix:** 1. Create or find an existing issue for this work 2. Assign yourself to the issue 3. Re-open this PR and add \`Fixes #123\` in the description **Why is this required?** See #472 for details.`; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: message, }); await github.rest.pulls.update({ owner: context.repo.owner, repo: context.repo.repo, pull_number: prNumber, state: 'closed', }); core.setFailed('PR must reference an issue'); return; } // Check if PR author is assigned to any linked issue let issueWithAuthorAssigned = null; let issuesWithoutAuthor = []; for (const issueNum of issueNumbers) { try { const { data: issue } = await github.rest.issues.get({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueNum, }); const assigneeLogins = (issue.assignees || []).map(a => a.login); if (assigneeLogins.includes(prAuthor)) { issueWithAuthorAssigned = issueNum; console.log(` Issue #${issueNum} has PR author ${prAuthor} as assignee`); break; } else { issuesWithoutAuthor.push({ number: issueNum, assignees: assigneeLogins }); console.log(` Issue #${issueNum} assignees: ${assigneeLogins.length > 0 ? assigneeLogins.join(', ') : 'none'}`); } } catch (error) { console.log(` Issue #${issueNum} not found`); } } if (!issueWithAuthorAssigned) { const issueList = issuesWithoutAuthor.map(i => `#${i.number} (assignees: ${i.assignees.length > 0 ? i.assignees.join(', ') : 'none'})` ).join(', '); const message = `## PR Closed - Requirements Not Met This PR has been automatically closed because it doesn't meet the requirements. **PR Author:** @${prAuthor} **Found issues:** ${issueList} **Problem:** The PR author must be assigned to the linked issue. **To fix:** 1. Assign yourself (@${prAuthor}) to one of the linked issues 2. Re-open this PR **Why is this required?** See #472 for details.`; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: message, }); await github.rest.pulls.update({ owner: context.repo.owner, repo: context.repo.repo, pull_number: prNumber, state: 'closed', }); core.setFailed('PR author must be assigned to the linked issue'); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: `✅ PR requirements met! Issue #${issueWithAuthorAssigned} has @${prAuthor} as assignee.`, }); console.log(`PR requirements met!`); }