Skip to content

Commit f04eb87

Browse files
author
lhw
committed
7.23 test
1 parent eed0a94 commit f04eb87

2 files changed

Lines changed: 231 additions & 50 deletions

File tree

.github/workflows/commit.yml

Lines changed: 230 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,271 @@
11
name: Custom Commit Message Validator
22

3+
4+
5+
36
on:
7+
48
pull_request:
5-
types: [opened, reopened, synchronize] # Triggers on PR open, reopen, or new commits pushed to the PR branch
9+
10+
types: [opened, reopened, synchronize]
11+
12+
13+
614

715
jobs:
8-
validate_commit_messages:
9-
runs-on: ubuntu-latest # Specifies the runner environment
16+
17+
validate_COMMIT_MESSAGEs:
18+
19+
runs-on: ubuntu-latest
20+
21+
22+
1023

1124
permissions:
12-
contents: read # Needed for checkout
13-
pull-requests: read # Needed to fetch PR details and commit SHAs
25+
26+
contents: read
27+
28+
pull-requests: read
29+
30+
31+
1432

1533
steps:
34+
1635
- name: Checkout Repository
17-
uses: actions/checkout@v4 # Action to checkout your repository
36+
37+
uses: actions/checkout@v4
38+
1839
with:
19-
fetch-depth: 0 # Fetches the entire history for git log operations. Crucial for retrieving full commit messages.
40+
41+
fetch-depth: 0
42+
43+
44+
2045

2146
- name: Get PR Commits SHAs
47+
2248
id: get_pr_commits
49+
2350
run: |
24-
# Use GitHub CLI to get all commit SHAs associated with the current Pull Request.
25-
# This robustly gets the commits that are part of the PR's changes.
26-
# The jq filter extracts the 'oid' (Object ID, which is the SHA) of each commit.
51+
52+
# Fetch all commit SHAs associated with the current Pull Request
53+
54+
55+
2756
PR_COMMIT_SHAS=$(gh pr view ${{ github.event.pull_request.number }} --json commits --jq '[.commits[].oid] | join(" ")')
28-
# Output the SHAs as a space-separated string.
29-
# This variable will be accessible via steps.get_pr_commits.outputs.PR_COMMITS_LIST
57+
58+
59+
60+
3061
echo "PR_COMMITS_LIST=${PR_COMMIT_SHAS}" >> "$GITHUB_OUTPUT"
62+
3163
env:
32-
# GITHUB_TOKEN is automatically provided by GitHub Actions with sufficient permissions.
64+
65+
3366
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3467

68+
69+
70+
3571
- name: Validate Each Commit Message
72+
73+
env:
74+
75+
TARGET_DATE: "2025-07-22" # Only check commits after this date
76+
77+
SKIP_KEYWORDS: "Merge,Revert,Release" # Comma-separated keywords to skip validation
78+
3679
run: |
37-
# Read the space-separated list of commit SHAs into a Bash array.
38-
# IFS (Internal Field Separator) is set to space to split the string correctly.
80+
81+
# Read commit SHAs into array
82+
83+
3984
IFS=' ' read -r -a commit_shas <<< "${{ steps.get_pr_commits.outputs.PR_COMMITS_LIST }}"
40-
# Initialize a flag to track if any commit fails validation.
85+
86+
87+
4188
has_validation_failed=false
42-
# Loop through each commit SHA.
89+
90+
91+
92+
# Convert skip keywords to array
93+
94+
IFS=',' read -r -a skip_keywords <<< "$SKIP_KEYWORDS"
95+
96+
97+
4398
for commit_sha in "${commit_shas[@]}"; do
99+
44100
echo "--- Checking commit: ${commit_sha} ---"
45-
# Get the full commit message (subject + body).
46-
# --format=%B gets the raw body (subject and body).
47-
# -n 1 limits to the latest commit for the given SHA.
48-
commit_message=$(git log --format=%B -n 1 "${commit_sha}")
101+
102+
103+
104+
# Get commit timestamps for date filtering
105+
106+
COMMIT_DATE_UNIX=$(git log -n 1 --format=%at "${commit_sha}")
107+
108+
TARGET_DATE_UNIX=$(date -d "${TARGET_DATE}" +"%s")
109+
110+
COMMIT_DATE_HUMAN=$(git log -n 1 --format=%ad --date=iso-strict "${commit_sha}")
111+
112+
113+
114+
# Skip older commits
115+
116+
if (( COMMIT_DATE_UNIX < TARGET_DATE_UNIX )); then
117+
118+
echo "Skipping commit ${commit_sha} (Date: ${COMMIT_DATE_HUMAN}) as it is older than ${TARGET_DATE}."
119+
120+
continue
121+
122+
fi
123+
124+
125+
126+
echo "Processing commit ${commit_sha} (Date: ${COMMIT_DATE_HUMAN}) as it is on or after ${TARGET_DATE}."
127+
128+
COMMIT_MESSAGE=$(git log --format=%B -n 1 "${commit_sha}")
129+
130+
131+
49132
echo "Message content:"
50-
echo "${commit_message}"
51-
echo "" # Add a newline for readability
52-
# --- Validation Logic ---
53-
# 1. Check for Conventional Commit format (type(scope)!: subject)
54-
# This regex allows for an optional scope and an optional breaking change marker (!).
55-
# Common types: feat, fix, docs, chore, style, refactor, perf, test, build, ci, revert
56-
if [[ ! "${commit_message}" =~ ^(feat|fix|docs|chore|style|refactor|perf|test|build|ci|revert)(\([a-zA-Z0-9_-]+\))?(!?): ]]; then
57-
echo "::error file=COMMIT_MESSAGE::Commit ${commit_sha} does not start with a conventional commit type (e.g., 'feat:', 'fix:'). Message: '${commit_message}'"
133+
134+
echo "${COMMIT_MESSAGE}"
135+
136+
echo ""
137+
138+
139+
140+
# Check for skip keywords
141+
142+
skip_this_commit=false
143+
144+
for keyword in "${skip_keywords[@]}"; do
145+
146+
# Trim whitespace from keyword
147+
148+
trimmed_keyword=$(echo "$keyword" | xargs)
149+
150+
151+
152+
if [[ -n "$trimmed_keyword" ]] &&
153+
154+
[[ "${COMMIT_MESSAGE}" == *"$trimmed_keyword"* ]]; then
155+
156+
echo "Skipping validation for commit ${commit_sha} due to skip keyword: ${trimmed_keyword}"
157+
158+
skip_this_commit=true
159+
160+
break
161+
162+
fi
163+
164+
done
165+
166+
167+
168+
if [ "$skip_this_commit" = true ]; then
169+
170+
continue
171+
172+
fi
173+
174+
175+
176+
# --- Validation Logic Start ---
177+
178+
179+
180+
# 1. Check Conventional Commit format
181+
182+
if [[ ! "${COMMIT_MESSAGE}" =~ ^(feat|fix|docs|chore|style|refactor|perf|test|build|ci|revert)(\([a-zA-Z0-9_-]+\))?(!?): ]]; then
183+
184+
echo "::error file=COMMIT_MESSAGE::Commit ${commit_sha} does not start with a conventional commit type. Message: '${COMMIT_MESSAGE}'"
185+
58186
has_validation_failed=true
59-
continue # Move to the next commit
187+
188+
continue
189+
190+
fi
191+
192+
193+
194+
# Extract commit subject (first line)
195+
196+
commit_subject=$(echo "${COMMIT_MESSAGE}" | head -n 1)
197+
198+
199+
200+
# 2. NEW: Check minimum subject length (15 characters)
201+
202+
if [[ ${#commit_subject} -lt 15 ]]; then
203+
204+
echo "::error file=COMMIT_MESSAGE::Commit ${commit_sha} subject is too short (min 15 characters). Length: ${#commit_subject}. Subject: '${commit_subject}'"
205+
206+
has_validation_failed=true
207+
208+
continue
209+
60210
fi
61-
# Extract the first line (subject) for further checks.
62-
commit_subject=$(echo "${commit_message}" | head -n 1)
63-
# 2. Check subject line length (e.g., max 72 characters)
211+
212+
213+
214+
# 3. Check maximum subject length (72 characters)
215+
64216
if [[ ${#commit_subject} -gt 72 ]]; then
217+
65218
echo "::warning file=COMMIT_MESSAGE::Commit ${commit_sha} subject line exceeds 72 characters. Length: ${#commit_subject}. Subject: '${commit_subject}'"
66-
# This is a warning, not a failure, adjust as needed.
219+
220+
67221
fi
68-
# 3. Check for empty line between subject and body (if body exists)
69-
# Check if there's more than just the subject line.
70-
if [[ $(echo "${commit_message}" | wc -l) -gt 1 ]]; then
71-
# Check if the second line is empty.
72-
# Use awk to get the second line and trim whitespace.
73-
second_line=$(echo "${commit_message}" | awk 'NR==2 {print}' | xargs)
74-
if [[ -n "${second_line}" ]]; then # If the second line is NOT empty
75-
echo "::error file=COMMIT_MESSAGE::Commit ${commit_sha} is missing an empty line between the subject and body. Message: '${commit_message}'"
222+
223+
224+
225+
# 4. Check empty line between subject and body
226+
227+
if [[ $(echo "${COMMIT_MESSAGE}" | wc -l) -gt 1 ]]; then
228+
229+
second_line=$(echo "${COMMIT_MESSAGE}" | awk 'NR==2 {print}' | xargs)
230+
231+
if [[ -n "${second_line}" ]]; then
232+
233+
echo "::error file=COMMIT_MESSAGE::Commit ${commit_sha} is missing an empty line between subject and body. Message: '${COMMIT_MESSAGE}'"
234+
235+
236+
237+
76238
has_validation_failed=true
239+
77240
continue
241+
78242
fi
243+
79244
fi
80-
# Add more custom validation rules here as needed:
81-
# - Subject capitalization (e.g., must be lowercase)
82-
# - Subject must not end with a period
83-
# - Body line length limits
84-
# - Required body content for certain types (e.g., 'fix:' requires a 'Fixes #ISSUE' line)
85-
done # End of commit loop
86-
# If any commit failed validation, exit with a non-zero status to fail the job.
245+
246+
247+
248+
done
249+
250+
251+
252+
253+
254+
255+
256+
257+
258+
# Fail job if any validation errors occurred
259+
260+
87261
if [ "$has_validation_failed" = true ]; then
262+
88263
echo "::error::One or more commit messages failed validation. Please review the errors above."
264+
89265
exit 1
266+
90267
fi
91-
echo "All commit messages in the PR passed validation."
268+
269+
270+
271+
echo "All relevant commit messages in the PR passed validation."

apps/c/RuxOS_Test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 15c4fe600689b79bccfd42bb88833f37383e3a74

0 commit comments

Comments
 (0)