chore(deps): update Python dependencies (major) #249
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: | |
| # Set minimal permissions for security | |
| permissions: | |
| contents: read | |
| security-events: write | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.12', '3.13'] | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 | |
| - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip packages | |
| uses: ./.github/actions/cache-pip | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install dependencies | |
| run: | | |
| # Pin pip to patched version to mitigate tar extraction symlink vulnerability (GHSA-4xh5-x5gv-qwph) | |
| python -m pip install --upgrade pip==25.2 | |
| pip install -r requirements.txt | |
| pip install -r requirements-dev.txt | |
| pip install -e . | |
| - name: Lint | |
| run: | | |
| ruff check src clients/python tests | |
| black --check src clients/python tests | |
| - name: Check for changes in Python source files | |
| uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
| id: src-changes | |
| with: | |
| filters: | | |
| src: | |
| - 'src/**/*.py' | |
| - name: MyPy strict mode check (new code) | |
| if: steps.src-changes.outputs.src == 'true' | |
| run: | | |
| echo "Running MyPy strict mode check..." | |
| mypy --strict src/ --show-error-codes | |
| test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.12', '3.13'] | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 | |
| - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip packages | |
| uses: ./.github/actions/cache-pip | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install dependencies | |
| run: | | |
| # Pin pip to patched version to mitigate tar extraction symlink vulnerability (GHSA-4xh5-x5gv-qwph) | |
| python -m pip install --upgrade pip==25.2 | |
| pip install -r requirements.txt | |
| pip install -r requirements-dev.txt | |
| pip install -e . | |
| # Install optional dependencies for testing | |
| pip install -e ".[openai]" | |
| # Ensure coverage plugin is available for enforcing minimum coverage | |
| pip install pytest-cov | |
| - name: Run tests | |
| env: | |
| CF_API_KEY: test-key-32-chars-long-for-security # pragma: allowlist secret | |
| TESTING: true | |
| run: pytest --cov=. --cov-report=xml --cov-report=term-missing -v --cov-fail-under=30 tests/ | |
| - name: Upload coverage reports to Codecov | |
| uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| security: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 | |
| - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 | |
| with: | |
| python-version: '3.12' | |
| - name: Cache pip packages | |
| uses: ./.github/actions/cache-pip | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies | |
| run: | | |
| # Pin pip to patched version to mitigate tar extraction symlink vulnerability (GHSA-4xh5-x5gv-qwph) | |
| python -m pip install --upgrade pip==25.2 | |
| pip install -r requirements.txt | |
| pip install -e . | |
| pip install safety pip-audit | |
| - name: Security audit | |
| id: security-audit | |
| continue-on-error: true | |
| run: | | |
| set +e # Don't exit on non-zero return codes | |
| safety check --json > safety-results.json | |
| echo $? > safety-exit-code.txt | |
| pip-audit --desc --format=json --output=audit-results.json | |
| echo "Security audit completed. Check artifacts for results." | |
| - name: Upload security audit results | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: security-audit-results | |
| path: | | |
| safety-results.json | |
| safety-exit-code.txt | |
| audit-results.json | |
| - name: Security audit failure notification | |
| if: failure() && steps.security-audit.outcome == 'failure' | |
| run: | | |
| echo "::warning::Security audit failed! Check the security-audit-results artifact for details." | |
| echo "::group::Safety scan results" | |
| if [ -f safety-results.json ]; then | |
| cat safety-results.json | |
| else | |
| echo "safety-results.json not found" | |
| fi | |
| echo "::endgroup::" | |
| echo "::group::Pip audit results" | |
| if [ -f audit-results.json ]; then | |
| cat audit-results.json | |
| else | |
| echo "audit-results.json not found" | |
| fi | |
| echo "::endgroup::" | |
| - name: Import smoke test | |
| env: | |
| CF_API_KEY: test-key-32-chars-long-for-security # pragma: allowlist secret | |
| run: | | |
| python - << 'PY' | |
| import importlib | |
| import sys | |
| sys.path.append('src') | |
| import contextforge_memory | |
| from contextforge_memory.main import app | |
| print('Import smoke test: OK') | |
| PY | |
| - name: Basic functionality test | |
| env: | |
| CF_API_KEY: test-key-32-chars-long-for-security # pragma: allowlist secret | |
| run: | | |
| python - << 'PY' | |
| import sys | |
| sys.path.append('src') | |
| from contextforge_memory.main import app, _embed_text, get_embedding_dimension | |
| # Test embedding function | |
| test_text = "test embedding" | |
| embedding = _embed_text(test_text) | |
| expected_dim = get_embedding_dimension() | |
| assert len(embedding) == expected_dim, f"Expected {expected_dim} dimensions, got {len(embedding)}" | |
| assert all(0 <= x <= 1 for x in embedding), "Embeddings should be normalized to [0,1]" | |
| print('Basic functionality test: OK') | |
| PY | |
| pre-commit: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 | |
| - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 | |
| with: | |
| python-version: '3.12' | |
| - name: Enable pip cache | |
| uses: ./.github/actions/cache-pip | |
| with: | |
| python-version: '3.12' | |
| requirements-files: 'requirements.txt' | |
| additional-paths: '~/.cache/pip-audit' | |
| - name: Cache pre-commit | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.cache/pre-commit | |
| key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-precommit- | |
| - name: Install dependencies | |
| run: | | |
| # Pin pip to patched version to mitigate tar extraction symlink vulnerability (GHSA-4xh5-x5gv-qwph) | |
| python -m pip install --upgrade pip==25.2 | |
| pip install -r requirements.txt | |
| pip install -e . | |
| pip install pre-commit pip-audit | |
| - name: Run pre-commit | |
| run: | | |
| set +e | |
| pre-commit run --all-files --show-diff-on-failure | |
| EXIT_CODE=$? | |
| if [ $EXIT_CODE -ne 0 ]; then | |
| if git diff --name-only | grep -q "^\.secrets\.baseline$"; then | |
| echo "::error::.secrets.baseline has changed. Please run 'pre-commit run --all-files' locally to regenerate and commit the baseline file." | |
| echo "::error::This ensures baseline updates undergo proper review rather than auto-committing in CI." | |
| exit 1 | |
| fi | |
| echo "Pre-commit failed for non-baseline reasons" | |
| exit $EXIT_CODE | |
| fi |