mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-06-02 15:10:29 -04:00
91 lines
2.8 KiB
YAML
91 lines
2.8 KiB
YAML
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");
|
|
}
|