python-ci.yml¶
Reusable workflow for Python continuous integration with quality checks, testing, security scanning, and building.
๐ค AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
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/python-ci.yml@v0.0.1
with:
python-version: '3.11'
With Security Scanning¶
jobs:
ci:
permissions:
contents: read
security-events: write
uses: provide-io/ci-tooling/.github/workflows/python-ci.yml@v0.0.1
with:
python-version: '3.11'
run-security: true
Matrix Testing¶
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/python-ci.yml@v0.0.1
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/python-ci.yml@v0.0.1
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/python-ci.yml@v0.0.1
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/python-ci.yml@v0.0.1
with:
source-paths: 'lib/ tests/'
test-directory: 'spec/'
Using Outputs¶
jobs:
ci:
uses: provide-io/ci-tooling/.github/workflows/python-ci.yml@v0.0.1
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:
Next Steps¶
- python-release.yml - Release workflow
- Actions - Individual actions
- Quick Start - Getting started guide