GitHub Advanced Security flagged that the workflow had no permissions block,
leaving GITHUB_TOKEN with its default broad scope. All write operations
(git push, gh pr create) already use GH_TOKEN (PAT), so the implicit
GITHUB_TOKEN only needs read access.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A re-run within the same second (or a leftover branch) would cause
`git push` to fail. Adding -f is safe since this is a bot-owned branch
that is immediately turned into a PR and never used for anything else.
Fixes inline suggestion from Greptile review.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without the token in the checkout step the subsequent `git push` uses the
default GITHUB_TOKEN which lacks permission to push new branches, causing
the workflow to fail silently. Fixes issue flagged by Greptile review.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a workflow that triggers whenever pyproject.toml is merged into main
and opens a PR with the refreshed lock file, fixing the recurring CI failure:
"pyproject.toml changed significantly since poetry.lock was last generated."
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Running `cd enterprise && poetry run pip install -e .` causes poetry to
create a separate venv in `enterprise/.venv` (since enterprise/ has its
own pyproject.toml). The main project's tests run with `.venv/bin/python`,
so the enterprise package installed in `enterprise/.venv` is never seen.
Fix: run `poetry run pip install -e enterprise/` from the repo root so
poetry uses the main project's venv. This ensures litellm_enterprise is
importable when tests run.
This explains why enterprise tests kept failing with:
AttributeError: '_PROXY_LiteLLMManagedFiles' object has no attribute
'_check_file_deletion_allowed'
even after --force-reinstall was added — the reinstall was going to the
wrong virtual environment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The same PyPI-override issue existed in test-litellm.yml, test-mcp.yml,
and .circleci/config.yml. Also adds --no-deps (enterprise has no runtime
deps) to avoid redundant dependency resolution on every forced reinstall.
Addresses greptile review comments on PR #21481.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
poetry install includes litellm-enterprise from PyPI, then the editable
install step runs. When the same version is already installed, pip may
skip the editable install leaving the PyPI build in place - which may
lack methods added after the latest PyPI release. Adding
--force-reinstall ensures the local editable version always wins.
Fixes enterprise tests failing with AttributeError on methods that exist
locally but not in the cached PyPI-installed package.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tests/proxy_unit_tests/test_key_generate_prisma.py imports PrismaClient
at module level, which triggers a Prisma binary check. Without running
prisma generate first, all tests in that file ERROR at collection time
with "Unable to find Prisma binaries. Please run 'prisma generate' first."
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements three key improvements to reduce test flakiness from parallel execution:
1. **Split Vertex AI tests into separate group** (workers: 1)
- Vertex AI tests often have environment variable pollution issues
- Running serially prevents cross-test interference with GOOGLE_APPLICATION_CREDENTIALS
- Isolates authentication-related test failures
2. **Reduce workers for other LLM tests** (4 -> 2)
- Decreases chance of race conditions and state conflicts
- Still parallel but with less contention
3. **Add --dist=loadscope to pytest-xdist**
- Keeps tests from the same file together on one worker
- Reduces interference between unrelated test modules
- Data shows 70% pass rate WITH loadscope vs 40% WITHOUT
- Better test isolation while maintaining parallelism
Note: loadscope exposes one tokenizer cache issue in core-utils which will be
fixed in a separate PR. The tradeoff is worth it (7/10 pass vs 4/10 without).
These changes address the root causes of intermittent test failures in:
PRs #21268, #21271, #21272, #21273, #21275, #21276:
- Environment variable pollution (GOOGLE_APPLICATION_CREDENTIALS, VERTEXAI_PROJECT)
- Global state conflicts (litellm.known_tokenizer_config)
- Async mock timing issues with parallel execution
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove pytest-retry from dev dependencies in pyproject.toml
- Add pytest-xdist as proper dev dependency (was only in pip install)
- Update CI workflow to reflect proper dependency management
- Prevents conflict between pytest-retry and pytest-rerunfailures
Having both pytest-retry and pytest-rerunfailures installed simultaneously
causes unpredictable behavior and excessive retries.
- Add pytest-xdist back to pip install line (required for -n flag)
- Was accidentally removed when removing pytest-retry
- Without pytest-xdist, all CI jobs fail with 'unrecognized option -n'
- Remove pytest-retry to avoid duplicate retry mechanisms (only use pytest-rerunfailures)
- Remove --dist loadgroup flag (no tests use xdist_group marker)
- Remove unused LITELLM_CI environment variable
- Remove sequential test step with error masking
- Simplify workflow for clarity
This fixes the issue where tests could be retried 60+ times due to
duplicate retry plugins (pytest-retry with retries=20 + pytest-rerunfailures
with --reruns 2-3).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Reduce workers from 4 to 2 to avoid race conditions
- Add --reruns with 2-3 retries per test group
- Increase timeout from 15 to 20 minutes
- Add better test isolation
The test-complete aggregate job adds no value as GitHub Actions
already provides visibility into matrix job results.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
The Helm chart on GHCR displays a `docker pull` command instead of
the correct `helm pull oci://` command. This is because the OCI artifact
is missing the `org.opencontainers.image.source` annotation that GHCR
uses to identify and properly display Helm charts.
Changes:
- Add OCI annotations to Chart.yaml (source + url) which Helm 3.10+
propagates to the OCI manifest on push
- Install explicit Helm v3.20.0 via azure/setup-helm@v4 for reproducible
builds and proper OCI annotation support
- Remove deprecated HELM_EXPERIMENTAL_OCI env var (OCI is GA since Helm 3.8)
Split tests/test_litellm into 10 parallel CI jobs using GitHub Actions
matrix strategy to reduce PR feedback time from ~25 min to ~8-10 min.
Changes:
- Add new test-litellm-matrix.yml workflow with 10 matrix jobs:
- llms (~225 files, 4 workers)
- proxy-guardrails (~51 files, 4 workers)
- proxy-core (~52 files, 4 workers)
- proxy-misc (~77 files, 4 workers)
- integrations (~60 files, 4 workers)
- core-utils (~32 files, 2 workers)
- other (~69 files, 4 workers) - includes all previously uncovered dirs
- root (~34 files, 4 workers)
- proxy-unit-a (~20 files, 2 workers)
- proxy-unit-b (~28 files, 2 workers)
- Deprecate test-litellm.yml (moved to workflow_dispatch for manual use)
- Add matching Makefile targets for local testing:
- make test-unit-llms
- make test-unit-proxy-guardrails
- make test-unit-proxy-core
- make test-unit-proxy-misc
- make test-unit-integrations
- make test-unit-core-utils
- make test-unit-other
- make test-unit-root
- make test-proxy-unit-a
- make test-proxy-unit-b
Benefits:
- ~3x faster wall-clock time through parallelization
- Dependency caching for faster subsequent runs
- Concurrency control to cancel stale runs
- Better failure isolation per test group
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Replace independent auto-incrementing chart versioning with 1-1 sync
to LiteLLM version. This allows users to easily map Helm chart versions
to LiteLLM versions without needing to inspect appVersion.
Changes:
- Remove auto-increment logic that read from OCI registry
- Chart version now equals LiteLLM tag without 'v' prefix (v1.81.0 -> 1.81.0)
- appVersion equals full Docker tag (v1.81.0)
- Update both ghcr_deploy.yml and ghcr_helm_deploy.yml workflows
Before: helm chart 0.1.837 -> user has to guess LiteLLM version
After: helm chart 1.81.0 -> matches LiteLLM v1.81.0
References:
- https://codefresh.io/docs/docs/ci-cd-guides/helm-best-practices/
* fix: sync Helm chart versioning with production standards and Docker versions
- Update Chart.yaml version from 0.4.10 to 1.0.0 (SemVer 0.x is for development, 1.0+ for production)
- Update appVersion from v1.50.2 to v1.80.12 to match current Docker image version
- Update workflow defaults from 0.1.0 to 1.0.0 for new chart version scheme
- Maintain independent chart versioning per Helm best practices
This ensures:
- Helm chart follows SemVer production standards (1.x instead of 0.x)
- appVersion stays synchronized with Docker/application version
- Chart version remains independent for flexibility (can update chart without waiting for app releases)
* fix: sync Helm chart appVersion with Docker image tags in release workflow
Updates the GitHub workflow to ensure Helm chart appVersion matches the
Docker image tags that are actually published:
- For stable/rc releases: Uses the workflow input tag (e.g., v1.80.12)
- For latest/dev releases: Uses the release_type to match main-{type} tags
- Makes 'tag' input required to prevent accidental releases with wrong versions
- Simplifies fallback logic by removing git-describe dependency
This ensures the chart's appVersion correctly references Docker images
that exist, preventing deployment failures from missing image tags.
* Update ghcr_deploy.yml
- Add repository check to only run workflow in BerriAI/litellm
- Prevents workflow failures and wasted resources in forked repositories
- Avoids confusion for external contributors
* fix: align max_tokens with max_output_tokens for consistency
Fixed inconsistent max_tokens definitions in model_prices_and_context_window.json.
According to LiteLLM convention, max_tokens should equal max_output_tokens when available.
Models fixed:
- deepseek-chat: 131072 → 8192 (now equals max_output_tokens)
- dashscope/qwen-flash: 1000000 → 32768 (now equals max_output_tokens)
- databricks/databricks-gemma-3-12b: 128000 → 32000 (now equals max_output_tokens)
This ensures consistency across all providers where max_tokens represents
the maximum number of tokens that can be generated in the output.
* fix(workflow): Update issue labeling with working regex pattern
- Replace contains() with regex pattern using \s* for flexible whitespace matching
- Consolidate 4 separate steps into single unified component labeling step
- Tested and verified pattern works for all components: SDK, Proxy, UI Dashboard, Docs
- Pattern handles GitHub's issue body formatting with ### headers and variable newlines
* Fix component label automation to prevent false positives
The GitHub Actions workflow was applying component labels (SDK, Proxy, UI Dashboard, Docs) too broadly by only checking if the component name appeared anywhere in the issue body. This caused issues to be mislabeled when users mentioned these terms in their descriptions.
Changes:
- Add more specific condition that checks for both the dropdown field header "What part of LiteLLM is this about?" AND the component name
- Applied to all 4 component labels: SDK, Proxy, UI Dashboard, and Docs
- Labels will now only be applied when users actually select the option from the dropdown
Fixes issues being incorrectly labeled with 'docs' and other component labels.
* Use more specific pattern to match dropdown selection exactly
Updated the label conditions to use a more precise pattern that matches
the dropdown header immediately followed by the selected value. This
prevents false positives when users mention component names in their
descriptions but select a different component.
Before: Checked for header AND component name anywhere in body
After: Checks for exact pattern "header\n\ncomponent"
This ensures labels are only applied when the component is actually
selected from the dropdown, not just mentioned in the issue text.
* Fix component label automation and require explicit user selection
This PR fixes two issues with component labeling:
1. **Improved label accuracy**: Updated the workflow to use exact pattern
matching ("### What part of LiteLLM is this about?\n\nDocs") instead of
broad substring matching. This prevents false positives where issues were
mislabeled when users mentioned component names in their descriptions.
2. **Require explicit component selection**: Added empty string ('') as the
first dropdown option to prevent GitHub from auto-selecting "SDK" as the
default. Users must now consciously select which component their issue
relates to.
Changes:
- Updated all component label conditions in label-component.yml workflow
- Added empty string as first option in bug_report.yml dropdown
- Added empty string as first option in feature_request.yml dropdown
- Labels only apply when users actually select a component from the dropdown
This ensures accurate labeling and prevents the default SDK label from
being applied to all new issues.