Clarify PR template checkboxes that must always be checked

The "when reasonable" checkboxes read as optional, but the contribution
policy workflow requires all boxes checked. Reword them as either/or
statements and accept the legacy wording in the policy script so
existing PRs keep validating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-07-05 08:36:23 -07:00
parent 4cad671305
commit f2972ee534
2 changed files with 25 additions and 13 deletions
+4 -2
View File
@@ -4,12 +4,14 @@
## Submission ## Submission
<!-- Check every box below except at most one of the first two (bug fixes only need the first). The last two must be checked even when they do not apply — checking confirms you considered them. -->
- [ ] This PR is a bug fix. - [ ] This PR is a bug fix.
- [ ] If this PR is not a bug fix, I linked the feedback item where @gschier explicitly gave me permission to work on it. - [ ] If this PR is not a bug fix, I linked the feedback item where @gschier explicitly gave me permission to work on it.
- [ ] I have read and followed [`CONTRIBUTING.md`](CONTRIBUTING.md). - [ ] I have read and followed [`CONTRIBUTING.md`](CONTRIBUTING.md).
- [ ] I tested this change locally. - [ ] I tested this change locally.
- [ ] I added or updated tests when reasonable. - [ ] I added or updated tests, or tests are not reasonable for this change.
- [ ] I added screenshots or recordings for UI changes when reasonable. - [ ] I added screenshots or recordings, or this change does not affect the UI.
Explicit permission feedback item (required if not a bug fix): Explicit permission feedback item (required if not a bug fix):
+21 -11
View File
@@ -53,16 +53,25 @@ const MANAGED_LABEL_NAMES = [
...new Set(Object.values(LABELS).map((label) => label.name)), ...new Set(Object.values(LABELS).map((label) => label.name)),
]; ];
// Each checkbox lists its current label first, followed by legacy labels still
// accepted from PRs opened against older versions of the template.
const CHECKBOXES = { const CHECKBOXES = {
bugFix: "This PR is a bug fix.", bugFix: ["This PR is a bug fix."],
explicitPermission: explicitPermission: [
"If this PR is not a bug fix, I linked the feedback item where @gschier explicitly gave me permission to work on it.", "If this PR is not a bug fix, I linked the feedback item where @gschier explicitly gave me permission to work on it.",
readContributing: ],
readContributing: [
"I have read and followed [`CONTRIBUTING.md`](CONTRIBUTING.md).", "I have read and followed [`CONTRIBUTING.md`](CONTRIBUTING.md).",
testedLocally: "I tested this change locally.", ],
testsUpdated: "I added or updated tests when reasonable.", testedLocally: ["I tested this change locally."],
screenshotsAdded: testsUpdated: [
"I added or updated tests, or tests are not reasonable for this change.",
"I added or updated tests when reasonable.",
],
screenshotsAdded: [
"I added screenshots or recordings, or this change does not affect the UI.",
"I added screenshots or recordings for UI changes when reasonable.", "I added screenshots or recordings for UI changes when reasonable.",
],
}; };
function escapeRegExp(value) { function escapeRegExp(value) {
@@ -102,8 +111,8 @@ function normalizeCheckboxLabel(label) {
.trim(); .trim();
} }
function checkboxState(body, label) { function checkboxState(body, labels) {
const expectedLabel = normalizeCheckboxLabel(label); const expectedLabels = new Set(labels.map(normalizeCheckboxLabel));
for (const line of body.split("\n")) { for (const line of body.split("\n")) {
const match = line.match(/^\s*[-*]\s*\[([ xX])\]\s*(.*?)\s*$/i); const match = line.match(/^\s*[-*]\s*\[([ xX])\]\s*(.*?)\s*$/i);
@@ -112,7 +121,7 @@ function checkboxState(body, label) {
continue; continue;
} }
if (normalizeCheckboxLabel(match[2]) === expectedLabel) { if (expectedLabels.has(normalizeCheckboxLabel(match[2]))) {
return match[1].toLowerCase() === "x"; return match[1].toLowerCase() === "x";
} }
} }
@@ -255,7 +264,8 @@ function analyzePullRequest(pr) {
if (states.testsUpdated !== true) { if (states.testsUpdated !== true) {
blockers.push({ blockers.push({
label: LABELS.policyUnmet.name, label: LABELS.policyUnmet.name,
message: "Confirm that tests were added or updated when reasonable.", message:
"Confirm that tests were added or updated, or that tests are not reasonable for this change. Check the box either way.",
}); });
} }
@@ -263,7 +273,7 @@ function analyzePullRequest(pr) {
blockers.push({ blockers.push({
label: LABELS.policyUnmet.name, label: LABELS.policyUnmet.name,
message: message:
"Confirm that screenshots or recordings were added for UI changes when reasonable.", "Confirm that screenshots or recordings were added, or that this change does not affect the UI. Check the box either way.",
}); });
} }
} }