Fix linting #13
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: Comprehensive Testing Suite | |
| on: | |
| push: | |
| branches: [ main, develop, v0.2.0 ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run nightly benchmarks at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| env: | |
| PYTHONUNBUFFERED: 1 | |
| PYTEST_ADDOPTS: --color=yes | |
| jobs: | |
| # Fast smoke tests for quick feedback | |
| smoke-tests: | |
| name: Smoke Tests (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["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 }} | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Validate installation | |
| run: | | |
| python -c "import preprimer; print(f'PrePrimer version: {preprimer.__version__ if hasattr(preprimer, \"__version__\") else \"development\"}')" | |
| python -c "from preprimer.parsers.varvamp_parser import VarVAMPParser; print('VarVAMP parser imported successfully')" | |
| - name: Run core tests (fast subset) | |
| run: | | |
| python -m pytest tests/test_core_interfaces.py tests/test_core_config.py -v --tb=short | |
| # Comprehensive test suite | |
| comprehensive-tests: | |
| name: Full Test Suite (${{ matrix.os }}, Python ${{ matrix.python-version }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: smoke-tests | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| python-version: ["3.11", "3.12", "3.13"] | |
| # No additional includes needed - all versions covered in matrix | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run comprehensive test suite | |
| run: | | |
| python -m pytest tests/ \ | |
| --cov=preprimer \ | |
| --cov-report=xml \ | |
| --cov-report=term-missing \ | |
| --cov-report=html \ | |
| --tb=short \ | |
| -x | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| - name: Upload coverage artifacts | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-reports | |
| path: | | |
| coverage.xml | |
| htmlcov/ | |
| retention-days: 7 | |
| # Property-based testing | |
| property-testing: | |
| name: Property-Based Testing | |
| runs-on: ubuntu-latest | |
| needs: smoke-tests | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run property-based tests | |
| run: | | |
| python -m pytest tests/test_property_based.py -v \ | |
| --hypothesis-max-examples=1000 \ | |
| --hypothesis-show-statistics \ | |
| --tb=short | |
| - name: Upload Hypothesis database | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: hypothesis-database | |
| path: .hypothesis/ | |
| retention-days: 7 | |
| # Security testing | |
| security-testing: | |
| name: Security Testing | |
| runs-on: ubuntu-latest | |
| needs: smoke-tests | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install bandit safety | |
| - name: Run security validation tests | |
| run: | | |
| python -m pytest tests/test_security.py -v --tb=short | |
| - name: Run bandit security linter | |
| run: | | |
| bandit -r preprimer/ -f json -o bandit-report.json || true | |
| bandit -r preprimer/ -f txt | |
| - name: Check dependencies for known vulnerabilities | |
| run: | | |
| safety check --json --output safety-report.json || true | |
| safety check | |
| - name: Upload security reports | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-reports | |
| path: | | |
| bandit-report.json | |
| safety-report.json | |
| retention-days: 30 | |
| # Performance benchmarking | |
| performance-benchmarks: | |
| name: Performance Benchmarks | |
| runs-on: ubuntu-latest | |
| needs: smoke-tests | |
| if: github.event_name == 'schedule' || contains(github.event.head_commit.message, '[benchmark]') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| # Fetch history for performance comparison | |
| fetch-depth: 0 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run performance benchmarks | |
| run: | | |
| python -m pytest tests/test_benchmarks.py -v \ | |
| --benchmark-only \ | |
| --benchmark-json=benchmark-results.json \ | |
| --benchmark-save=benchmark-$(date +%Y%m%d-%H%M%S) \ | |
| --benchmark-sort=mean | |
| - name: Upload benchmark results | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-results | |
| path: | | |
| benchmark-results.json | |
| .benchmarks/ | |
| retention-days: 30 | |
| - name: Comment PR with benchmark results | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| try { | |
| const results = JSON.parse(fs.readFileSync('benchmark-results.json', 'utf8')); | |
| const benchmarks = results.benchmarks; | |
| let comment = '## 🚀 Performance Benchmark Results\n\n'; | |
| comment += '| Benchmark | Mean Time | Operations/sec |\n'; | |
| comment += '|-----------|-----------|---------------|\n'; | |
| benchmarks.slice(0, 10).forEach(bench => { | |
| const name = bench.name.replace('test_', '').replace('_benchmark', ''); | |
| const mean = bench.stats.mean; | |
| const ops = (1 / mean).toExponential(2); | |
| comment += `| ${name} | ${mean.toFixed(6)}s | ${ops} |\n`; | |
| }); | |
| comment += `\n**Total benchmarks:** ${benchmarks.length}`; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: comment | |
| }); | |
| } catch (error) { | |
| console.log('Could not parse benchmark results:', error.message); | |
| } | |
| # Integration testing | |
| integration-testing: | |
| name: Integration Testing | |
| runs-on: ${{ matrix.os }} | |
| needs: comprehensive-tests | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run integration tests | |
| run: | | |
| python -m pytest tests/test_integration.py -v --tb=short | |
| - name: Test CLI functionality | |
| run: | | |
| # Test CLI installation and basic functionality | |
| python -c "import preprimer; print('✅ PrePrimer module imported successfully')" | |
| # Test with small dataset | |
| python -m pytest tests/test_data/datasets/small/ -k "not test_" --collect-only || true | |
| echo "✅ Test data structure validation passed" | |
| # Mutation testing (weekly) | |
| mutation-testing: | |
| name: Mutation Testing | |
| runs-on: ubuntu-latest | |
| needs: comprehensive-tests | |
| if: github.event_name == 'schedule' || contains(github.event.head_commit.message, '[mutation]') | |
| timeout-minutes: 120 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Run mutation testing | |
| run: | | |
| # Run on core modules only to manage time | |
| python scripts/run_mutation_tests.py --paths preprimer/core/ preprimer/parsers/varvamp_parser.py | |
| - name: Upload mutation test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mutation-test-results | |
| path: mutation_results/ | |
| retention-days: 30 | |
| # Code quality and linting | |
| code-quality: | |
| name: Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install pre-commit | |
| - name: Run code formatting check | |
| run: | | |
| black --check --diff preprimer/ tests/ examples/ scripts/ | |
| - name: Run import sorting check | |
| run: | | |
| isort --check-only --diff preprimer/ tests/ examples/ scripts/ | |
| - name: Run linting | |
| run: | | |
| flake8 preprimer/ tests/ examples/ scripts/ --max-line-length=88 --extend-ignore=E203,W503 | |
| - name: Run type checking | |
| run: | | |
| mypy preprimer/ --ignore-missing-imports --no-strict-optional | |
| - name: Run pre-commit hooks | |
| run: | | |
| pre-commit run --all-files || true | |
| # Deployment readiness check | |
| deployment-check: | |
| name: Deployment Readiness | |
| runs-on: ubuntu-latest | |
| needs: [comprehensive-tests, security-testing, code-quality] | |
| if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/v0.2.0' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install build twine | |
| - name: Build package | |
| run: | | |
| python -m build | |
| - name: Check package | |
| run: | | |
| python -m twine check dist/* | |
| - name: Test package installation | |
| run: | | |
| pip install dist/*.whl | |
| python -c "import preprimer; print('✅ Package installation successful')" | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: package-build | |
| path: dist/ | |
| retention-days: 7 | |
| # Summary report | |
| test-summary: | |
| name: Test Summary | |
| runs-on: ubuntu-latest | |
| needs: [comprehensive-tests, property-testing, security-testing, integration-testing, code-quality] | |
| if: always() | |
| steps: | |
| - name: Check test results | |
| run: | | |
| echo "## 📊 Test Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Comprehensive Tests**: ${{ needs.comprehensive-tests.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Property-Based Testing**: ${{ needs.property-testing.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Security Testing**: ${{ needs.security-testing.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Integration Testing**: ${{ needs.integration-testing.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Code Quality**: ${{ needs.code-quality.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Overall Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY |