A Java-based web application built with Spring MVC, backed by MySQL, Memcached, RabbitMQ, and Elasticsearch. The project includes a full CI/CD pipeline using GitHub Actions, SonarQube, Amazon ECR, and Helm GitOps with a manual approval gate before deploying to Kubernetes.
- Java 8 — Spring MVC, Spring Security, Spring Data JPA, Hibernate
- MySQL — primary database
- Memcached — caching layer
- RabbitMQ — message broker
- Elasticsearch — search engine
- Maven — build and dependency management
- Docker — containerization (multistage build)
- Amazon ECR — container image registry
- SonarQube — code quality and static analysis
- Helm — Kubernetes deployment via GitOps
├── .github/workflows/ci.yml # GitHub Actions CI/CD pipeline
├── Docker-files/
│ ├── app/multistage/Dockerfile # Multistage Docker build for the app
│ ├── db/Dockerfile # MySQL container
│ └── web/Dockerfile # Nginx reverse proxy
├── src/
│ ├── main/java # Application source code
│ ├── main/resources # Config files
│ └── test/java # Unit tests
├── pom.xml # Maven build config
└── sonar-project.properties # SonarQube project config
The pipeline is defined in .github/workflows/ci.yml and has 4 jobs:
- Checks out source code
- Sets up Java 21 with Maven and SonarQube cache
- Runs
mvn clean verify checkstyle:checkstyle— compiles, runs unit tests, packages the WAR, and generates a Checkstyle report attarget/checkstyle-result.xml - Runs SonarQube scan — picks up test coverage (JaCoCo), Checkstyle violations, and code smells
- Evaluates the SonarQube quality gate — fails the pipeline if quality standards are not met
- Authenticates to AWS via OIDC (no long-lived credentials)
- Logs in to Amazon ECR
- Builds the Docker image using the multistage Dockerfile
- Scans the image with Trivy for CRITICAL and HIGH vulnerabilities (non-blocking,
exit-code: 0) - Pushes the image to ECR with two tags:
<commit-sha>andlatest - Uploads the Trivy scan report as a pipeline artifact (retained for 14 days)
This job does not directly update the Helm values.yaml on main. Instead it introduces a manual approval step via a Pull Request:
- Checks out the Helm GitOps repository on
main - Creates or resets a branch called
helm-approvalfrommain - Updates
helm/vprofile/values.yamlwith the new image registry and tag usingyq - Commits and pushes the change to the
helm-approvalbranch - Opens a Pull Request from
helm-approval→mainin the Helm repo (skips if one already exists) - Sends a Slack notification with the PR status
A team member must review and merge the PR in the Helm repository before the new image is applied to the Kubernetes cluster. This gives you a manual gate between CI and deployment.
- Sends a Slack notification with the overall pipeline result (success or failure)
- Skips silently if
SLACK_WEBHOOKis not configured
PR to main → build job (test, checkstyle, sonarqube)
↓
Merge to main → docker-build-push (build, scan, push to ECR)
↓
update-helm (create helm-approval branch + open PR)
↓
Manual review & merge PR in Helm repo
↓
ArgoCD/Flux picks up values.yaml change → deploys
| Secret | Description |
|---|---|
SONAR_TOKEN |
SonarQube authentication token |
CI_AWS_ROLE_ARN |
AWS IAM role ARN for OIDC authentication |
GITOPS_PAT |
GitHub Personal Access Token for pushing to the Helm repo and creating PRs |
SLACK_WEBHOOK |
Slack incoming webhook URL (optional) |
| Variable | Description |
|---|---|
SONAR_HOST_URL |
SonarQube server URL |
AWS_REGION |
AWS region (e.g. us-east-1) |
ECR_REPOSITORY |
ECR repository name |
HELM_REPO_NAME |
Name of the Helm GitOps repository |
- An IAM role with ECR push permissions, configured for GitHub Actions OIDC federation
- An ECR repository created in your AWS account
- A running SonarQube instance
- Project key:
vprofile-java99(as defined insonar-project.properties)
- The
GITOPS_PATtoken must havereposcope to create branches and open PRs in the Helm repository
mvn clean verifymvn -B -U clean verify checkstyle:checkstylemvn jetty:runApp will be available at http://localhost:8080
| Branch | Pipeline Behaviour |
|---|---|
feature/* |
No pipeline triggered |
PR → main |
Runs build job only (test, checkstyle, sonarqube) |
push to main |
Runs docker build/push → creates Helm approval PR → notify |