From 004e9f6189216a4bce9e08ae8f341ff36579a986 Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Tue, 14 Jul 2026 09:50:18 -0700 Subject: [PATCH] ci: fold the snapshot check into the existing types-sync job The standalone workflow duplicated the whole backend setup (uv sync, prisma generate) to run a five second check, and it triggered on nearly the same paths as Check UI API Types Sync. Move the check into that job instead and delete the workflow. It runs before gen:api on purpose. The snapshot is an input to schema.d.ts, so when it is stale the regenerated types match the committed ones and the existing step passes while both disagree with the code; checking the snapshot first reports the root cause rather than a downstream symptom. The workflow and job names are unchanged so any branch protection matching on them keeps applying. --- .../workflows/check-lazy-openapi-snapshot.yml | 73 ------------------- .github/workflows/check-ui-api-types.yml | 26 +++++++ litellm/proxy/_lazy_openapi_snapshot.py | 6 +- 3 files changed, 30 insertions(+), 75 deletions(-) delete mode 100644 .github/workflows/check-lazy-openapi-snapshot.yml diff --git a/.github/workflows/check-lazy-openapi-snapshot.yml b/.github/workflows/check-lazy-openapi-snapshot.yml deleted file mode 100644 index 9d4945fc04d..00000000000 --- a/.github/workflows/check-lazy-openapi-snapshot.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Check Lazy OpenAPI Snapshot Sync - -on: - pull_request: - paths: - - "litellm/proxy/**" - - "litellm/types/**" - - "enterprise/**" - - "uv.lock" - - ".github/workflows/check-lazy-openapi-snapshot.yml" - -permissions: - contents: read - -jobs: - check-sync: - name: Verify _lazy_openapi_snapshot.json matches the proxy routes - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout repository - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - with: - persist-credentials: false - - - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: "3.12" - - - name: Set up uv - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 - with: - version: "0.10.9" - - - name: Cache uv dependencies - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: | - ~/.cache/uv - .venv - key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} - restore-keys: | - ${{ runner.os }}-uv- - - - name: Install backend dependencies - run: .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router - - - name: Generate Prisma client - env: - PRISMA_BINARY_CACHE_DIR: ${{ runner.temp }}/prisma-cache - run: uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma - - - name: Fail if the snapshot is stale - run: | - set +e - uv run --no-sync python -m litellm.proxy._lazy_openapi_snapshot --check - status=$? - set -e - - case "$status" in - 0) - exit 0 - ;; - 2) - echo "::error file=litellm/proxy/_lazy_openapi_snapshot.json::Could not verify the lazy OpenAPI snapshot: a lazy feature failed to import, so the regenerated snapshot would be incomplete. This is a missing dependency in this job, not snapshot drift. See the log for the feature and error." - exit 1 - ;; - *) - echo "::error file=litellm/proxy/_lazy_openapi_snapshot.json::Lazy OpenAPI snapshot is out of sync with the proxy routes. Run 'python -m litellm.proxy._lazy_openapi_snapshot', commit the result, and re-run 'npm run gen:api' if schema.d.ts changes." - exit 1 - ;; - esac diff --git a/.github/workflows/check-ui-api-types.yml b/.github/workflows/check-ui-api-types.yml index 439126aa1ee..d5c696c4e87 100644 --- a/.github/workflows/check-ui-api-types.yml +++ b/.github/workflows/check-ui-api-types.yml @@ -5,6 +5,8 @@ on: paths: - "litellm/proxy/**" - "litellm/types/**" + - "enterprise/**" + - "uv.lock" - "ui/litellm-dashboard/src/lib/http/schema.d.ts" - "ui/litellm-dashboard/scripts/gen-api-types.mjs" - "ui/litellm-dashboard/package.json" @@ -53,6 +55,30 @@ jobs: PRISMA_BINARY_CACHE_DIR: ${{ runner.temp }}/prisma-cache run: uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma + # Runs before gen:api because the snapshot is an *input* to schema.d.ts: for + # lazy features the types are copied out of it verbatim. A stale snapshot + # therefore regenerates matching-but-wrong types, so the check below would pass + # while both files disagreed with the code. Report the root cause first. + - name: Fail if the lazy OpenAPI snapshot is stale + run: | + set +e + uv run --no-sync python -m litellm.proxy._lazy_openapi_snapshot --check + status=$? + set -e + + case "$status" in + 0) + ;; + 2) + echo "::error file=litellm/proxy/_lazy_openapi_snapshot.json::Could not verify the lazy OpenAPI snapshot: a lazy feature failed to import, so the regenerated snapshot would be incomplete. This is a missing dependency in this job, not snapshot drift. See the log for the feature and error." + exit 1 + ;; + *) + echo "::error file=litellm/proxy/_lazy_openapi_snapshot.json::Lazy OpenAPI snapshot is out of sync with the proxy routes. Run 'python -m litellm.proxy._lazy_openapi_snapshot', commit the result, and re-run 'npm run gen:api' if schema.d.ts changes." + exit 1 + ;; + esac + - name: Set up Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: diff --git a/litellm/proxy/_lazy_openapi_snapshot.py b/litellm/proxy/_lazy_openapi_snapshot.py index de782d1d288..56d4e3e8b14 100644 --- a/litellm/proxy/_lazy_openapi_snapshot.py +++ b/litellm/proxy/_lazy_openapi_snapshot.py @@ -8,8 +8,10 @@ features without importing them. The snapshot is also an *input* to the dashboard's generated types: `npm run gen:api` dumps the proxy spec without loading the lazy features, so their paths and schemas come from this file verbatim. A stale fragment therefore ships stale `schema.d.ts` -types, and the UI types-sync check cannot catch it (it regenerates from this same -file). `--check` closes that loop; the Lazy OpenAPI Snapshot Sync workflow runs it. +types, and the UI types-sync check cannot catch it on its own (it regenerates from +this same file, so both end up agreeing with each other and disagreeing with the +code). `--check` closes that loop, and the Check UI API Types Sync workflow runs it +before regenerating the types. """ import json