-
Notifications
You must be signed in to change notification settings - Fork 12
132 lines (113 loc) · 3.54 KB
/
pr-checks.yml
File metadata and controls
132 lines (113 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
---
name: '🔍 PR Validation'
on:
workflow_call:
inputs:
types:
required: false
type: string
default: |
fix
feat
docs
ci
chore
test
refactor
style
perf
build
revert
requireScope:
required: false
type: boolean
default: false
subjectPattern:
required: false
type: string
default: '[A-Za-z].+'
validateSingleCommit:
required: false
type: boolean
default: false
checkLabels:
required: false
type: boolean
default: true
commitlintConfig:
description: "Path to commitlint configuration file"
required: false
type: string
default: "commitlint.config.cjs"
jobs:
validate-title:
name: 📝 Validate PR title
runs-on: ubuntu-latest
steps:
- name: Validate PR title format
run: |
TITLE="${{ github.event.pull_request.title }}"
echo "PR Title: $TITLE"
shopt -s nocasematch
TYPES=$(echo "${{ inputs.types }}" | tr ',\n' '|' | sed 's/|$//')
# Full regex for conventional commits
FULL_REGEX="^(${TYPES})(\([a-zA-Z0-9_-]+\))?:\s+${{ inputs.subjectPattern }}$"
if [[ ! "$TITLE" =~ $FULL_REGEX ]]; then
echo "::error::PR title does not follow Conventional Commit format."
echo ""
echo "Required format:"
echo " type(scope): subject"
echo " type: subject"
echo ""
echo "Examples:"
echo " feat: Add login API"
echo " fix(auth): Resolve token issue"
echo " docs(readme): Update README"
echo ""
echo "Allowed types:"
echo "${{ inputs.types }}"
exit 1
fi
# Enforce scope if required
if [[ "${{ inputs.requireScope }}" == "true" ]]; then
if [[ ! "$TITLE" =~ ^(${TYPES})\([a-zA-Z0-9_-]+\): ]]; then
echo "::error::PR title must include a scope because requireScope=true"
echo "Example:"
echo " feat(auth): Add login API"
exit 1
fi
fi
echo "PR title validation passed."
- name: 🏷️ Check PR labels
if: ${{ inputs.checkLabels && github.event.pull_request.head.repo.fork == false }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [ -z "$(gh api repos/$GITHUB_REPOSITORY/issues/${{ github.event.pull_request.number }}/labels --jq '.[].name')" ]; then
echo "::error::No labels found on this PR. Please add at least one label."
exit 1
else
echo "PR has labels, validation passed."
fi
validate-commits:
name: 🧾 Validate Commit Messages
runs-on: ubuntu-latest
steps:
- name: 📦 Checkout Repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: 🔢 Validate single commit
if: ${{ inputs.validateSingleCommit }}
run: |
COUNT=$(git rev-list --count origin/${{ github.base_ref }}..HEAD)
echo "Commit count in PR: $COUNT"
if [ "$COUNT" -ne 1 ]; then
echo "::error::This PR must contain exactly one commit."
exit 1
fi
- name: 🧾 Commitlint Validation
uses: wagoid/commitlint-github-action@v6
with:
configFile: ${{ inputs.commitlintConfig }}
...