feat: initial release of arbitrium-core v0.1.0 #18
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: ['**'] | |
| permissions: | |
| contents: read | |
| security-events: write | |
| jobs: | |
| # ============================================================================ | |
| # LAYER 1: Fast feedback (runs first) | |
| # ============================================================================ | |
| pre-commit: | |
| name: Pre-commit hooks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Cache pre-commit | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pre-commit | |
| key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} | |
| - name: Install pre-commit | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pre-commit | |
| - name: Run pre-commit | |
| run: pre-commit run --all-files | |
| lint-type-check: | |
| name: Lint & Type Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Cache pip | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-lint-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-lint-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| - name: Run ruff | |
| run: ruff check src tests | |
| - name: Run black | |
| run: black --check src tests | |
| - name: Run mypy | |
| run: mypy src | |
| # ============================================================================ | |
| # LAYER 2: Cross-platform Testing (depends on Layer 1) | |
| # ============================================================================ | |
| test: | |
| name: Test (Python ${{ matrix.python-version }} / ${{ matrix.os }}) | |
| needs: [pre-commit, lint-type-check] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ['3.10', '3.11', '3.12', '3.13'] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-${{ matrix.python-version }}- | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| - name: Run tests with coverage | |
| shell: bash | |
| run: | | |
| pytest tests/ -v \ | |
| --cov=src/arbitrium_core \ | |
| --cov-report=xml \ | |
| --cov-report=term-missing \ | |
| --cov-branch \ | |
| --junitxml=test-results.xml | |
| - name: Enforce coverage threshold | |
| if: runner.os == 'Linux' && matrix.python-version == '3.12' | |
| run: coverage report --fail-under=40 | |
| - name: Upload coverage report | |
| if: runner.os == 'Linux' && matrix.python-version == '3.12' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: | | |
| coverage.xml | |
| test-results.xml | |
| retention-days: 1 | |
| # ============================================================================ | |
| # NOTE: PyPy testing disabled - scikit-learn doesn't support PyPy | |
| # (scipy build fails due to OpenBLAS dependency issues) | |
| # ============================================================================ | |
| # LAYER 3: Quality analysis (parallel, non-blocking on main) | |
| # ============================================================================ | |
| mutation-testing: | |
| name: Mutation Testing | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Cache pip | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-mutmut-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-mutmut-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| pip install mutmut pytest-timeout | |
| - name: Run mutation testing | |
| env: | |
| PYTHONPATH: ${{ github.workspace }}/src | |
| run: | | |
| echo "=== Running Mutation Testing ===" | |
| cd ${{ github.workspace }} | |
| mutmut run || true | |
| - name: Generate mutation report | |
| run: | | |
| echo "=== Mutation Testing Results ===" | |
| mutmut results || true | |
| echo "" | |
| echo "=== Survived Mutants ===" | |
| mutmut results --survived 2>/dev/null || true | |
| complexity-checks: | |
| name: Complexity & Maintainability Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Install radon | |
| run: pip install radon | |
| - name: Check cyclomatic complexity | |
| run: | | |
| echo "=== Cyclomatic Complexity Report ===" | |
| radon cc src/arbitrium_core/ --min B --show-complexity --total-average | |
| - name: Check maintainability index | |
| run: | | |
| echo "=== Maintainability Index Report ===" | |
| radon mi src/arbitrium_core/ --min B --show | |
| - name: Fail on high complexity | |
| run: | | |
| radon cc src/arbitrium_core/ --min C --total-average || \ | |
| (echo "::warning::High complexity detected (grade C or worse)" && exit 0) | |
| architecture-checks: | |
| name: Architecture & Import Contracts | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| pip install import-linter | |
| - name: Create import contracts | |
| run: | | |
| cat > .importlinter <<EOF | |
| [importlinter] | |
| root_package = arbitrium_core | |
| [importlinter:contract:1] | |
| name = CLI should not import domain internals directly | |
| type = forbidden | |
| source_modules = arbitrium_core.interfaces.cli | |
| forbidden_modules = arbitrium_core.domain.tournament.tournament | |
| [importlinter:contract:2] | |
| name = Domain should not import interfaces | |
| type = forbidden | |
| source_modules = arbitrium_core.domain | |
| forbidden_modules = arbitrium_core.interfaces | |
| [importlinter:contract:3] | |
| name = Support should be independent | |
| type = independence | |
| modules = | |
| arbitrium_core.support | |
| EOF | |
| - name: Validate architecture | |
| run: lint-imports || echo "::warning::Architecture violations detected" |