๐ฆ Quality Gate
Every service must pass these gates before being deployed to production.
Build success โ production readiness.
Gate Criteria
โ ๐ BLOCK
Unit + Integration Tests
dotnet testThreshold: 100% pass
How to resolve a failure
- Run locally: dotnet test <Service>.Tests/ -v normal
- Check the TRX output for failed test names and stack traces
- Do not skip (ignore) tests โ remove the [Ignore] attribute and fix the underlying issue
โก๐ BLOCK
Security Scan
Trivy (container image)Threshold: 0 HIGH/CRITICAL fixable CVEs
How to resolve a failure
- Run: trivy image <image-ref> --severity HIGH,CRITICAL --ignore-unfixed
- Update the affected NuGet / npm / OS package to the version in the "Fixed Version" column
- If no fix is available yet, add the CVE to .trivyignore with an expiry date (max 30 days) and a comment
โข๐ BLOCK
Code Coverage
dotnet coverage (Cobertura)Threshold: โฅ 60% financial services ยท โฅ 40% others
How to resolve a failure
- Run: dotnet test --collect:"XPlat Code Coverage" --results-directory ./coverage
- Open coverage/*/coverage.cobertura.xml and look for low-coverage files (line-rate)
- Add tests for the uncovered business logic โ focus on happy path + one error path per public method
- Financial services (Accounting, Billing, Treasury, POS, Purchasing, FixedAssets) must reach 60%
โฃ๐ BLOCK
Static Analysis
Roslyn AnalyzersThreshold: 0 critical errors
How to resolve a failure
- Run: dotnet build -p:RunAnalyzersDuringBuild=true and inspect error lines
- Fix the reported diagnostic (e.g. CA2007, CS8600) โ do not suppress without a documented reason
- Add #pragma warning disable XXXX only when the false-positive is confirmed, with a comment explaining why
โค๐ BLOCK
OpenAPI Contract Compatibility
oasdiffThreshold: 0 breaking changes vs main
How to resolve a failure
- Run: oasdiff breaking openapi-base.yaml openapi.yaml --format text
- Removing an endpoint, changing a required parameter type, or removing a response field are all breaking
- Version the API (v2) or use additive-only changes when backward compatibility cannot be maintained
- If no openapi.yaml exists yet, the gate is skipped โ add one to enable this protection
โฅ๐ BLOCK
Architecture Tests (KafkaLibrary)
NetArchTest / ArchUnitNETThreshold: 100% pass
How to resolve a failure
- Run: dotnet test <Service>.ArchTests/
- Common violations: using Confluent.Kafka directly instead of KafkaLibrary abstractions
- Fix by replacing direct Confluent.Kafka usage with the IEventPublisher / IEventConsumer interfaces
- If no ArchTests project exists, the gate emits a WARN โ create one to enforce patterns (see TASK-127)
โฆโ ๏ธ WARN
Performance Smoke (p95)
k6Threshold: p95 < 500ms baseline + 20% = 600ms
How to resolve a failure
- Run: k6 run --env BASE_URL=https://staging.innovask.com tools/quality-gate/smoke.js
- Check for N+1 queries, missing DB indexes, or uncached hot paths
- Use dotnet-trace or Application Insights to profile the slow endpoint
- WARN does not block production, but a P95 > 1000ms should be escalated immediately
Financial Services (stricter coverage)
The following services require โฅ 60% line coverage (vs 40% for others):
- Accounting_Api
- Billing_Api
- Treasury_Api
- POS_Api
- Purchasing_Api
- FixedAssets_Api
Override Process
If a blocking gate cannot be fixed immediately, the QA team can override by:
- Opening a ticket in the issue tracker describing the risk and reason
- Entering the ticket reference in the
override_reasonfield when triggering a manual deployment:QG-OVERRIDE-2026-0042: approved by @qa-lead โ CVE-2024-1234 has no fix yet, risk accepted
- The override is logged in the Quality Gate Report artifact for audit
- Overrides expire after 14 days โ the gate is enforced again after that
Running the gate locally
# From the DevOps repo root: ./tools/quality-gate/run.sh ../../Accounting_Api --financial # With a built container image: ./tools/quality-gate/run.sh ../../Auth_Api --image ghcr.io/org/auth-api:sha-abc1234
CI/CD Integration
CI (ci-*.yml) โ build + test + Trivy
โ
โผ push to main (success)
CD (cd.yml)
โโโ deploy-staging # automatic
โโโ await-approval # manual reviewer
โโโ quality-gate # ๐ฆ all gates evaluated here
โโโ deploy-production # runs ONLY if quality-gate passesArtifacts are saved for 90 days: quality-gate-report-{service}-{run_id}.json