This guide explains the Continuous Integration and Continuous Deployment (CI/CD) pipeline for the Snipper application using GitHub Actions.
The CI/CD pipeline consists of four main workflows:
- Backend CI - Tests and builds the Spring Boot backend
- Frontend CI - Tests and builds the React frontend
- Docker Build - Builds and pushes Docker images
- Deploy - Deploys to Kubernetes cluster
Triggers:
- Push to
mainordevelopbranches (backend changes) - Pull requests to
mainordevelop(backend changes)
Jobs:
- Sets up MySQL service container
- Runs Maven tests with coverage
- Generates test reports
- Uploads coverage to Codecov
- Builds the application with Maven
- Creates JAR artifact
- Uploads artifact for later use
- Runs SonarCloud analysis
- Checks code quality metrics
- Reports issues and technical debt
Required Secrets:
SONAR_TOKEN- SonarCloud authentication token
Triggers:
- Push to
mainordevelopbranches (frontend changes) - Pull requests to
mainordevelop(frontend changes)
Jobs:
- Installs npm dependencies
- Runs ESLint for code linting
- Executes Jest tests with coverage
- Uploads coverage to Codecov
- Builds production React application
- Optimizes bundle size
- Uploads build artifact
- Runs SonarCloud analysis for frontend
- Checks code quality and security
Required Secrets:
SONAR_TOKEN- SonarCloud authentication token
Triggers:
- Push to
mainbranch - Git tags (e.g.,
v1.0.0) - Manual workflow dispatch
Jobs:
- Builds multi-platform Docker image (amd64, arm64)
- Pushes to GitHub Container Registry
- Tags with version, branch, and SHA
- Builds multi-platform Docker image
- Pushes to GitHub Container Registry
- Tags appropriately
- Scans images with Trivy
- Uploads vulnerability reports
- Fails on critical vulnerabilities
Image Tags:
latest- Latest main branch buildv1.0.0- Semantic version tagsmain-abc123- Branch with commit SHAstaging- Staging environment
Triggers:
- Successful completion of Docker Build workflow
- Manual workflow dispatch with environment selection
Jobs:
- Configures kubectl with cluster credentials
- Creates/updates namespace
- Deploys ConfigMaps and Secrets
- Deploys MySQL StatefulSet
- Updates Backend deployment
- Updates Frontend deployment
- Applies HPA configuration
- Runs smoke tests
- Sends deployment notifications
Required Secrets:
KUBE_CONFIG- Base64 encoded kubeconfig fileMYSQL_ROOT_PASSWORD- MySQL root passwordMYSQL_USER- MySQL usernameMYSQL_PASSWORD- MySQL passwordJWT_SECRET- JWT signing secretSLACK_WEBHOOK- Slack webhook URL (optional)
Navigate to your repository → Settings → Secrets and variables → Actions
Add the following secrets:
# SonarCloud
SONAR_TOKEN=your-sonarcloud-token
# Kubernetes
KUBE_CONFIG=base64-encoded-kubeconfig
# Database
MYSQL_ROOT_PASSWORD=strong-root-password
MYSQL_USER=snipper_user
MYSQL_PASSWORD=strong-user-password
# Application
JWT_SECRET=your-jwt-secret-min-256-bits
# Notifications (optional)
SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL# Get your kubeconfig
cat ~/.kube/config | base64 -w 0
# Or for specific context
kubectl config view --minify --flatten | base64 -w 0Add the output as KUBE_CONFIG secret.
- Go to SonarCloud
- Import your repository
- Generate a token
- Add token as
SONAR_TOKENsecret - Update organization in workflow files
The workflows use GitHub Container Registry (ghcr.io) by default.
Permissions:
- Ensure GitHub Actions has write access to packages
- Repository → Settings → Actions → General → Workflow permissions
- Select "Read and write permissions"
Use act to test workflows locally:
# Install act
brew install act # macOS
choco install act # Windows
# Run backend CI
act -W .github/workflows/backend-ci.yml
# Run with secrets
act -W .github/workflows/backend-ci.yml --secret-file .secrets-
Push to main/develop:
git push origin main
- Triggers Backend CI and/or Frontend CI
- If main branch, triggers Docker Build
- Docker Build success triggers Deploy
-
Create Pull Request:
gh pr create --base main --head feature-branch
- Triggers CI workflows for changed components
- Shows status checks in PR
-
Create Release Tag:
git tag -a v1.0.0 -m "Release v1.0.0" git push origin v1.0.0- Triggers Docker Build with version tags
-
Manual Deployment:
- Go to Actions → Deploy to Kubernetes
- Click "Run workflow"
- Select environment (staging/production)
- Click "Run workflow"
-
Manual Docker Build:
- Go to Actions → Docker Build and Push
- Click "Run workflow"
- Select branch
- Click "Run workflow"
# Using GitHub CLI
gh run list
gh run view <run-id>
gh run watch <run-id># View logs for specific run
gh run view <run-id> --log
# View logs for specific job
gh run view <run-id> --log --job=<job-id>Add to README.md:


- Namespace:
snipper-staging - Trigger: Automatic on main branch
- Image Tag:
staging - Purpose: Pre-production testing
- Namespace:
snipper-prod - Trigger: Manual approval required
- Image Tag:
latestor version tag - Purpose: Live production environment
# Rollback to previous version
kubectl rollout undo deployment/backend -n snipper-prod
kubectl rollout undo deployment/frontend -n snipper-prod
# Rollback to specific revision
kubectl rollout undo deployment/backend --to-revision=2 -n snipper-prod
# Check rollout history
kubectl rollout history deployment/backend -n snipper-prod- Go to Actions → Deploy to Kubernetes
- Find successful previous deployment
- Click "Re-run all jobs"
# Run tests locally
cd backend
mvn clean test
# Check MySQL connection
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootpassword mysql:8.0
mvn test# Run tests locally
cd frontend
npm test
# Run with coverage
npm test -- --coverage# Test Docker build locally
docker build -t test-backend ./backend
docker build -t test-frontend ./frontend
# Check build logs
docker build --progress=plain -t test-backend ./backendIncrease Docker memory in workflow:
- name: Build with Maven
run: mvn clean package -DskipTests
env:
MAVEN_OPTS: "-Xmx2048m"# Verify kubeconfig
echo $KUBE_CONFIG | base64 -d > /tmp/config
kubectl --kubeconfig=/tmp/config get nodes
# Test connection
kubectl cluster-info# Check pod status
kubectl get pods -n snipper-prod
kubectl describe pod <pod-name> -n snipper-prod
kubectl logs <pod-name> -n snipper-prod
# Check events
kubectl get events -n snipper-prod --sort-by='.lastTimestamp'# Verify image exists
docker pull ghcr.io/username/repo/backend:latest
# Check image pull secret
kubectl get secrets -n snipper-prod-
Branch Protection
- Require status checks to pass
- Require pull request reviews
- Require up-to-date branches
-
Secrets Management
- Rotate secrets regularly
- Use environment-specific secrets
- Never commit secrets to repository
-
Testing
- Maintain high test coverage (>80%)
- Run tests before pushing
- Fix failing tests immediately
-
Deployment
- Deploy to staging first
- Run smoke tests after deployment
- Monitor application after deployment
- Have rollback plan ready
-
Monitoring
- Set up alerts for workflow failures
- Monitor deployment success rate
- Track deployment frequency
- Review failed workflows promptly
-
Documentation
- Document workflow changes
- Keep secrets list updated
- Document deployment procedures
- Maintain runbooks for common issues
Already implemented in workflows:
- Maven dependencies cached
- npm dependencies cached
- Docker layer caching enabled
Workflows run jobs in parallel when possible:
- Test, Build, and Code Quality run in parallel
- Backend and Frontend workflows run independently
Workflows only run when relevant files change:
paths:
- 'backend/**'
- '.github/workflows/backend-ci.yml'- Trivy scans Docker images
- Dependabot updates dependencies
- SonarCloud checks for vulnerabilities
GitHub automatically scans for exposed secrets.
Consider signing Docker images:
- name: Sign image
uses: sigstore/cosign-installer@main
- run: cosign sign ghcr.io/username/repo/backend:latestTrack these metrics:
- Build success rate
- Average build time
- Deployment frequency
- Mean time to recovery (MTTR)
- Change failure rate
Use GitHub Insights → Actions to view metrics.