Skip to content

Commit 6b133d2

Browse files
committed
[GITHUB] Add PR title and commit validation to CI workflow
1 parent 023d9fa commit 6b133d2

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

.github/workflows/valid-tags.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[GEN]
2+
[ZH]
3+
[CMAKE]
4+
[GITHUB]
5+
[CORE]
6+
[LINUX]
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Validate Pull Request
2+
3+
permissions:
4+
contents: read
5+
pull-requests: write
6+
7+
on:
8+
pull_request:
9+
branches:
10+
- main
11+
types:
12+
- opened
13+
- edited
14+
- synchronize
15+
- reopened
16+
17+
jobs:
18+
validate-title-and-commits:
19+
name: Validate Title and Commits
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 5
22+
23+
steps:
24+
- name: Checkout Code
25+
uses: actions/checkout@v4
26+
27+
- name: Load valid tags
28+
id: load-tags
29+
run: |
30+
if [ ! -f ./.github/workflows/valid-tags.txt ]; then
31+
echo "::error::.github/workflows/valid-tags.txt file not found"
32+
exit 1
33+
fi
34+
35+
echo "**Valid tags**: $(cat ./.github/workflows/valid-tags.txt | tr '\n' ',' | sed 's/,/, /g' | sed 's/, $//')" >> $GITHUB_STEP_SUMMARY
36+
37+
TAG_REGEX=$(sed 's/[]\/$*.^|[]/\\&/g' ./.github/workflows/valid-tags.txt | paste -sd "|" -)
38+
39+
# Matches:
40+
# 1) One or more valid tags at the beginning, directly adjacent, followed by at least one space, then text
41+
# 2) Text that does not start with '[' (i.e. no tags)
42+
echo "regex=^((($TAG_REGEX)){1,}[[:space:]]+.*|[^[]+.*)$" >> $GITHUB_OUTPUT
43+
44+
echo "Built the regex: ^((($TAG_REGEX)){1,}[[:space:]]+.*|[^[]+.*)$"
45+
46+
- name: Validate PR title
47+
id: validate_title
48+
run: |
49+
echo "### Validate PR Title" >> $GITHUB_STEP_SUMMARY
50+
REGEX="${{ steps.load-tags.outputs.regex }}"
51+
TITLE=$(jq -r '.pull_request.title // "No title found"' "$GITHUB_EVENT_PATH")
52+
53+
ESCAPED_TITLE=$(echo "$TITLE" | sed 's/["\`\\$]/\\&/g')
54+
55+
if [[ ! "$TITLE" =~ $REGEX ]]; then
56+
echo "- ❌ PR title \"$ESCAPED_TITLE\" is invalid." >> $GITHUB_STEP_SUMMARY
57+
echo "TITLE_VALID=false" >> $GITHUB_OUTPUT
58+
else
59+
echo "- ✅ PR title \"$ESCAPED_TITLE\" is valid." >> $GITHUB_STEP_SUMMARY
60+
echo "TITLE_VALID=true" >> $GITHUB_OUTPUT
61+
fi
62+
63+
- name: Validate PR commits
64+
id: validate_commits
65+
run: |
66+
echo "### Validate PR Commits" >> $GITHUB_STEP_SUMMARY
67+
REGEX="${{ steps.load-tags.outputs.regex }}"
68+
git fetch --prune --unshallow origin ${{ github.base_ref }}
69+
COMMITS=$(git log origin/${{ github.base_ref }}..HEAD --pretty=format:"%s" --no-merges)
70+
71+
INVALID_COMMITS=0
72+
73+
while read -r COMMIT_MSG; do
74+
if [[ -z "$COMMIT_MSG" ]]; then
75+
continue
76+
fi
77+
ESCAPED_MSG=$(echo "$COMMIT_MSG" | sed 's/["\`\\$]/\\&/g')
78+
if [[ ! "$COMMIT_MSG" =~ $REGEX ]]; then
79+
echo "- ❌ Commit message \"$ESCAPED_MSG\" is invalid." >> $GITHUB_STEP_SUMMARY
80+
INVALID_COMMITS=$((INVALID_COMMITS+1))
81+
else
82+
echo "- ✅ Commit message \"$ESCAPED_MSG\" is valid." >> $GITHUB_STEP_SUMMARY
83+
fi
84+
done <<< "$COMMITS"
85+
86+
if [[ $INVALID_COMMITS -gt 0 ]]; then
87+
echo "COMMITS_VALID=false" >> $GITHUB_OUTPUT
88+
else
89+
echo "COMMITS_VALID=true" >> $GITHUB_OUTPUT
90+
fi
91+
92+
- name: Validation return code
93+
run: |
94+
if [[ "${{ steps.validate_title.outputs.TITLE_VALID }}" != "true" || "${{ steps.validate_commits.outputs.COMMITS_VALID }}" != "true" ]]; then
95+
exit 1
96+
fi

0 commit comments

Comments
 (0)