Skip to content

Commit 1d4f27a

Browse files
committed
update workflow.yml for PR verification
1 parent a00604a commit 1d4f27a

3 files changed

Lines changed: 134 additions & 0 deletions

File tree

.github/pull_request_template.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Pull Request Checklist
2+
3+
- [ ] My change keeps template folders self-contained.
4+
- [ ] Template folder names use lowercase letters and hyphens.
5+
- [ ] I did not add secrets, tokens, or machine-specific files.
6+
- [ ] README or docs updates are included when needed.
7+
- [ ] I kept the change focused and avoided unrelated cleanup.

.github/scripts/check_pr_rules.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env python3
2+
"""Validate contribution rules that can be checked automatically."""
3+
4+
from __future__ import annotations
5+
6+
import re
7+
import sys
8+
from pathlib import Path
9+
10+
11+
ROOT = Path(__file__).resolve().parents[2]
12+
TEMPLATES = ROOT / "templates"
13+
NAME_RE = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
14+
SUSPICIOUS_FILES = {
15+
".env",
16+
".env.local",
17+
".env.production",
18+
"id_rsa",
19+
"id_dsa",
20+
"id_ecdsa",
21+
"id_ed25519",
22+
}
23+
SUSPICIOUS_CONTENT = (
24+
"BEGIN PRIVATE KEY",
25+
"BEGIN RSA PRIVATE KEY",
26+
"ghp_",
27+
"github_pat_",
28+
"xoxb-",
29+
"xoxa-",
30+
"aws_secret_access_key",
31+
"api_key=",
32+
"secret=",
33+
)
34+
35+
36+
def fail(message: str, errors: list[str]) -> None:
37+
errors.append(message)
38+
39+
40+
def main() -> int:
41+
errors: list[str] = []
42+
43+
if not TEMPLATES.is_dir():
44+
fail("templates/ folder is missing.", errors)
45+
report(errors)
46+
return 1
47+
48+
templates_readme = TEMPLATES / "README.md"
49+
if not templates_readme.is_file():
50+
fail("templates/README.md is missing.", errors)
51+
52+
for template_dir in sorted(p for p in TEMPLATES.iterdir() if p.is_dir() and not p.name.startswith(".")):
53+
if template_dir.name == "__pycache__":
54+
continue
55+
56+
if not NAME_RE.fullmatch(template_dir.name):
57+
fail(
58+
f"Template folder '{template_dir.name}' should use lowercase letters, numbers, and hyphens only.",
59+
errors,
60+
)
61+
62+
readme = template_dir / "README.md"
63+
if not readme.is_file():
64+
fail(f"Template folder '{template_dir.name}' is missing a README.md file.", errors)
65+
66+
for path in template_dir.rglob("*"):
67+
if not path.is_file():
68+
continue
69+
70+
if path.name.lower() in SUSPICIOUS_FILES:
71+
fail(
72+
f"Template '{template_dir.name}' contains a sensitive-looking file name: {path.relative_to(ROOT)}",
73+
errors,
74+
)
75+
76+
try:
77+
text = path.read_text(encoding="utf-8")
78+
except UnicodeDecodeError:
79+
continue
80+
81+
for marker in SUSPICIOUS_CONTENT:
82+
if marker in text:
83+
fail(
84+
f"Template '{template_dir.name}' contains a suspicious secret-like pattern in {path.relative_to(ROOT)}.",
85+
errors,
86+
)
87+
break
88+
89+
if errors:
90+
report(errors)
91+
return 1
92+
93+
print("PR rules check passed.")
94+
return 0
95+
96+
97+
def report(errors: list[str]) -> None:
98+
print("PR rules check failed:\n", file=sys.stderr)
99+
for error in errors:
100+
print(f"- {error}", file=sys.stderr)
101+
102+
103+
if __name__ == "__main__":
104+
raise SystemExit(main())

.github/workflows/pr-rules.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Pull Request Rules Check
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
validate:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.11"
21+
22+
- name: Validate contribution rules
23+
run: python .github/scripts/check_pr_rules.py

0 commit comments

Comments
 (0)