mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
* chore(hooks): enforce Conventional Commits and Conventional Branches 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> * fix(hooks): address Greptile review on PR #28703 Resolves two findings from the automated code review: 1. CONTRIBUTING.md: shrink the new Conventional Commits / Branches section to a 2-line pointer at docs.litellm.ai. Per the team convention, the full documentation lives in the litellm-docs repo — see BerriAI/litellm-docs#208 for the companion change that adds the section to docs/extras/contributing_code.md. 2. .githooks/commit-msg: tighten the subject regex to also reject an uppercase first letter in the description. CI's subjectPattern is ^(?![A-Z]).+$ so the previous local hook would accept 'feat: Add thing' which would then fail the PR-title check. The local hook is now the strictly tighter of the two gates. Test cases extended to cover both the new rejection and the digit/symbol-start cases that remain allowed. Resolves LIT-3306 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: trigger ci after branch rename * fix(ci): rerun pr title check when bypass label changes amannn/action-semantic-pull-request only honors ignoreLabels if the workflow retriggers on labeled/unlabeled events; without them a red check stays red after a maintainer applies the bypass label. Also point the CONTRIBUTING.md workflow comments at the conventions section, which now sits above the Development Workflow section. --------- Co-authored-by: Yassin Kortam <yassinkortam@Yassins-MBP.localdomain> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
2.2 KiB
Bash
Executable file
92 lines
2.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# pre-push — enforce Conventional Branches
|
|
# https://conventional-branch.github.io/
|
|
#
|
|
# Branch format: <type>/<description>
|
|
# <type> must be one of: feature, bugfix, hotfix, release, chore
|
|
#
|
|
# Protected branches (always allowed):
|
|
# - main
|
|
# - litellm_internal_staging
|
|
# - dependabot/*
|
|
# - gh-readonly-queue/*
|
|
#
|
|
# Tag pushes and branch deletions are skipped.
|
|
# Bypass: git push --no-verify.
|
|
|
|
set -eu
|
|
|
|
ZERO_OID="0000000000000000000000000000000000000000"
|
|
ZERO_OID_SHA256="0000000000000000000000000000000000000000000000000000000000000000"
|
|
ALLOWED_TYPES="feature|bugfix|hotfix|release|chore"
|
|
BRANCH_PATTERN="^(${ALLOWED_TYPES})/.+"
|
|
|
|
PROTECTED_NAMES="main litellm_internal_staging"
|
|
PROTECTED_PREFIXES="dependabot/ gh-readonly-queue/"
|
|
|
|
is_protected() {
|
|
branch="$1"
|
|
for name in $PROTECTED_NAMES; do
|
|
if [ "$branch" = "$name" ]; then
|
|
return 0
|
|
fi
|
|
done
|
|
for prefix in $PROTECTED_PREFIXES; do
|
|
case "$branch" in "$prefix"*) return 0 ;; esac
|
|
done
|
|
return 1
|
|
}
|
|
|
|
invalid=""
|
|
|
|
while read -r local_ref local_oid remote_ref remote_oid; do
|
|
# Branch deletion (no local commit being pushed).
|
|
if [ "$local_oid" = "$ZERO_OID" ] || [ "$local_oid" = "$ZERO_OID_SHA256" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Only validate branch pushes; ignore tags and other ref namespaces.
|
|
case "$remote_ref" in
|
|
refs/heads/*) ;;
|
|
*) continue ;;
|
|
esac
|
|
|
|
branch="${remote_ref#refs/heads/}"
|
|
|
|
if is_protected "$branch"; then
|
|
continue
|
|
fi
|
|
|
|
if ! printf '%s' "$branch" | grep -Eq "$BRANCH_PATTERN"; then
|
|
invalid="$invalid $branch"
|
|
fi
|
|
done
|
|
|
|
if [ -n "$invalid" ]; then
|
|
cat >&2 <<EOF
|
|
✗ Branch name does not follow Conventional Branches.
|
|
|
|
Invalid:$invalid
|
|
|
|
Expected: <type>/<description>
|
|
|
|
Allowed types: feature, bugfix, hotfix, release, chore
|
|
Examples:
|
|
feature/weighted-round-robin
|
|
bugfix/streaming-empty-chunks
|
|
chore/bump-deps
|
|
hotfix/auth-bypass
|
|
|
|
Protected (always allowed): main, litellm_internal_staging,
|
|
dependabot/*, gh-readonly-queue/*.
|
|
|
|
See https://conventional-branch.github.io/
|
|
|
|
Rename with: git branch -m <new-name>
|
|
To bypass (use sparingly): git push --no-verify
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
exit 0
|