CI/CD Pipeline Guide¶
datason uses a modern, multi-pipeline CI/CD architecture designed for speed, clarity, and parallel execution. This guide explains our complete CI/CD setup.
๐๏ธ Architecture Overview¶
graph TD
A[Git Push/PR] --> B{Change Type?}
B -->|Any Code| C[๐ Quality Pipeline]
B -->|Non-docs| D[๐งช Main CI Pipeline]
B -->|Docs Only| E[๐ Docs Pipeline]
B -->|Release Tag| F[๐ฆ Publish Pipeline]
C --> G[โ
Code Quality & Security]
D --> H[โ
Tests & Build]
E --> I[โ
Documentation]
F --> J[โ
PyPI Release]
๐ Pipeline Details¶
๐งช Main CI Pipeline (ci.yml
)¶
Triggers:
- Push to main
, develop
- Pull requests to main
- Excludes: docs-only changes
What it does:
jobs:
test:
- ๐ฅ Checkout code
- ๐ Setup Python 3.11
- ๐พ Cache pip dependencies
- ๐ฆ Install dev dependencies
- ๐งช Run core tests with plugin matrix:
โข minimal: tests/unit/ (no optional deps)
โข with-numpy: tests/unit/ + ML features (numpy)
โข with-pandas: tests/unit/ + data features (pandas)
โข with-ml-deps: tests/unit/ + tests/integration/ (full ML stack)
โข full: tests/unit/ + tests/edge_cases/ + tests/integration/
- ๐ Upload coverage to Codecov
- ๐ Security scan (bandit)
- ๐ค Upload security report
build:
- ๐๏ธ Build package (wheel + sdist)
- โ
Check package integrity
- ๐ค Upload build artifacts
Performance: ~2-3 minutes with caching
๐ Code Quality & Security Pipeline (ruff.yml
)¶
Triggers:
- All pushes to main
, develop
- All pull requests to main
, develop
What it does:
jobs:
quality-and-security:
- ๐ฅ Checkout code
- ๐ Setup Python 3.11
- ๐พ Cache pip dependencies (quality)
- ๐ ๏ธ Install ruff + bandit
- ๐งน Run ruff linter
- ๐จ Run ruff formatter check
- ๐ก๏ธ Run bandit security scan
- ๐ Generate quality report
Performance: ~30-60 seconds (15-30s with cache)
๐ Documentation Pipeline (docs.yml
)¶
Triggers:
- Changes to docs/**
, mkdocs.yml
, README.md
What it does:
jobs:
build-docs:
- ๐ฅ Checkout code
- ๐ Setup Python 3.11
- ๐พ Cache pip dependencies (docs)
- ๐พ Cache MkDocs build
- ๐ฆ Install docs dependencies
- ๐๏ธ Build documentation
- ๐ค Upload docs artifact
deploy-github-pages:
- ๐ Deploy to GitHub Pages (main only)
Performance: ~1-2 minutes (very fast with cache)
๐ฆ Publish Pipeline (publish.yml
)¶
Triggers: - GitHub releases (automatic) - Manual workflow dispatch
What it does:
jobs:
build:
- ๐๏ธ Build package
- โ
Verify package integrity
- ๐ค Upload build artifacts
test-pypi:
- ๐งช Publish to TestPyPI
- โ
Verify upload
pypi:
- ๐ Publish to PyPI (releases only)
- ๐ข Create release summary
Performance: ~2-3 minutes
โก Performance Optimizations¶
Intelligent Caching Strategy¶
Each pipeline has optimized caching:
# Main CI - General development cache
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
# Quality - Specialized for linting tools
key: ${{ runner.os }}-quality-pip-${{ hashFiles('**/pyproject.toml') }}
# Docs - Documentation-specific cache + MkDocs
key: ${{ runner.os }}-docs-pip-${{ hashFiles('**/pyproject.toml') }}
key: ${{ runner.os }}-mkdocs-${{ hashFiles('mkdocs.yml') }}-${{ hashFiles('docs/**') }}
Cache Benefits: - First run: Full dependency installation - Subsequent runs: 2-5x faster execution - Cross-pipeline sharing: Quality cache falls back to main cache
Smart Triggering¶
Path-based triggers prevent unnecessary runs:
# Main CI skips docs-only changes
paths-ignore:
- 'docs/**'
- '*.md'
- 'mkdocs.yml'
# Docs pipeline only runs for docs changes
paths: ['docs/**', 'mkdocs.yml', 'README.md']
Result: Docs changes don't trigger expensive test runs
๐ฏ Pipeline Responsibilities¶
Pipeline | Purpose | Speed | When |
---|---|---|---|
Main CI | Core functionality validation | ~2-3 min | Code changes |
Quality | Code quality & security | ~30-60s | All changes |
Docs | Documentation generation | ~1-2 min | Docs changes |
Performance | Performance regression tracking (informational) | ~3-5 min | Performance changes, weekly |
Publish | Package distribution | ~2-3 min | Releases |
๐๏ธ Test Structure & CI Matrix Alignment¶
New Organized Test Structure¶
Our test suite is organized into logical directories for optimal CI performance:
tests/
โโโ core/ # Fast core functionality tests (~7 seconds)
โ โโโ test_core.py # Basic serialization
โ โโโ test_security.py # Security features
โ โโโ test_circular_references.py # Circular reference handling
โ โโโ test_edge_cases.py # Edge cases and error handling
โ โโโ test_converters.py # Type converters
โ โโโ test_deserializers.py # Deserialization functionality
โ โโโ test_dataframe_orientation_regression.py
โ
โโโ features/ # Feature-specific tests (~10-20 seconds)
โ โโโ test_ml_serializers.py # ML library integrations
โ โโโ test_chunked_streaming.py # Streaming/chunking features
โ โโโ test_auto_detection_and_metadata.py # Auto-detection
โ โโโ test_template_deserialization.py # Template deserialization
โ
โโโ integration/ # Integration tests (~5-15 seconds)
โ โโโ test_config_and_type_handlers.py # Configuration integration
โ โโโ test_optional_dependencies.py # Dependency integrations
โ โโโ test_pickle_bridge.py # Pickle bridge functionality
โ
โโโ coverage/ # Coverage boost tests (~10-30 seconds)
โ โโโ test_*_coverage_boost.py # Targeted coverage improvement
โ
โโโ benchmarks/ # Performance tests (separate pipeline, ~60-120 seconds)
โโโ test_*_benchmarks.py # Performance measurements
CI Test Matrix Mapping¶
CI Job | Test Directories | Dependencies | Purpose | Speed |
---|---|---|---|---|
minimal | tests/unit/ |
None | Core functionality only | ~7s |
with-numpy | tests/unit/ + ML features |
numpy | Basic array support | ~15s |
with-pandas | tests/unit/ + data features |
pandas | DataFrame support | ~25s |
with-ml-deps | tests/unit/ + tests/integration/ |
numpy, pandas, sklearn | Full ML stack | ~45s |
full | tests/unit/ + tests/edge_cases/ + tests/integration/ |
All dependencies | Complete test suite | ~60s |
Performance | tests/benchmarks/ |
All dependencies | Performance tracking | ~120s (separate) |
Plugin Testing Strategy¶
Our CI implements plugin-style testing where the core package has zero required dependencies but gains functionality when optional dependencies are available:
- Core Tests (
tests/unit/
): Always run, no optional dependencies - Feature Tests (
tests/features/
): Run only when relevant dependencies are available - Integration Tests (
tests/integration/
): Test cross-component functionality - Coverage Tests (
tests/coverage/
): Improve coverage metrics for edge cases
This ensures:
- โ
Zero dependency install works: pip install datason
- โ
Enhanced features work: pip install datason[ml]
- โ
Cross-platform compatibility: Tests run on multiple Python versions
- โ
Fast feedback: Core tests complete in ~7 seconds
๐ Quality Gates¶
Automatic Checks¶
Every commit is validated by:
โ
Ruff linting (1000+ rules)
โ
Ruff formatting (consistent style)
โ
Bandit security scanning
โ
Test suite with coverage
โ
Type checking (mypy)
โ
Package build integrity
Required Checks¶
For PR merging, these must pass: - [ ] Code Quality & Security pipeline - [ ] Main CI pipeline (if code changed) - [ ] Documentation pipeline (if docs changed)
Optional Checks¶
Non-blocking but monitored: - Coverage reports (Codecov) - Security reports (GitHub Security tab) - Performance benchmarks
๐ Monitoring & Reports¶
GitHub Actions Dashboard¶
- โ Green: All checks passing
- โ Red: Issues found, PR blocked
- ๐ก Yellow: In progress
Detailed Reports¶
Quality Pipeline generates rich reports:
## Code Quality & Security Report
### ๐ Ruff Linting
โ
No issues found
### ๐จ Code Formatting
โ
All files properly formatted
### ๐ก๏ธ Security Scan Results
**Scanned**: 2,547 lines of code
**High Severity**: 0
**Medium Severity**: 0
**Low Severity**: 1
โ
**Security Status**: PASSED
Artifacts Available¶
- ๐ Coverage reports (HTML, XML)
- ๐ก๏ธ Security reports (JSON)
- ๐ฆ Build artifacts (wheels, sdist)
- ๐ Documentation (static site)
๐ Developer Workflow¶
Local Development¶
# Pre-commit handles local quality
git commit โ pre-commit runs โ quality checks pass โ commit succeeds
# Manual quality check
ruff check --fix .
ruff format .
pytest --cov=datason
Push to GitHub¶
What happens: 1. Quality Pipeline runs immediately (~30s) 2. Main CI runs in parallel (~2-3min) 3. PR Status Checks update in real-time
Documentation Changes¶
What happens: 1. Docs Pipeline runs (~1-2min) 2. Quality Pipeline runs (for any .md files) 3. Main CI skipped (docs-only change)
Release Process¶
What happens: 1. Publish Pipeline triggers automatically 2. Package built and verified 3. Published to PyPI with OIDC (secure, no tokens)
๐ ๏ธ Configuration Files¶
Workflow Locations¶
.github/workflows/
โโโ ci.yml # Main CI pipeline
โโโ ruff.yml # Code quality & security
โโโ docs.yml # Documentation
โโโ publish.yml # PyPI publishing
Key Configuration¶
# pyproject.toml - Tool configuration
[tool.ruff] # Linting rules
[tool.pytest] # Test configuration
[tool.coverage] # Coverage requirements
[tool.bandit] # Security scanning
# .pre-commit-config.yaml - Local hooks
repos:
- ruff # Local quality checks
- bandit # Local security
๐ง Customization¶
Adding New Checks¶
To Quality Pipeline:
To Main CI:
Performance Tuning¶
Cache Optimization:
# Add new cache for expensive tool
- name: Cache expensive-tool
uses: actions/cache@v4
with:
path: ~/.cache/expensive-tool
key: ${{ runner.os }}-expensive-${{ hashFiles('config') }}
Parallel Jobs:
๐ฏ Best Practices¶
Pipeline Design¶
- โ Fast feedback - Quality checks run first (30s)
- โ Parallel execution - Independent pipelines don't block each other
- โ Intelligent triggers - Only run what's needed
- โ Comprehensive caching - 2-5x speedup on repeated runs
Security¶
- โ OIDC Publishing - No API tokens needed
- โ Multi-tool scanning - Bandit + Safety + pip-audit
- โ Artifact signing - GPG-signed commits
- โ Dependency monitoring - Dependabot + security advisories
Developer Experience¶
- โ Clear status - GitHub status checks show exactly what failed
- โ Rich reports - Detailed summaries in GitHub UI
- โ Local consistency - pre-commit matches CI exactly
- โ Fast iteration - Quick feedback for common issues
๐ Metrics & Performance¶
Pipeline Performance¶
Pipeline | Cached | Uncached | Frequency |
---|---|---|---|
Quality | ~30s | ~60s | Every push/PR |
Main CI | ~2min | ~3min | Most pushes/PRs |
Docs | ~1min | ~2min | Docs changes only |
Publish | ~3min | ~3min | Releases only |
Success Rates¶
- Quality Pipeline: 95%+ pass rate (fast feedback catches most issues)
- Main CI: 90%+ pass rate (comprehensive testing)
- Docs: 99%+ pass rate (simple build process)
๐ Performance Pipeline Strategy¶
Why Performance Tests Don't Block CI:
The performance pipeline is informational only and doesn't block CI for these important reasons:
- Environment Variability: GitHub Actions runners have inconsistent performance
- Micro-benchmark Noise: Tests measuring <1ms are highly sensitive to environment
- Hardware Differences: Local vs CI environments produce different baseline measurements
- False Positive Prevention: Avoid blocking legitimate code changes due to infrastructure noise
Environment-Aware Thresholds:
Environment | Threshold | Reasoning |
---|---|---|
Local Development | 5% | Stable environment, consistent hardware |
CI (Same Environment) | 25% | Account for runner variability |
CI (Cross Environment) | 25%+ | Local baseline vs CI execution |
How to Interpret Performance Results:
โ Safe to Ignore: - Changes <50% (likely environment noise) - First run after environment change - Micro-benchmarks showing high variance
โ ๏ธ Worth Investigating: - Consistent patterns across multiple tests - Changes >100% without code explanation - Memory usage regressions
๐ฅ Action Required: - Changes >200% with clear code correlation - New algorithmic complexity introduced - Memory leaks or resource issues
Performance Baseline Management:
# Create new CI baseline (if needed)
gh workflow run performance.yml -f save_baseline=true
# Local performance testing
cd benchmarks
python ci_performance_tracker.py
# Test with different threshold
PERFORMANCE_REGRESSION_THRESHOLD=15 python ci_performance_tracker.py
๐ Troubleshooting¶
Common Issues¶
Quality Pipeline Fails:
Main CI Test Failures:
# Local debugging
pytest tests/test_failing.py -v
pytest --cov=datason --cov-report=html
# Open htmlcov/index.html
Cache Issues:
Performance Issues¶
Slow Pipeline: - Check cache hit rates in Actions logs - Verify cache keys are stable - Consider splitting large jobs
Resource Limits:
- Use timeout-minutes
for runaway processes
- Monitor memory usage in logs
- Consider matrix builds for heavy testing
This architecture provides:
- ๐ Fast feedback (30s for quality issues)
- ๐ Parallel execution (quality + tests simultaneously)
- ๐พ Intelligent caching (2-5x speedup)
- ๐ฏ Smart triggering (only run what's needed)
- ๐ Rich reporting (detailed GitHub summaries)
- ๐ Strong security (multi-tool scanning + OIDC)
The result is a production-ready CI/CD pipeline that scales with your team while maintaining developer velocity! ๐