name: Merge smoke checks on: pull_request: branches: [main, litellm_internal_staging, litellm_oss_staging, "litellm_**"] workflow_dispatch: permissions: contents: read concurrency: group: merge-smoke-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true jobs: dashboard-build: name: Dashboard build runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 with: persist-credentials: false - name: Build the dashboard stage run: docker build --target ui-builder -f Dockerfile . core-checks: name: Core checks (Python ${{ matrix.python-version }}) runs-on: ubuntu-24.04 timeout-minutes: 30 strategy: fail-fast: false matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] env: LITELLM_LOCAL_MODEL_COST_MAP: "True" steps: - name: Checkout 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: ${{ matrix.python-version }} - name: Set up uv uses: ./.github/actions/setup-uv-with-retries with: version: "0.10.9" - name: Install dependencies run: .github/scripts/uv_sync_with_retries.sh --frozen --extra proxy --extra cli --group dev --group proxy-dev --python ${{ matrix.python-version }} - name: Create the loopback-only network namespace run: | sudo ip netns add smoke sudo ip netns exec smoke ip link set lo up cat > "${RUNNER_TEMP}/in-netns" <<'WRAP' #!/usr/bin/env bash set -euo pipefail exec sudo --preserve-env=LITELLM_LOCAL_MODEL_COST_MAP ip netns exec smoke setpriv --reuid "$(id -u)" --regid "$(id -g)" --init-groups -- env HOME="${HOME}" PATH="${PATH}" "$@" WRAP chmod +x "${RUNNER_TEMP}/in-netns" echo "IN_NETNS=${RUNNER_TEMP}/in-netns" >> "${GITHUB_ENV}" - name: Verify namespace isolation run: $IN_NETNS .venv/bin/python .github/scripts/run_merge_smoke.py verify-isolation - name: Verify interpreter version run: $IN_NETNS .venv/bin/python .github/scripts/run_merge_smoke.py interpreter --expect ${{ matrix.python-version }} - name: Import and CLI checks run: $IN_NETNS .venv/bin/python .github/scripts/run_merge_smoke.py cli - name: Proxy startup check run: $IN_NETNS .venv/bin/python .github/scripts/run_merge_smoke.py proxy-startup --diagnostics-dir "${RUNNER_TEMP}/smoke-diagnostics" - name: Run curated smoke cases run: $IN_NETNS .venv/bin/python .github/scripts/run_merge_smoke.py pytest --manifest .github/merge-smoke-tests.json - name: Upload smoke diagnostics if: always() uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: merge-smoke-diagnostics-py${{ matrix.python-version }} path: ${{ runner.temp }}/smoke-diagnostics if-no-files-found: ignore - name: Remove the network namespace if: always() run: sudo ip netns delete smoke