CI/CD from Dev to QA to UAT to Production: Jenkins, SonarQube and Security Gates
The delivery flow I prefer
In enterprise programs I normally structure promotion as:
Developer
|
Pull Request
|
Build + Unit Test
|
Static Analysis
|
Security Scan
|
Immutable Artifact
|
DEV
|
QA
|
UAT
|
PRODThe most important rule:
build once, promote the same artifact.
I do not rebuild different source for UAT and Production.
Jenkins pipeline skeleton
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build & Unit Test') {
steps {
sh 'npm ci'
sh 'npm test -- --runInBand'
sh 'npm run build'
}
}
stage('Quality') {
steps {
sh '''
sonar-scanner \
-Dsonar.projectKey=booking-service
'''
}
}
stage('Security') {
steps {
sh '''
trivy fs \
--exit-code 1 \
--severity CRITICAL \
.
'''
}
}
stage('Container') {
steps {
sh '''
docker build \
-t registry/booking:${GIT_COMMIT} .
docker push \
registry/booking:${GIT_COMMIT}
'''
}
}
stage('Deploy DEV') {
steps {
sh './deploy.sh dev ${GIT_COMMIT}'
}
}
stage('QA Gate') {
steps {
input 'Promote to QA?'
}
}
stage('Deploy QA') {
steps {
sh './deploy.sh qa ${GIT_COMMIT}'
}
}
stage('UAT Gate') {
steps {
input 'Promote to UAT?'
}
}
stage('Deploy UAT') {
steps {
sh './deploy.sh uat ${GIT_COMMIT}'
}
}
stage('PROD Gate') {
steps {
input 'Production approval?'
}
}
stage('Deploy PROD') {
steps {
sh './deploy.sh prod ${GIT_COMMIT}'
}
}
}
}Actual approvals can integrate change-management systems, but the conceptual control remains.
Quality gate
I use SonarQube for trends such as:
new-code bugs
vulnerabilities
maintainability
duplication
coverageI care more about new code quality than forcing a legacy 2-million-line system to reach an arbitrary coverage percentage overnight.
Security gate
Examples:
- dependency/SCA scan;
- container image scan;
- secret scan;
- SAST;
- IaC scan;
- license policy.
Critical findings can block promotion.
Database deployment
Database schema has its own controlled step.
I require:
migration reviewed
backward compatible
expected runtime estimated
rollback/roll-forward documented
backup/recovery understoodApplication and DB deployment order depends on expand-contract.
Configuration
I promote the same image with environment configuration:
DEV ConfigMap/Secret
QA ConfigMap/Secret
UAT ConfigMap/Secret
PROD ConfigMap/SecretSecrets do not live in Jenkinsfiles.
Post-deploy verification
Production deployment is not complete when Kubernetes says pods are running.
I verify:
version endpoint
readiness
synthetic business transaction
error rate
latency
Kafka lag
DB pool
external dependency healthRollback / roll-forward
For application-only defects:
rollback imageFor schema/data behavior:
often roll forwardbecause reversing data migrations can be more dangerous.
Production checklist
- Build once.
- Immutable artifact tag/digest.
- Unit/integration tests.
- Sonar quality gate.
- Security scan.
- Environment configuration externalized.
- Secrets outside pipeline files.
- DB migration stage.
- Approval gates where required.
- Automated post-deploy verification.
- Version-specific telemetry.
- Tested rollback/roll-forward.
FAQ
Why not rebuild per environment?
Because it means QA/UAT tested a different artifact from Production.
Should production be fully automatic?
It depends on risk/governance. The deployment mechanics should be automated even if approval is manual.
How much test coverage?
I use coverage as one signal. Critical business logic and new code deserve stronger coverage than chasing a global percentage without risk context.
Related architecture guides
- [Production Deployment Patterns I Have Used](/articles/production-deployment-patterns-blue-green-canary-rolling)
- [Rolling Deployment](/articles/rolling-deployment-kubernetes-production)
-
Architect's final take
A production pipeline is an executable release policy. It should prove what artifact was built, what checks passed, who approved it and what actually reached production.
Your feedback helps prioritize deeper technical content.






