Advanced quality gate patterns — dynamic thresholds, composite scoring, and metric history tracking.
dynamic_thresholds.py— Adjust gate thresholds based on git change sizecomposite_gates.py— Weighted composite score from multiple metricsmetric_history.py— Track metrics over time and detect regressionspyqual.yaml— Pipeline config for custom gates
Adjusts coverage thresholds based on the number of changed Python files:
- Large changes (>10 files): lower threshold (60%)
- Small changes (≤10 files): higher threshold (80%)
python dynamic_thresholds.pyCombines coverage, complexity, lint errors, and security issues into a single weighted score (0–100). Gates pass only if both individual gates AND the composite score meet thresholds.
python composite_gates.pyWeights:
| Component | Weight | Source |
|---|---|---|
| Coverage | 35% | pytest-cov |
| Complexity | 25% | code2llm |
| Lint errors | 20% | ruff |
| Security | 20% | bandit |
Stores metric snapshots in .pyqual/metric_history.json and detects regressions between runs. Fails if any metric regresses beyond a configurable tolerance.
python metric_history.pyFeatures:
- Timestamped metric snapshots
- Per-metric trend analysis (improving / degrading / stable)
- Configurable regression tolerance (default: 2%)
- Distinguishes "higher is better" vs "lower is better" metrics
cd examples/custom_gates
# Run individual examples
python dynamic_thresholds.py
python composite_gates.py
python metric_history.py
# Run the pipeline
pyqual run -c pyqual.yamlGateConfig— defines a single metric + operator + thresholdGateSet— collection of gates with metric collection from.pyqual/artifactsGate.check(metrics)— evaluates one gate against collected metricsgate_set.check_all(workdir)— collects metrics and checks all gatesgate_set._collect_metrics(workdir)— gathers metrics from all sources
See pyqual.yaml for the example pipeline configuration.