MicroFish/.github/workflows/pr-hygiene.yml

58 lines
1.7 KiB
YAML

name: PR Hygiene
on:
pull_request:
types:
- opened
- edited
- reopened
- synchronize
permissions:
contents: read
pull-requests: read
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Validate pull request body
uses: actions/github-script@v7
with:
script: |
const body = context.payload.pull_request.body || "";
function getSection(title) {
const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const regex = new RegExp(`##\\s+${escaped}\\s*\\n([\\s\\S]*?)(?=\\n##\\s+|$)`, "i");
const match = body.match(regex);
return match ? match[1].trim() : "";
}
const linkedIssue = getSection("Linked issue");
const howToTest = getSection("How to test");
const hasIssueReference =
/#\d+/.test(linkedIssue) ||
/https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/issues\/\d+/i.test(linkedIssue);
const sanitizedHowToTest = howToTest
.replace(/Describe the verification steps\. If no runtime test applies, explain why\./i, "")
.trim();
const failures = [];
if (!hasIssueReference) {
failures.push("Add an issue reference under `## Linked issue` (for example `Closes #123`).");
}
if (!sanitizedHowToTest) {
failures.push("Fill in `## How to test` with verification steps or explain why no runtime test applies.");
}
if (failures.length > 0) {
core.setFailed(failures.join("\n"));
} else {
core.info("Pull request body passed hygiene checks.");
}