Skip to content

Commit 158b7a1

Browse files
authored
ci: require semantic PR titles and head commits (#24)
1 parent 70fc9d9 commit 158b7a1

1 file changed

Lines changed: 28 additions & 15 deletions

File tree

.github/workflows/pr-title.yml

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: PR Title
1+
name: Semantic PR Title
22

33
on:
44
pull_request:
@@ -13,36 +13,49 @@ permissions:
1313
pull-requests: read
1414

1515
concurrency:
16-
group: pr-title-${{ github.workflow }}-${{ github.event.pull_request.number }}
16+
group: semantic-pr-title-${{ github.workflow }}-${{ github.event.pull_request.number }}
1717
cancel-in-progress: true
1818

1919
jobs:
20-
conventional-pr-title:
20+
semantic-pr-title:
2121
runs-on: ubuntu-latest
2222
steps:
23-
- name: Validate PR title
23+
- name: Check out PR head
24+
uses: actions/checkout@v5
25+
with:
26+
ref: ${{ github.event.pull_request.head.sha }}
27+
fetch-depth: 1
28+
29+
- name: Validate semantic PR title and head commit subject
2430
env:
2531
PR_TITLE: ${{ github.event.pull_request.title }}
2632
run: |
2733
python3 - <<'PY'
2834
import os
2935
import re
36+
import subprocess
3037
import sys
3138
32-
title = os.environ["PR_TITLE"]
3339
pattern = re.compile(
3440
r"^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([^)]+\))?(!)?: .+"
3541
)
42+
allowed = "build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test"
3643
37-
if pattern.match(title):
38-
print("PR title is a valid conventional commit title.")
39-
raise SystemExit(0)
44+
def validate(label: str, value: str) -> None:
45+
if pattern.match(value):
46+
print(f"{label} is a valid conventional commit title: {value}")
47+
return
4048
41-
print(f"Invalid PR title: {title}", file=sys.stderr)
42-
print("Expected format: type(scope): description", file=sys.stderr)
43-
print(
44-
"Allowed types: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test",
45-
file=sys.stderr,
46-
)
47-
raise SystemExit(1)
49+
print(f"Invalid {label}: {value}", file=sys.stderr)
50+
print("Expected format: type(scope): description", file=sys.stderr)
51+
print(f"Allowed types: {allowed}", file=sys.stderr)
52+
raise SystemExit(1)
53+
54+
validate("PR title", os.environ["PR_TITLE"])
55+
56+
head_subject = subprocess.check_output(
57+
["git", "log", "-1", "--pretty=%s"],
58+
text=True,
59+
).strip()
60+
validate("head commit subject", head_subject)
4861
PY

0 commit comments

Comments
 (0)