diff --git a/.githooks/pre-push b/.githooks/pre-push index dc1a73a7ba2..72bb50cf48c 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -1,10 +1,11 @@ #!/usr/bin/env bash # -# pre-push — enforce Conventional Branches -# https://conventional-branch.github.io/ +# pre-push hook enforcing the repo's branch naming conventions # -# Branch format: / -# must be one of: feature, bugfix, hotfix, release, chore +# Accepted formats: +# litellm_ (internal convention, see AGENTS.md) +# / (Conventional Branches, https://conventional-branch.github.io/) +# must be one of: feature, bugfix, hotfix, release, chore # # Protected branches (always allowed): # - main @@ -19,7 +20,8 @@ set -eu ZERO_OID="0000000000000000000000000000000000000000" ZERO_OID_SHA256="0000000000000000000000000000000000000000000000000000000000000000" ALLOWED_TYPES="feature|bugfix|hotfix|release|chore" -BRANCH_PATTERN="^(${ALLOWED_TYPES})/.+" +INTERNAL_PREFIX="litellm_" +BRANCH_PATTERN="^((${ALLOWED_TYPES})/|${INTERNAL_PREFIX}).+" PROTECTED_NAMES="main" PROTECTED_PREFIXES="dependabot/ gh-readonly-queue/" @@ -64,22 +66,23 @@ done if [ -n "$invalid" ]; then cat >&2 </ + Expected: litellm_ + or: / (Conventional Branches) Allowed types: feature, bugfix, hotfix, release, chore Examples: + litellm_weighted_round_robin feature/weighted-round-robin bugfix/streaming-empty-chunks chore/bump-deps - hotfix/auth-bypass Protected (always allowed): main, dependabot/*, gh-readonly-queue/*. -See https://conventional-branch.github.io/ +See AGENTS.md and https://conventional-branch.github.io/ Rename with: git branch -m To bypass (use sparingly): git push --no-verify diff --git a/AGENTS.md b/AGENTS.md index 7f8e9cedc26..0f84798ab57 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -74,7 +74,7 @@ Always pull before starting any work. The checkout or worktree may be sitting on If you're an internal contributor, when creating a new PR, the typical flow is to branch off the repository's current default branch and create a branch prefixed with litellm_. Do not create a branch prefixed with claude/ and generally do not have / in your branch names -Do not add `Co-Authored-By: Claude` or any Claude attribution to commit messages. Never use a `claude/` prefix or put a `/` in a branch name. Do not add "Generated with Claude Code" (or any similar attribution) to PR descriptions or comments. Do not create a new PR/branch off the existing PR to fix/add something that is related and could've just been committed directly to the existing PR's branch +Do not add `Co-Authored-By: Claude` or any Claude attribution to commit messages. Never use a `claude/` branch prefix. Do not add "Generated with Claude Code" (or any similar attribution) to PR descriptions or comments. Do not create a new PR/branch off the existing PR to fix/add something that is related and could've just been committed directly to the existing PR's branch When working on a PR, keep the PR description in sync with new commits being made diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0af12bd5318..ea24a914a65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,7 +55,7 @@ That's it! Your local development environment is ready. ## Commit and Branch Conventions -Commits follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) and branches follow [Conventional Branches](https://conventional-branch.github.io/). Run `make install-hooks` once per clone to enable the local git hooks that enforce these — see the [contributor docs](https://docs.litellm.ai/docs/extras/contributing_code#commit-and-branch-conventions) for the full type list, examples, the protected-branch bypass list, and how to opt out. +Commits follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Branches are named either `litellm_` (the form most PRs in this repo use, and the one AGENTS.md asks internal contributors to use) or in the [Conventional Branches](https://conventional-branch.github.io/) form `/`, where `` is one of `feature`, `bugfix`, `hotfix`, `release`, or `chore`. Run `make install-hooks` once per clone to enable the local git hooks that enforce these. See the [contributor docs](https://docs.litellm.ai/docs/extras/contributing_code#commit-and-branch-conventions) for the full type list, examples, the protected-branch bypass list, and how to opt out. ### 2. Development Workflow @@ -78,7 +78,7 @@ uv run pytest tests/unit/.py -v git add . git commit -m "feat(scope): your descriptive commit message" -# Push and create a PR (branch must follow Conventional Branches — see above) +# Push and create a PR (branch name must follow the conventions above) git push origin feature/your-feature ``` diff --git a/scripts/install_git_hooks.sh b/scripts/install_git_hooks.sh index 8f4e79e4ddd..48a94ffe818 100755 --- a/scripts/install_git_hooks.sh +++ b/scripts/install_git_hooks.sh @@ -31,7 +31,8 @@ cat < or Conventional Branches /). Bypass with --no-verify when you need to (e.g. for emergency hotfixes). The CI-equivalent lint is deliberately not installed as an auto-firing hook diff --git a/tests/unit/test_git_hooks.py b/tests/unit/test_git_hooks.py index 2ecf0da6ed6..4e8f6a2b254 100644 --- a/tests/unit/test_git_hooks.py +++ b/tests/unit/test_git_hooks.py @@ -1,7 +1,8 @@ """Tests for the repo's git hook scripts in ``.githooks/``. -The hooks enforce Conventional Commits 1.0.0 on the commit-msg path and -Conventional Branches on the pre-push path. Each hook is exercised here as a +The hooks enforce Conventional Commits 1.0.0 on the commit-msg path and, on the +pre-push path, either the internal ``litellm_`` branch prefix or Conventional +Branches. Each hook is exercised here as a subprocess against representative valid / invalid inputs so that any future regex change or accidental edit gets caught by ``make test-unit``. @@ -222,15 +223,35 @@ def test_pre_push_accepts_conventional_branches(branch): ) +@pytest.mark.parametrize( + "branch", + [ + "litellm_fix_bedrock_sts_region", + "litellm_conventional_commits", + "litellm_backport_45721_rc_1_106_0", + "litellm_fix/optimize-streaming", + ], +) +def test_pre_push_accepts_litellm_prefixed_branches(branch): + result = _run_pre_push(_ref_line(branch)) + assert result.returncode == 0, ( + f"hook rejected a litellm_ branch:\n branch: {branch!r}\n" + f" stderr: {result.stderr}" + ) + + @pytest.mark.parametrize( "branch", [ "random-branch-name", - "litellm_fix/optimize-streaming", # legacy pattern is now rejected "ui/navbar-notifications", # not in the allow list "feature/", # empty description "Feature/foo", # type is case-sensitive "feat/foo", # angular commit type, not branch type + "litellm_", # empty description + "litellm-fix-foo", # hyphen is not the litellm_ prefix + "Litellm_fix_foo", # prefix is case-sensitive + "mylitellm_fix_foo", # prefix must start the name ], ) def test_pre_push_rejects_non_conventional_branches(branch):