name: "Label Fixed Issues" on: pull_request: types: [closed] branches: - develop jobs: label-issues: name: "Add 'fixed in develop' label to referenced issues" runs-on: ubuntu-latest # Only run if the PR was actually merged (not just closed) if: github.event.pull_request.merged == true permissions: issues: write pull-requests: read steps: - name: Extract issue numbers from PR id: extract_issues uses: actions/github-script@v8 with: script: | const prBody = context.payload.pull_request.body || ''; const prTitle = context.payload.pull_request.title || ''; // Strip
blocks (used by dependabot PRs) and fenced code // blocks from the body to avoid matching issue numbers that appear // in collapsed/code sections rather than as real references. const strippedBody = prBody .replace(//gi, '') .replace(/```[\s\S]*?```/g, ''); const combinedText = `${prTitle}\n${strippedBody}`; // Match patterns like "fixes #123", "fixes owner/repo#456", // "fixes https://github.com/owner/repo/issues/789", etc. // This regex matches common GitHub issue reference patterns const issueRegex = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?|ref(?:erence)?|see|issue)\s+(?:https?:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/(\d+)|[^\/\s]+\/[^\/\s]+#(\d+)|[:#]?\s*(\d+))|#(\d+)/gi; const matches = [...combinedText.matchAll(issueRegex)]; // Extract unique issue numbers const issueNumbers = [...new Set(matches.map(match => match[1] || match[2] || match[3] || match[4]))]; console.log(`Found issue references: ${issueNumbers.join(', ')}`); // If a PR references more than two issues it is likely a broad // change that should not automatically label every mentioned issue. if (issueNumbers.length > 2) { console.log(`Skipping: PR references ${issueNumbers.length} issues (more than 2).`); return []; } return issueNumbers; - name: Add label to issues uses: actions/github-script@v8 with: script: | const issueNumbers = ${{ steps.extract_issues.outputs.result }}; if (!issueNumbers || issueNumbers.length === 0) { console.log('No issues found to label'); return; } const label = 'fixed in develop'; const owner = context.repo.owner; const repo = context.repo.repo; for (const issueNumber of issueNumbers) { try { // Add the label to the issue await github.rest.issues.addLabels({ owner, repo, issue_number: parseInt(issueNumber), labels: [label], }); console.log(`Added '${label}' label to issue #${issueNumber}`); } catch (error) { const msg = `Failed to label issue #${issueNumber}`; console.error(`${msg}: ${error.message}`); } }