fix(proxy): route blocked models through healthy fallbacks #14617
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: UI Lint | |
| permissions: | |
| contents: read | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| - litellm_internal_staging | |
| - litellm_oss_staging | |
| - "litellm_**" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| frontend-lint: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 8 | |
| defaults: | |
| run: | |
| working-directory: ui/litellm-dashboard | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Collect changed files | |
| id: changed | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| # base.sha is the base branch tip from when the PR was opened, while | |
| # actions/checkout leaves HEAD on a merge of the PR into the *current* | |
| # base tip. "$BASE_SHA"...HEAD therefore spans every base-branch commit | |
| # landed since, so a PR that touches no UI file still gets linted | |
| # against hundreds of other people's files. Diff the PR head against its | |
| # own merge base instead, which is exactly what this PR changed. | |
| merge_base=$(gh api "repos/${{ github.repository }}/compare/${BASE_SHA}...${HEAD_SHA}?per_page=1" --jq '.merge_base_commit.sha') | |
| test -n "$merge_base" | |
| git fetch --no-tags --depth=1 origin "$merge_base" "$HEAD_SHA" | |
| : > "$RUNNER_TEMP/prettier_files.txt" | |
| : > "$RUNNER_TEMP/eslint_files.txt" | |
| while IFS= read -r f; do | |
| [ -f "$f" ] || continue | |
| case "$f" in | |
| *.js | *.jsx | *.ts | *.tsx | *.mjs | *.cjs) | |
| printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" | |
| printf '%s\n' "$f" >> "$RUNNER_TEMP/eslint_files.txt" ;; | |
| *.json | *.css | *.scss | *.md | *.mdx | *.yml | *.yaml | *.html) | |
| printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" ;; | |
| esac | |
| done < <(git diff --name-only --diff-filter=ACMR --relative "$merge_base" "$HEAD_SHA" -- .) | |
| if [ -s "$RUNNER_TEMP/prettier_files.txt" ] || [ -s "$RUNNER_TEMP/eslint_files.txt" ]; then | |
| echo "has_files=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_files=false" >> "$GITHUB_OUTPUT" | |
| echo "No lintable UI files changed in this PR; nothing to check." | |
| fi | |
| - name: Setup Node.js | |
| if: steps.changed.outputs.has_files == 'true' | |
| uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 | |
| with: | |
| node-version-file: ui/litellm-dashboard/.nvmrc | |
| cache: "npm" | |
| cache-dependency-path: ui/litellm-dashboard/package-lock.json | |
| - name: Install dependencies | |
| if: steps.changed.outputs.has_files == 'true' | |
| run: npm ci | |
| - name: Lint changed files (prettier + eslint) | |
| if: steps.changed.outputs.has_files == 'true' | |
| run: | | |
| prettier_files=() | |
| eslint_files=() | |
| while IFS= read -r f; do prettier_files+=("$f"); done < "$RUNNER_TEMP/prettier_files.txt" | |
| while IFS= read -r f; do eslint_files+=("$f"); done < "$RUNNER_TEMP/eslint_files.txt" | |
| status=0 | |
| if [ ${#prettier_files[@]} -gt 0 ]; then | |
| echo "::group::Prettier (${#prettier_files[@]} files)" | |
| npx prettier --check "${prettier_files[@]}" || { status=1; echo "::error::Unformatted files. Fix with: npm run format"; } | |
| echo "::endgroup::" | |
| fi | |
| if [ ${#eslint_files[@]} -gt 0 ]; then | |
| echo "::group::ESLint (${#eslint_files[@]} files)" | |
| npx eslint --no-warn-ignored --pass-on-unpruned-suppressions "${eslint_files[@]}" || status=1 | |
| echo "::endgroup::" | |
| fi | |
| exit $status | |
| - name: Check lint budgets | |
| if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }} | |
| run: | | |
| npx eslint . -f json -o "$RUNNER_TEMP/lint-report.json" || true | |
| node scripts/check-lint-budgets.mjs "$RUNNER_TEMP/lint-report.json" eslint-budgets.json | |
| - name: Check for dead code (knip) | |
| if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }} | |
| run: npm run knip:ci |