-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Auto-comment on PR template CI failure #10015
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,38 +49,57 @@ jobs: | |
|
||
validate-pr-template: | ||
if: github.event_name == 'pull_request' | ||
|
||
runs-on: ubuntu-latest | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, and you're going to need to add a permissions stanza that is specific to this job with increased permissions, so that the bot can write comments on the PR. |
||
steps: | ||
- name: Validate PR template | ||
- name: Validate PR template and comment | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const body = context.payload.pull_request.body || ""; | ||
const pr = context.payload.pull_request; | ||
const body = pr.body || ""; | ||
|
||
// 1. Check both checkboxes | ||
const checkbox1 = /\[x\].*?There is reasonable content/i.test(body); | ||
const checkbox2 = /\[x\].*?I have read and accepted/i.test(body); | ||
|
||
// 2. URL must be on the exact "The site content can be seen at ..." line | ||
// https://regex101.com/r/N36fsT | ||
const urlLineRegex = /^[ \t]*-[ \t]*The site content can be seen at[ \t]+(?:<)?(?:\[.*?\]\()?https?:\/\/[^\s>()]+(?:\))?(?:>)?/m; | ||
const urlMatch = urlLineRegex.exec(body); | ||
const urlValid = urlMatch !== null; | ||
|
||
// 3. Explanation must follow the blockquote marker | ||
const urlValid = urlLineRegex.exec(body) !== null; | ||
const explanationMatch = />\s*The site content is(?:\s*|\s*\n)(.+)/i.exec(body); | ||
const explanation = explanationMatch && explanationMatch[1].trim().length > 10; | ||
|
||
if (!checkbox1 || !checkbox2 || !urlValid || !explanation) { | ||
core.setFailed( | ||
"❌ PR template is not properly filled:\n" + | ||
`Checkbox1: ${checkbox1 ? '✅' : '❌'}\n` + | ||
`Checkbox2: ${checkbox2 ? '✅' : '❌'}\n` + | ||
`URL on correct line: ${urlValid ? '✅' : '❌'}\n` + | ||
`Explanation: ${explanation ? '✅' : '❌'}` | ||
); | ||
const failed = !checkbox1 || !checkbox2 || !urlValid || !explanation; | ||
|
||
if (!failed) { | ||
console.log("✅ PR template is valid."); | ||
return; | ||
} | ||
|
||
const commentBody = `❌ **PR template is not properly filled:**\n\n- Checkbox1 (reasonable content): ${checkbox1 ? "✅" : "❌"}\n- Checkbox2 (read and accepted): ${checkbox2 ? "✅" : "❌"}\n- URL on correct line: ${urlValid ? "✅" : "❌"}\n- Explanation (> The site content is...): ${explanation ? "✅" : "❌"}\n\nPlease update your PR description accordingly.`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we might want some more explicit guidance here on exactly the markup that the check is expecting to find when a check has failed? I also wonder if we simply don't need to include the bits that're okay, to reduce the information that a requester needs to read through? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use an actual multi-line template literal here, instead of encoded |
||
|
||
const { data: comments } = await github.rest.issues.listComments({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: pr.number, | ||
}); | ||
|
||
const existingComment = comments.find(c => | ||
c.user.login === 'github-actions[bot]' && | ||
c.body.includes("**PR template is not properly filled:**") | ||
); | ||
|
||
if (existingComment) { | ||
await github.rest.issues.updateComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
comment_id: existingComment.id, | ||
body: commentBody | ||
}); | ||
} else { | ||
console.log("✅ PR template format is valid."); | ||
await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: pr.number, | ||
body: commentBody | ||
}); | ||
} | ||
|
||
core.setFailed("PR template validation failed."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might need to set a concurrency restriction on this, so that you don't end up in a race if the user edits the body multiple times in quick succession, with the wrong comment being the one that ends up sent to GitHub?