fix: DockerFile #184
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: Ensure PR has linked issue | |
on: | |
pull_request: | |
types: [opened, edited, synchronize, reopened] | |
workflow_dispatch: | |
jobs: | |
check-linked-issue: | |
name: Ensure PR has linked issue # 👈 Must EXACTLY match your branch protection rule! | |
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 | |
}); | |
// Check PR body for issue references | |
const prTitle = pr.title || ''; | |
// Skip check for release PRs | |
if (prTitle.startsWith('release: v')) { | |
console.log('🔄 Skipping linked issue check for release PR'); | |
core.notice('✅ Release PR - linked issue check skipped'); | |
return; | |
} | |
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(); | |
for (const pattern of issuePatterns) { | |
for (const match of textToCheck.matchAll(pattern)) { | |
if (match[1]) linkedIssues.add(match[1]); | |
} | |
} | |
pr.closingIssuesReferences.nodes.forEach(node => { | |
linkedIssues.add(node.number.toString()); | |
}); | |
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\n\nHi 👋 This pull request does not appear to be linked to any open issue yet.\n\nLinking your PR to an issue helps keep the project tidy and ensures the issue is closed automatically.\n\n### ✔️ How to fix this\n\n- Add a keyword like `Fixes #123` or `Closes #456` to your PR **description** or a **commit message**.\n- Or link it manually using the **\"Linked issues\"** panel in the PR sidebar.\n\n> ✅ **Tip:** You can link multiple issues.\n> 🚫 **Note:** If only one issue is linked, it must be open for this check to pass.\n\nOnce linked, this check will pass automatically on your next push or when you re-run the workflow.\n\nThanks for helping maintainers! 🙌" | |
}); | |
core.setFailed('❌ No linked issue found.'); | |
return; | |
} | |
let openIssues = 0; | |
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 (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\n\nHi 👋 This pull request links only **one issue**, but that issue is **closed**.\n\nTo pass this check, the linked issue must be **open** — or link an additional open issue.\n\n### ✔️ How to fix this\n\n- Reopen the linked issue if appropriate.\n- Or link another relevant **open** issue via the PR description or the **\"Linked issues\"** panel.\n\nThanks 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}`); | |
} |