|
23 | 23 | uses: zrr1999/zendev-actions/validate-title@9013ad848b32d287d0258fdbc9f51e350b8eca33 |
24 | 24 | with: |
25 | 25 | text: ${{ github.event.pull_request.title }} |
| 26 | + |
| 27 | + description: |
| 28 | + name: PR description |
| 29 | + runs-on: ubuntu-latest |
| 30 | + steps: |
| 31 | + - uses: actions/checkout@v6 |
| 32 | + |
| 33 | + - name: Check PR description headings |
| 34 | + env: |
| 35 | + GITHUB_EVENT_PATH: ${{ github.event_path }} |
| 36 | + run: | |
| 37 | + python - <<'PY' |
| 38 | + import json |
| 39 | + import os |
| 40 | + import re |
| 41 | + import sys |
| 42 | + from pathlib import Path |
| 43 | +
|
| 44 | + def extract_h2_headings(text: str) -> list[str]: |
| 45 | + in_fence = False |
| 46 | + headings = [] |
| 47 | + for line in text.splitlines(): |
| 48 | + stripped = line.strip() |
| 49 | + if stripped.startswith("```"): |
| 50 | + in_fence = not in_fence |
| 51 | + continue |
| 52 | + if in_fence: |
| 53 | + continue |
| 54 | + if re.match(r"^##\s+\S", stripped): |
| 55 | + headings.append(re.sub(r"^##\s+", "", stripped)) |
| 56 | + return headings |
| 57 | +
|
| 58 | + payload = json.loads(Path(os.environ["GITHUB_EVENT_PATH"]).read_text(encoding="utf-8")) |
| 59 | + body = (payload.get("pull_request") or {}).get("body") or "" |
| 60 | + template = Path(".github/pull_request_template.md").read_text(encoding="utf-8") |
| 61 | +
|
| 62 | + expected = extract_h2_headings(template) |
| 63 | + actual = extract_h2_headings(body) |
| 64 | +
|
| 65 | + if actual != expected: |
| 66 | + print("PR description headings do not match the repository template.", file=sys.stderr) |
| 67 | + print(f"Expected headings: {expected}", file=sys.stderr) |
| 68 | + print(f"Actual headings: {actual}", file=sys.stderr) |
| 69 | + raise SystemExit(1) |
| 70 | +
|
| 71 | + print("PR description headings match the repository template.") |
| 72 | + PY |
0 commit comments