From 416e95c83958c017111a5d1c649d1284be1a8cd0 Mon Sep 17 00:00:00 2001 From: pouriaetab <124482480+pouriaetab@users.noreply.github.com> Date: Sat, 17 Oct 2026 21:58:58 -0500 Subject: [PATCH] fix(ci): run the cost map guard's bot contract on price-sync PRs The provider-info-sync App opens its PRs from litellm-providers/price-sync* branches, but the guard only treated litellm_cost_map_sync_* branches as bot PRs, so the bot contract never ran on them Fixes #46100 --- ci_cd/cost_map_guard.py | 10 +++++----- tests/unit/test_cost_map_guard.py | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ci_cd/cost_map_guard.py b/ci_cd/cost_map_guard.py index 932da84e5d7..2b9d7d9c766 100644 --- a/ci_cd/cost_map_guard.py +++ b/ci_cd/cost_map_guard.py @@ -3,9 +3,9 @@ Every pull request whose diff against its merge base touches one of the two cost map files gets the file checks: the files parse and the backup copy matches the root file. A pull request that leaves both untouched skips them, since merging it keeps the base branch's copies and its head tree only carries whatever state the -branch was cut from. Pull requests from the cost map sync bot (branches named litellm_cost_map_sync_*) always -get the file checks and additionally may only touch those two files or the legacy schema -path and may only add or update models. +branch was cut from. Pull requests from the cost map sync bots (branches named litellm-providers/price-sync* or +litellm_cost_map_sync_*) always get the file checks and additionally may only touch those two files or the +legacy schema path and may only add or update models. """ from __future__ import annotations @@ -23,7 +23,7 @@ COST_MAP_PATH: Final = "model_prices_and_context_window.json" BACKUP_PATH: Final = "litellm/model_prices_and_context_window_backup.json" LEGACY_SCHEMA_PATH: Final = "model_prices_and_context_window.schema.json" GUARDED_PATHS: Final = (COST_MAP_PATH, BACKUP_PATH) -BOT_BRANCH_PREFIX: Final = "litellm_cost_map_sync_" +BOT_BRANCH_PREFIXES: Final = ("litellm-providers/price-sync", "litellm_cost_map_sync_") SPECIAL_ROOT_KEYS: Final = frozenset({"sample_spec", "fallback_generalizations"}) EVALUATION_OUTPUT_PRICE_SOURCES: Final[Mapping[str, str]] = MappingProxyType({}) @@ -173,7 +173,7 @@ def main(argv: Sequence[str]) -> int: parser.add_argument("--head", required=True, help="head commit of the pull request") parser.add_argument("--head-ref", required=True, help="head branch name of the pull request") args: Final = parser.parse_args(argv) - bot: Final = args.head_ref.startswith(BOT_BRANCH_PREFIX) + bot: Final = args.head_ref.startswith(BOT_BRANCH_PREFIXES) changed: Final = changed_files(args.base, args.head) if changed is None: print(f"cost map guard failed: git diff {args.base} {args.head} failed, so the changed files are unknown") diff --git a/tests/unit/test_cost_map_guard.py b/tests/unit/test_cost_map_guard.py index a705597952b..8d00cecf61a 100644 --- a/tests/unit/test_cost_map_guard.py +++ b/tests/unit/test_cost_map_guard.py @@ -251,7 +251,10 @@ def _run_guard(repo: Path, base: str, head: str, head_ref: str) -> subprocess.Co ("head_ref", "expected_code", "expected_line"), [ (BOT_REF, 1, "- bot PRs may not remove models: openrouter/b"), + ("litellm-providers/price-sync-openrouter", 1, "- bot PRs may not remove models: openrouter/b"), + ("litellm-providers/price-sync", 1, "- bot PRs may not remove models: openrouter/b"), ("litellm_fix_pricing", 0, "cost map guard passed (human PR, file checks only)"), + ("fix-openrouter-price-sync", 0, "cost map guard passed (human PR, file checks only)"), ], ) def test_main_reads_both_revisions_from_git(