fix(router): exclude hard-cooldowned providers + DeepSeek V4 + Codex plan-tier #620
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install dependencies | |
| run: | | |
| pip install -e ".[dev]" | |
| - name: Lint | |
| run: ruff check . | |
| - name: Test with coverage | |
| run: pytest tests/ -v --cov=faigate --cov-report=term --cov-report=xml:coverage.xml | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| file: ./coverage.xml | |
| fail_ci_if_error: false | |
| package: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Build Python package | |
| run: | | |
| python -m pip install --upgrade pip build twine | |
| python -m build | |
| python -m twine check dist/* | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install ruff pre-commit | |
| - run: ruff check . | |
| - run: ruff format --check . | |
| - run: bash -n scripts/* | |
| - name: Validate pre-commit config | |
| run: pre-commit validate-config .pre-commit-config.yaml | |
| - run: pre-commit run --all-files --show-diff-on-failure | |
| - name: Validate version consistency | |
| run: | | |
| python - <<'PY' | |
| import re, sys | |
| from pathlib import Path | |
| root = Path('.') | |
| pyproject_content = (root / 'pyproject.toml').read_text() | |
| package_content = (root / 'faigate' / '__init__.py').read_text() | |
| pv = re.search(r'^version = "([^"]+)"$', pyproject_content, re.MULTILINE) | |
| iv = re.search(r'^__version__ = "([^"]+)"$', package_content, re.MULTILINE) | |
| if not pv: | |
| sys.exit('ERROR: version not found in pyproject.toml') | |
| if not iv: | |
| sys.exit('ERROR: __version__ not found in faigate/__init__.py') | |
| if pv.group(1) != iv.group(1): | |
| sys.exit(f'ERROR: version mismatch: pyproject={pv.group(1)} package={iv.group(1)}') | |
| print(f'Version OK: {pv.group(1)}') | |
| PY | |
| security: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install bandit[toml] | |
| - run: bandit -c pyproject.toml -r faigate -f html -o bandit-report.html || true | |
| - run: bandit -c pyproject.toml -r faigate -f json -o bandit-report.json || true | |
| - name: Upload Bandit report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: bandit-security-report | |
| path: | | |
| bandit-report.html | |
| bandit-report.json | |
| benchmarks: | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e .[dev] | |
| - name: Run performance benchmarks | |
| run: pytest tests/benchmarks/ --benchmark-only --benchmark-json=benchmark-results.json | |
| - name: Upload benchmark results | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-results | |
| path: benchmark-results.json | |
| docs: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e .[dev] | |
| - name: Generate API documentation | |
| run: python scripts/generate-api-docs.py | |
| - name: Check if API.md changed | |
| run: | | |
| if ! git diff --quiet docs/API.md; then | |
| echo "::warning::API.md is out of date. Run 'python scripts/generate-api-docs.py' and commit." | |
| git diff docs/API.md | |
| else | |
| echo "API.md is up to date." | |
| fi | |
| changelog: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install git-cliff | |
| run: | | |
| VERSION=$(curl -s https://api.github.com/repos/orhun/git-cliff/releases/latest | grep '"tag_name"' | cut -d'"' -f4 | tr -d 'v') | |
| curl -LsSf "https://github.com/orhun/git-cliff/releases/download/v${VERSION}/git-cliff-${VERSION}-x86_64-unknown-linux-gnu.tar.gz" | tar xz -C /tmp | |
| sudo mv /tmp/git-cliff-*/git-cliff /usr/local/bin/ | |
| - name: Generate changelog | |
| run: git-cliff --config .cliff.toml --unreleased --strip header -o /tmp/generated-changelog.md | |
| - name: Check if CHANGELOG.md is up to date | |
| run: | | |
| if ! diff -u CHANGELOG.md /tmp/generated-changelog.md; then | |
| echo "::warning::CHANGELOG.md has unreleased entries. Run: git-cliff --unreleased --strip header -o CHANGELOG.md" | |
| else | |
| echo "CHANGELOG.md is up to date." | |
| fi | |
| forbid-artifacts: | |
| name: Forbid artifacts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fail if forbidden paths are tracked | |
| run: | | |
| set -euo pipefail | |
| if git ls-files | grep -qE '(\.ssh/|\.db($|-)|.*\.sqlite|.*\.log$)'; then | |
| echo "ERROR: forbidden files are tracked:" | |
| git ls-files | grep -E '(\.ssh/|\.db($|-)|.*\.sqlite|.*\.log$)' || true | |
| exit 1 | |
| fi | |
| - name: Fail if history contains forbidden blobs | |
| run: | | |
| set -euo pipefail | |
| if git rev-list --objects --all | grep -qE '(\.ssh/|.*\.db($|-)|.*\.sqlite|.*\.log$)'; then | |
| echo "ERROR: forbidden artifacts exist in history:" | |
| git rev-list --objects --all | grep -E '(\.ssh/|.*\.db($|-)|.*\.sqlite|.*\.log$)' || true | |
| exit 1 | |
| fi | |
| gate: | |
| name: CI Gate | |
| runs-on: ubuntu-latest | |
| needs: [test, lint, package, forbid-artifacts] | |
| if: always() | |
| steps: | |
| - name: All required checks passed | |
| run: | | |
| if [[ "${{ needs.test.result }}" != "success" ]] || | |
| [[ "${{ needs.lint.result }}" != "success" ]] || | |
| [[ "${{ needs.package.result }}" != "success" ]] || | |
| [[ "${{ needs.forbid-artifacts.result }}" != "success" ]]; then | |
| echo "::error::One or more required checks failed — merge blocked." | |
| exit 1 | |
| fi | |
| echo "All required checks passed." |