| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- name: Check pull request template
- # Runs on pull_request_target so the token can comment, label, and close pull
- # requests that come from forks. Only the base branch is checked out, and the
- # script reads nothing but the pull request body, so the head commit never runs.
- on:
- pull_request_target:
- types: [opened, edited, reopened]
- permissions:
- pull-requests: write
- jobs:
- template:
- if: >-
- github.event.pull_request.user.login != 'wsvincent' &&
- github.event.pull_request.user.login != 'jefftriplett' &&
- github.event.pull_request.user.login != 'dependabot[bot]'
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- with:
- ref: ${{ github.event.repository.default_branch }}
- sparse-checkout: .github/scripts
- - uses: actions/github-script@v7
- with:
- script: |
- const { checkTemplate } = require("./.github/scripts/check-pr-template.js");
- const pr = context.payload.pull_request;
- const { owner, repo } = context.repo;
- const issue_number = pr.number;
- const LABEL = "needs-template";
- const MARKER = "<!-- pr-template-check -->";
- const { missing, company } = checkTemplate(pr.body);
- const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number, per_page: 100 });
- const existing = comments.find((c) => c.body && c.body.includes(MARKER));
- async function say(body) {
- body = `${MARKER}\n${body}`;
- if (existing) {
- await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
- } else {
- await github.rest.issues.createComment({ owner, repo, issue_number, body });
- }
- }
- if (missing.length) {
- const list = missing.map((m) => `- ${m}`).join("\n");
- await say(
- `Thanks for the submission! This pull request does not fill out the ` +
- `[pull request template](https://github.com/${owner}/${repo}/blob/main/.github/pull_request_template.md), ` +
- `so it was closed automatically.\n\nMissing:\n${list}\n\n` +
- `Edit the pull request description to add the missing items. ` +
- `The check runs again on every edit and reopens the pull request when the template is complete.`
- );
- await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [LABEL] });
- if (pr.state === "open") {
- await github.rest.pulls.update({ owner, repo, pull_number: issue_number, state: "closed" });
- }
- return;
- }
- const hadLabel = pr.labels.some((l) => l.name === LABEL);
- if (hadLabel) {
- await github.rest.issues.removeLabel({ owner, repo, issue_number, name: LABEL }).catch(() => {});
- if (pr.state === "closed" && !pr.merged_at) {
- await github.rest.pulls.update({ owner, repo, pull_number: issue_number, state: "open" });
- }
- }
- let note = "The pull request template is complete. Thanks! A maintainer will review it.";
- if (company) {
- note +=
- `\n\nThis submission is on behalf of a company. Please read the ` +
- `[commercial products and services](https://github.com/${owner}/${repo}/blob/main/contributing.md#commercial-products-and-services) ` +
- `section of the contribution guidelines.`;
- }
- if (existing || company) await say(note);
|