name: Pull Request Linter on: workflow_call: pull_request: types: [edited, reopened] # This captures the PR title/body changing branches: - mealie-next jobs: validate-title: name: Validate PR title runs-on: ubuntu-latest steps: # https://github.com/amannn/action-semantic-pull-request - uses: amannn/action-semantic-pull-request@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: # Configure which types are allowed (newline-delimited). # Default: https://github.com/commitizen/conventional-commit-types types: | feat fix docs chore dev # Configure which scopes are allowed (newline-delimited). # These are regex patterns auto-wrapped in `^ $`. scopes: | deps auto l10n config # Configure that a scope must always be provided. requireScope: false # If the PR contains one of these newline-delimited labels, the # validation is skipped. If you want to rerun the validation when # labels change, you might want to use the `labeled` and `unlabeled` # event triggers in your workflow. ignoreLabels: | bot ignore-semantic-pull-request validate-template: name: Validate PR template runs-on: ubuntu-latest permissions: pull-requests: write steps: - name: Check required PR template sections uses: actions/github-script@v7 with: script: | const pr = context.payload.pull_request; if (pr.user.type === "Bot") { console.log("Skipping template check for bot"); return; } const response = await github.rest.repos.getContent({ owner: context.repo.owner, repo: context.repo.repo, path: ".github/pull_request_template.md", }); const template = Buffer.from(response.data.content, "base64").toString("utf8"); const lines = template.split("\n"); const requiredHeadings = []; let lastHeading = null; for (const line of lines) { if (line.startsWith("## ")) { lastHeading = line.trim(); } else if (line.trim() === "_(REQUIRED)_" && lastHeading) { requiredHeadings.push(lastHeading); lastHeading = null; } } const body = pr.body || ""; const missing = requiredHeadings.filter(h => !body.includes(h)); if (missing.length > 0) { core.setFailed(`Missing headings:\n${missing.join("\n")}`); } else { console.log("All required headings present"); }