mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-02 02:11:58 +00:00
Adds opt-in local git hooks plus a CI PR-title check: - .githooks/commit-msg validates commit subjects against Conventional Commits 1.0.0 (feat|fix|docs|style|refactor|perf|test|build|ci| chore|revert)(scope)!: subject. Merge/revert/fixup!/squash!/amend! messages pass through; --no-verify still works. - .githooks/pre-push validates branch names against Conventional Branches (feature|bugfix|hotfix|release|chore)/desc. Bypasses main, litellm_internal_staging, dependabot/*, gh-readonly-queue/*. Tag pushes and deletions are skipped. - scripts/install_git_hooks.sh sets core.hooksPath=.githooks and is wired up as 'make install-hooks'. Opt-in — not chained into install-dev. - .github/workflows/conventional-commits.yml validates PR titles via amannn/action-semantic-pull-request pinned to v6.1.1's SHA. This is the actual gate since squash-merge uses the PR title as the commit subject. - tests/test_litellm/test_git_hooks.py exercises both hooks via subprocess for accept / reject / bypass / git-generated-message cases. - CONTRIBUTING.md documents the conventions, the install step, the bypass list, and the --no-verify escape hatch. Resolves LIT-3306 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
70 lines
1.8 KiB
Bash
Executable file
70 lines
1.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# commit-msg — enforce Conventional Commits 1.0.0
|
|
# https://www.conventionalcommits.org/en/v1.0.0/
|
|
#
|
|
# Subject format: <type>(<scope>)!: <description>
|
|
# - <type> must be one of the angular types (feat, fix, ...)
|
|
# - (<scope>) is optional
|
|
# - ! is optional and marks a breaking change
|
|
# - <description> is mandatory and must be non-empty
|
|
#
|
|
# Bypass: commit with --no-verify.
|
|
# Merge, revert, fixup!, squash!, and amend! messages are passed through.
|
|
|
|
set -eu
|
|
|
|
COMMIT_MSG_FILE="${1:-}"
|
|
if [ -z "$COMMIT_MSG_FILE" ] || [ ! -f "$COMMIT_MSG_FILE" ]; then
|
|
echo "commit-msg: missing commit message file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# First non-comment, non-empty line is the subject.
|
|
subject=""
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
case "$line" in
|
|
''|'#'*) continue ;;
|
|
esac
|
|
subject="$line"
|
|
break
|
|
done < "$COMMIT_MSG_FILE"
|
|
|
|
if [ -z "$subject" ]; then
|
|
echo "commit-msg: empty commit message" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Pass-through commits generated by git itself.
|
|
case "$subject" in
|
|
"Merge "*|"Revert \""*|"fixup! "*|"squash! "*|"amend! "*)
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
ALLOWED_TYPES="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert"
|
|
PATTERN="^(${ALLOWED_TYPES})(\([^)]+\))?!?: .+"
|
|
|
|
if printf '%s' "$subject" | grep -Eq "$PATTERN"; then
|
|
exit 0
|
|
fi
|
|
|
|
cat >&2 <<EOF
|
|
✗ Commit message does not follow Conventional Commits.
|
|
|
|
Got: $subject
|
|
|
|
Expected: <type>(<scope>)!: <description>
|
|
|
|
Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
|
Examples:
|
|
feat(router): add weighted round-robin strategy
|
|
fix(bedrock): decouple STS region from aws_region_name
|
|
chore(deps): bump black to 26.3.1
|
|
refactor!: drop Python 3.8 support
|
|
|
|
See https://www.conventionalcommits.org/en/v1.0.0/
|
|
|
|
To bypass (use sparingly): git commit --no-verify
|
|
EOF
|
|
exit 1
|