test(lint): remove dead skips + ratchet CLAUDE.md §3.7 violations #434
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/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main ] | |
| release: | |
| types: [ published ] | |
| workflow_dispatch: | |
| inputs: | |
| publish_target: | |
| description: 'Which index to publish to' | |
| type: choice | |
| options: | |
| - none | |
| - testpypi-only | |
| - pypi-only | |
| - both | |
| default: none | |
| # Opt into Node 24 runtime early for all JavaScript actions. | |
| # GitHub's documented migration path (blog post 2025-09-19) before the | |
| # hard cutover on 2026-06-02. Keeps existing action versions intact and | |
| # just swaps the runtime, so no surface-area change in our steps. | |
| # Security: pure runner config, no user input. | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true' | |
| jobs: | |
| # Decide the test matrix based on trigger: | |
| # - pull_request: 1 combo (ubuntu-latest × 3.10) — fast PR feedback, keeps Codecov upload | |
| # - push / release / workflow_dispatch: full 13-combo matrix | |
| # Rationale: PR CI was ~44 min wall-clock on the slowest Windows shard; a PR | |
| # rarely needs all 13 shards to catch regressions, and push-to-main still runs | |
| # the full matrix before any release. Fully reversible: delete set-matrix and | |
| # inline the old matrix block to restore. | |
| set-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.compute.outputs.matrix }} | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| steps: | |
| - id: compute | |
| shell: bash | |
| run: | | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| # Match the Codecov upload combo (ubuntu-latest × 3.10) so PR runs still publish coverage. | |
| echo 'matrix={"include":[{"os":"ubuntu-latest","python-version":"3.10"}]}' >> "$GITHUB_OUTPUT" | |
| else | |
| echo 'matrix={"include":[{"os":"ubuntu-latest","python-version":"3.9"},{"os":"ubuntu-latest","python-version":"3.10"},{"os":"ubuntu-latest","python-version":"3.11"},{"os":"ubuntu-latest","python-version":"3.12"},{"os":"ubuntu-latest","python-version":"3.13"},{"os":"windows-latest","python-version":"3.10"},{"os":"windows-latest","python-version":"3.11"},{"os":"windows-latest","python-version":"3.12"},{"os":"windows-latest","python-version":"3.13"},{"os":"macos-latest","python-version":"3.10"},{"os":"macos-latest","python-version":"3.11"},{"os":"macos-latest","python-version":"3.12"},{"os":"macos-latest","python-version":"3.13"}]}' >> "$GITHUB_OUTPUT" | |
| fi | |
| test: | |
| needs: set-matrix | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.set-matrix.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Lint with flake8 | |
| run: | | |
| flake8 src/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics | |
| flake8 src/ tests/ --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics | |
| - name: Test with pytest | |
| run: | | |
| pytest tests/ -v --cov=src/statspai --cov-report=xml | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| file: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| build: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine | |
| - name: Build package | |
| run: python -m build | |
| - name: Check package | |
| run: twine check dist/* | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-packages | |
| path: dist/ | |
| publish-test: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'release' && github.event.action == 'published') || | |
| (github.event_name == 'workflow_dispatch' && (inputs.publish_target == 'testpypi-only' || inputs.publish_target == 'both')) | |
| environment: testpypi | |
| permissions: | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine | |
| - name: Build package | |
| run: python -m build | |
| - name: Check package | |
| run: twine check dist/* | |
| - name: Publish to TestPyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| skip-existing: true | |
| publish-prod: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'release' && github.event.action == 'published') || | |
| (github.event_name == 'workflow_dispatch' && (inputs.publish_target == 'pypi-only' || inputs.publish_target == 'both')) | |
| environment: pypi | |
| permissions: | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine | |
| - name: Build package | |
| run: python -m build | |
| - name: Check package | |
| run: twine check dist/* | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| skip-existing: true | |
| security: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install safety bandit | |
| - name: Run safety check | |
| run: safety check --json || true | |
| - name: Run bandit security check | |
| run: bandit -r src/ -f json --severity-level medium |