Week 10 — CI/CD Pipeline + Basic Monitoring
The textbook for this week
The pipeline material lives in the CI/CD — GitHub Actions track: Anatomy for Days 1–2, Advanced when the basic pipeline works. Work the track; use this page as the weekly checklist.
Why This Week Matters
Deploying manually is amateur. Every real company has a pipeline: push code → tests run automatically → if tests pass → deploy automatically. You need to understand this and have it set up.
Daily Breakdown
Day 1-2: GitHub Actions CI Pipeline
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: splitwise_test
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'maven'
- name: Run tests
env:
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/splitwise_test
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: postgres
run: ./mvnw verify
- name: Build Docker image
run: docker build -t splitwise-api .
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
# Deploy step depends on your cloud provider
# Railway auto-deploys from GitHub, so this may not be needed
What this does:
- Every push/PR → runs your tests against a real PostgreSQL (not mocks!)
- If tests pass → builds Docker image
- If on main branch → deploys
Day 3: Monitoring Basics
The three pillars of observability:
| Pillar | What | Tool |
|---|---|---|
| Logs | What happened (text records) | Structured logging (SLF4J + Logback) |
| Metrics | How much/how fast (numbers) | Micrometer + Prometheus |
| Traces | Request journey across services | OpenTelemetry (later) |
Add Prometheus metrics:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
management.endpoints.web.exposure.include=health,info,prometheus
Now GET /actuator/prometheus exposes metrics like:
http_server_requests_seconds_count— how many requestshttp_server_requests_seconds_sum— total time spentjvm_memory_used_bytes— memory usagehikaricp_connections_active— database connection pool status
Custom business metrics:
@Service
public class ExpenseService {
private final Counter expenseCounter;
public ExpenseService(MeterRegistry registry) {
this.expenseCounter = Counter.builder("expenses.created")
.tag("type", "split")
.description("Number of expenses created")
.register(registry);
}
public ExpenseDTO createExpense(...) {
// ... business logic ...
expenseCounter.increment();
return dto;
}
}
Day 4: Uptime Monitoring
Free uptime monitoring services:
- UptimeRobot (free, 50 monitors) — pings your health endpoint every 5 min
- Better Stack (free tier) — better UI, incident alerts
Set up UptimeRobot to monitor:
https://your-app.up.railway.app/actuator/health— every 5 minutes- Get email alerts when your app goes down
This gives you a number for your resume: “99.9% uptime over 30 days”
Day 5: API Documentation with Swagger
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
Visit http://localhost:8080/swagger-ui.html — auto-generated API docs.
Add annotations for clarity:
@Operation(summary = "Create a new expense in a group")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Expense created"),
@ApiResponse(responseCode = "400", description = "Invalid input"),
@ApiResponse(responseCode = "404", description = "Group not found")
})
@PostMapping
public ResponseEntity<ApiResponse<ExpenseDTO>> createExpense(...) { }
Weekend: DSA + Review
- CI pipeline running on every push
- Swagger docs accessible on deployed URL
- UptimeRobot monitoring your health endpoint
- DSA: DSA 08 — Trees, BFS & DFS — module + 5-6 problems from its list
Resources
| What | Where | Time |
|---|---|---|
| GitHub Actions | docs.github.com/actions quickstart | 30 min |
| Spring Boot + Prometheus | Baeldung “Spring Boot Actuator + Prometheus” | 20 min |
| UptimeRobot | uptimerobot.com | 10 min setup |
| SpringDoc OpenAPI | springdoc.org | 15 min |