chore: some minor things #10
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Check Linked Issue | ||
on: | ||
pull_request: | ||
types: [opened, edited, synchronize, reopened] | ||
workflow_dispatch: | ||
jobs: | ||
check-linked-issue: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Ensure PR is linked to an issue | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const query = ` | ||
query($owner: String!, $repo: String!, $number: Int!) { | ||
repository(owner: $owner, name: $repo) { | ||
pullRequest(number: $number) { | ||
title | ||
body | ||
closingIssuesReferences(first: 10) { | ||
nodes { | ||
number | ||
state | ||
} | ||
} | ||
} | ||
} | ||
} | ||
`; | ||
const { repository: { pullRequest: pr } } = await github.graphql(query, { | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
number: context.issue.number | ||
}); | ||
const textToCheck = `${pr.title} ${pr.body || ''}`; | ||
const issuePatterns = [ | ||
/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi, | ||
/#(\d+)/g, | ||
/(?:issue|issues)\s+#?(\d+)/gi, | ||
]; | ||
const linkedIssues = new Set(); | ||
// Find linked issues from patterns | ||
for (const pattern of issuePatterns) { | ||
for (const match of textToCheck.matchAll(pattern)) { | ||
if (match[1]) linkedIssues.add(match[1]); | ||
} | ||
} | ||
// Add issues from GitHub's closing references | ||
pr.closingIssuesReferences.nodes.forEach(node => { | ||
linkedIssues.add(node.number.toString()); | ||
}); | ||
// Check if no issues are linked | ||
if (linkedIssues.size === 0) { | ||
await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
body: ` | ||
## 🚫 Missing Linked Issue | ||
Hi 👋 This pull request does not appear to be linked to any open issue yet. | ||
Linking your PR to an issue helps keep the project tidy and ensures the issue is closed automatically. | ||
### ✔️ How to fix this | ||
- Add a keyword like \`Fixes #123\` or \`Closes #456\` to your PR **description** or a **commit message**. | ||
- Or link it manually using the **"Linked issues"** panel in the PR sidebar. | ||
> ✅ **Tip:** You can link multiple issues. | ||
> 🚫 **Note:** If only one issue is linked, it must be open for this check to pass. | ||
Once linked, this check will pass automatically on your next push or when you re-run the workflow. | ||
Thanks for helping maintainers! 🙌 | ||
` | ||
}); | ||
core.setFailed('❌ No linked issue found.'); | ||
return; | ||
} | ||
let openIssues = 0; | ||
// Check status of each linked issue | ||
for (const issueNumber of linkedIssues) { | ||
const issueQuery = ` | ||
query($owner: String!, $repo: String!, $number: Int!) { | ||
repository(owner: $owner, name: $repo) { | ||
issue(number: $number) { | ||
state | ||
} | ||
} | ||
} | ||
`; | ||
const { repository: { issue } } = await github.graphql(issueQuery, { | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
number: parseInt(issueNumber, 10) | ||
}); | ||
if (issue.state === 'OPEN') { | ||
openIssues++; | ||
} | ||
} | ||
// If only one issue is linked and it's closed, fail the check | ||
if (linkedIssues.size === 1 && openIssues === 0) { | ||
await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
body: ` | ||
## 🚫 Linked Issue is Closed | ||
Hi 👋 This pull request links only **one issue**, but that issue is **closed**. | ||
To pass this check, the linked issue must be **open** — or link an additional open issue. | ||
### ✔️ How to fix this | ||
- Reopen the linked issue if appropriate. | ||
- Or link another relevant **open** issue via the PR description or the **"Linked issues"** panel. | ||
Thanks for keeping the project healthy! 🚀 | ||
` | ||
}); | ||
core.setFailed('❌ Linked issue is closed.'); | ||
} else { | ||
console.log(`✅ PR is linked to issue(s): ${Array.from(linkedIssues).join(', ')}`); | ||
console.log(`✅ Number of open issues: ${openIssues}`); | ||
} |