-
Notifications
You must be signed in to change notification settings - Fork 5
96 lines (81 loc) · 3.69 KB
/
commit-lint.yaml
File metadata and controls
96 lines (81 loc) · 3.69 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
---
name: Lint Commit Messages
on:
pull_request:
merge_group:
jobs:
commit-lint:
runs-on:
group: infra1-runners-arc
labels: runners-small
permissions:
contents: read
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
steps:
- name: Validate commits
shell: bash
run: |
set -euo pipefail
: "${BASE_SHA:?unsupported event: no base SHA in event payload}"
: "${HEAD_SHA:?unsupported event: no head SHA in event payload}"
HEADER_MAX_LENGTH=100
CONVENTIONAL_TYPES='build|chore|ci|docs|feat|fix|perf|refactor|revert|reapply|style|test'
CONVENTIONAL_REGEX="^(${CONVENTIONAL_TYPES})(\(.+\))?!?: .+"
# Bot-generated dep/version bumps (renovate, extimage, ...) - skip length and risk checks
BOT_BUMP_REGEX='^chore(\(deps\))?:[[:space:]]([Uu]pdate|bump)'
# Repos that require a `risk:` trailer
RISK_REPOS_REGEX='^(.*/)?(gdc-nas|gdc-ui|gooddata-ui-sdk|gdc-panther)$'
# Fetch non-merge commits in the range via the compare API (no checkout required).
# Output: one JSON object per line - {sha, message}.
COMMITS=$(gh api --paginate "repos/$REPO/compare/$BASE_SHA...$HEAD_SHA" \
--jq '.commits[] | select((.parents | length) <= 1) | {sha: .sha[0:7], message: .commit.message} | @json')
VIOLATIONS=""
if [[ -n "$COMMITS" ]]; then
while IFS= read -r COMMIT_JSON; do
COMMIT_HASH=$(jq -r '.sha' <<< "$COMMIT_JSON")
COMMIT_MESSAGE=$(jq -r '.message' <<< "$COMMIT_JSON")
COMMIT_SUBJECT="${COMMIT_MESSAGE%%$'\n'*}"
COMMIT_VIOLATIONS=""
# Skip auto-generated revert/reapply commits ("Revert ...", "Reapply ...")
if [[ "$COMMIT_SUBJECT" =~ ^([Rr]evert|[Rr]eapply) ]]; then
continue
fi
IS_BOT_BUMP=false
if [[ "$COMMIT_SUBJECT" =~ $BOT_BUMP_REGEX ]]; then
IS_BOT_BUMP=true
fi
if ! [[ "$COMMIT_SUBJECT" =~ $CONVENTIONAL_REGEX ]]; then
COMMIT_VIOLATIONS+=":x: does not follow Conventional Commits guidelines\n"
fi
if [[ "$IS_BOT_BUMP" == "false" ]] && (( ${#COMMIT_SUBJECT} > HEADER_MAX_LENGTH )); then
COMMIT_VIOLATIONS+=":x: exceeds $HEADER_MAX_LENGTH characters\n"
fi
if [[ "$REPO" =~ $RISK_REPOS_REGEX ]] && [[ "$IS_BOT_BUMP" == "false" ]]; then
TRAILERS=$(git interpret-trailers --parse <<< "$COMMIT_MESSAGE")
if ! grep -iqE '^risk:[[:space:]]*(nonprod|low|high)' <<< "$TRAILERS"; then
COMMIT_VIOLATIONS+=":x: does not contain a valid risk trailer\n"
fi
fi
if [[ -n "$COMMIT_VIOLATIONS" ]]; then
VIOLATIONS+="\`$COMMIT_HASH $COMMIT_SUBJECT\`\n$COMMIT_VIOLATIONS\n"
fi
done <<< "$COMMITS"
fi
{
echo "## Commit Lint Results"
if [[ -n "$VIOLATIONS" ]]; then
echo "### Violations"
echo -e "$VIOLATIONS"
else
echo ":white_check_mark: All commit messages follow Conventional Commits guidelines."
fi
} >> "$GITHUB_STEP_SUMMARY"
if [[ -n "$VIOLATIONS" ]]; then
echo -e "$VIOLATIONS"
exit 1
fi
echo "All commit messages follow Conventional Commits guidelines."