python-ci.yml¶
Reusable workflow for Python continuous integration with quality checks, testing, security scanning, and building.
Overview¶
Complete CI pipeline with orchestrated jobs:
- Quality - Code quality checks (ruff, mypy)
- Test - PyTest execution with coverage
- Security - Security scanning (optional)
- Performance - Performance benchmarks (optional)
Usage¶
Basic CI¶
name: CI
on: [push, pull_request]
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
python-version: '3.11'
With Security Scanning¶
jobs:
ci:
permissions:
contents: read
security-events: write
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
python-version: '3.11'
run-security: true
Matrix Testing¶
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
matrix-testing: true
os-matrix: 'ubuntu-latest,macos-latest,windows-latest'
Inputs¶
| Input | Type | Description | Default |
|---|---|---|---|
python-version |
string | Python version to use | '3.11' |
uv-version |
string | UV version to use | '0.7.8' |
source-paths |
string | Source paths for quality checks | 'src/ tests/' |
test-directory |
string | Test directory | 'tests/' |
coverage-threshold |
number | Coverage threshold percentage | 80 |
run-security |
boolean | Run security scanning | true |
run-performance |
boolean | Run performance tests | false |
matrix-testing |
boolean | Enable matrix testing across Python versions | false |
os-matrix |
string | Operating systems to test on (comma-separated) | 'ubuntu-latest' |
fail-fast |
boolean | Fail fast in matrix builds | false |
Secrets¶
| Secret | Description | Required |
|---|---|---|
CODECOV_TOKEN |
Codecov token for coverage upload | No |
Outputs¶
| Output | Description |
|---|---|
coverage-percentage |
Test coverage percentage |
package-version |
Built package version |
Jobs¶
quality¶
Runs first, performs code quality checks:
- Ruff linting:
ruff check - Ruff formatting:
ruff format --check - MyPy type checking:
mypy src/
Subsequent jobs only run if quality passes.
test¶
Runs after quality, executes tests:
- PyTest: Runs test suite
- Coverage: Tracks code coverage
- Matrix: Optional multi-version/OS testing
- Artifacts: Uploads test results and coverage
security (Optional)¶
Runs parallel to tests when run-security: true:
- Bandit: Security vulnerability scanning
- Safety: Dependency vulnerability check
- SARIF: Upload to GitHub Security tab
performance (Optional)¶
Runs when run-performance: true:
- Benchmarks: Performance benchmark execution
- Comparison: Compare against baseline
- Reports: Upload benchmark results
Job Dependencies¶
quality
├── test (depends on quality)
├── security (parallel to test)
└── performance (parallel to test)
Quality checks must pass before other jobs run. Test, security, and performance jobs run in parallel.
Examples¶
Complete CI Pipeline¶
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
permissions:
contents: read
security-events: write
pull-requests: write
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
python-version: '3.11'
coverage-threshold: 85
run-security: true
run-performance: false
secrets:
codecov-token: ${{ secrets.CODECOV_TOKEN }}
Matrix Testing Example¶
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
matrix-testing: true
python-version: '3.11' # Base version, matrix adds 3.12, 3.13
os-matrix: 'ubuntu-latest,macos-latest'
fail-fast: false # Continue testing all combinations
Custom Paths¶
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
source-paths: 'lib/ tests/'
test-directory: 'spec/'
Using Outputs¶
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
with:
python-version: '3.11'
deploy:
needs: ci
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy
run: |
echo "Coverage: ${{ needs.ci.outputs.coverage-percentage }}%"
echo "Deploying version: ${{ needs.ci.outputs.package-version }}"
Matrix Testing¶
When matrix-testing: true, tests run across:
- Python versions: 3.11, 3.12, 3.13
- Operating systems: As specified in
os-matrix
Total combinations: len(python_versions) × len(os_matrix)
Example with os-matrix: 'ubuntu-latest,macos-latest':
- 3.11 on ubuntu-latest
- 3.11 on macos-latest
- 3.12 on ubuntu-latest
- 3.12 on macos-latest
- 3.13 on ubuntu-latest
- 3.13 on macos-latest
Permissions¶
Minimal (No Security)¶
With Security Scanning¶
With PR Comments¶
Artifacts¶
Automatically uploaded artifacts:
test-results¶
test-results.xml- JUnit formatcoverage.xml- Coverage report- Retention: 30 days
security-results (if enabled)¶
bandit-report.json- Bandit scansafety-report.json- Safety checkresults.sarif- SARIF format- Retention: 90 days
performance-results (if enabled)¶
benchmark-results.json- Retention: 30 days
Codecov Integration¶
When CODECOV_TOKEN secret is provided:
- Coverage reports uploaded to Codecov
- PR comments with coverage delta
- Coverage trends and graphs
Setup:
1. Sign up at codecov.io
2. Add repository
3. Copy token
4. Add as CODECOV_TOKEN secret
Troubleshooting¶
Quality Checks Failing¶
Quality job blocks all other jobs. Fix issues or adjust settings:
Coverage Below Threshold¶
Lower threshold temporarily:
Or improve test coverage.
Matrix Jobs Failing¶
Use fail-fast: false to see all failures:
Security Job Blocking¶
Disable temporarily:
Performance¶
| Configuration | Time | Notes |
|---|---|---|
| Basic (no matrix) | 2-4min | Single OS, single Python |
| Matrix (3 versions) | 3-6min | Parallel execution |
| Matrix (3 versions, 3 OS) | 4-8min | 9 parallel jobs |
| With security | +1-2min | Parallel to tests |
Best Practices¶
Always Run Quality First¶
Quality checks are fast and catch common issues early.
Use Matrix Sparingly¶
Matrix testing is thorough but resource-intensive. Consider: - Run on main branch only - Run on schedule (nightly) - Run on release PRs only
Set Appropriate Thresholds¶
- Start with 70% coverage
- Gradually increase to 80-90%
- Don't aim for 100% immediately
Enable Security Scanning¶
Security scans are valuable: - Catch vulnerabilities early - Low overhead (parallel to tests) - Integrates with GitHub Security
Migration from Custom Workflows¶
Before:
After:
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/[email protected]
Next Steps¶
- python-release.yml - Release workflow
- Actions - Individual actions
- Quick Start - Getting started guide