Skip to content

Commit 122f90e

Browse files
authored
Revamp CI/CD workflow for Reservation Service
Updated CI/CD workflow for Reservation Service to include code quality checks, build, Docker image creation, security scans, and deployment steps.
1 parent c0c779b commit 122f90e

File tree

1 file changed

+210
-31
lines changed

1 file changed

+210
-31
lines changed

.github/workflows/ci-cd.yml

Lines changed: 210 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,222 @@
1-
# Multi-stage Dockerfile for Reservation Service
1+
name: Reservation Service CI/CD
22

3-
# Stage 1: Build stage
4-
FROM maven:3.9-eclipse-temurin-17 AS build
5-
WORKDIR /app
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
69

7-
# Copy Maven wrapper and pom.xml first for dependency caching
8-
COPY mvnw .
9-
COPY .mvn .mvn
10-
COPY pom.xml .
10+
env:
11+
JAVA_VERSION: '17'
12+
MAVEN_CLI_OPTS: '-B --no-transfer-progress'
13+
DOCKER_IMAGE_NAME: reservation-service
14+
REGISTRY: docker.io
1115

12-
# Download dependencies (cached if pom.xml hasn't changed)
13-
RUN mvn dependency:go-offline -B
16+
jobs:
17+
# Job 1: Code Quality & Security
18+
code-quality:
19+
name: Code Quality & Security Checks
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0 # Shallow clones should be disabled for better analysis
1427

15-
# Copy source code
16-
COPY src ./src
28+
- name: Set up JDK ${{ env.JAVA_VERSION }}
29+
uses: actions/setup-java@v4
30+
with:
31+
java-version: ${{ env.JAVA_VERSION }}
32+
distribution: 'temurin'
33+
cache: 'maven'
1734

18-
# Build the application (skip tests for faster builds)
19-
RUN mvn clean package -DskipTests
35+
- name: Cache SonarCloud packages
36+
uses: actions/cache@v3
37+
with:
38+
path: ~/.sonar/cache
39+
key: ${{ runner.os }}-sonar
40+
restore-keys: ${{ runner.os }}-sonar
2041

21-
# Stage 2: Runtime stage
22-
FROM eclipse-temurin:17-jre
23-
WORKDIR /app
42+
- name: Run code style checks
43+
run: mvn ${{ env.MAVEN_CLI_OPTS }} checkstyle:check
44+
continue-on-error: true
2445

25-
# Add non-root user for security
26-
RUN groupadd -r spring && useradd -r -g spring spring
27-
USER spring:spring
46+
- name: Run SpotBugs analysis
47+
run: mvn ${{ env.MAVEN_CLI_OPTS }} compile spotbugs:check
48+
continue-on-error: true
2849

29-
# Copy the built artifact from build stage
30-
COPY --from=build /app/target/reservation-service-*.jar app.jar
50+
# Job 2: Build
51+
build:
52+
name: Build
53+
runs-on: ubuntu-latest
54+
needs: code-quality
3155

32-
# Expose the application port
33-
EXPOSE 8084
56+
steps:
57+
- name: Checkout code
58+
uses: actions/checkout@v4
3459

35-
# Set JVM options for containerized environment
36-
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"
60+
- name: Set up JDK ${{ env.JAVA_VERSION }}
61+
uses: actions/setup-java@v4
62+
with:
63+
java-version: ${{ env.JAVA_VERSION }}
64+
distribution: 'temurin'
65+
cache: 'maven'
3766

38-
# Health check
39-
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
40-
CMD curl -f http://localhost:8084/actuator/health || exit 1
67+
- name: Build with Maven
68+
run: mvn ${{ env.MAVEN_CLI_OPTS }} clean compile
4169

42-
# Run the application
43-
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
70+
- name: Package application
71+
run: mvn ${{ env.MAVEN_CLI_OPTS }} package -DskipTests
72+
73+
- name: Upload build artifact
74+
uses: actions/upload-artifact@v4
75+
with:
76+
name: reservation-service-jar
77+
path: target/*.jar
78+
retention-days: 5
79+
80+
# Job 3: Docker Build & Push
81+
docker-build-push:
82+
name: Build & Push Docker Image
83+
runs-on: ubuntu-latest
84+
needs: build
85+
if: github.event_name == 'push'
86+
permissions:
87+
contents: read
88+
packages: write
89+
90+
steps:
91+
- name: Checkout code
92+
uses: actions/checkout@v4
93+
94+
- name: Set up Docker Buildx
95+
uses: docker/setup-buildx-action@v3
96+
97+
- name: Log in to Docker Hub
98+
uses: docker/login-action@v3
99+
with:
100+
username: ${{ secrets.DOCKER_HUB_USERNAME }}
101+
password: ${{ secrets.DOCKER_HUB_TOKEN }}
102+
103+
- name: Extract metadata for Docker
104+
id: meta
105+
uses: docker/metadata-action@v5
106+
with:
107+
images: ${{ secrets.DOCKER_HUB_USERNAME }}/${{ env.DOCKER_IMAGE_NAME }}
108+
tags: |
109+
type=ref,event=branch
110+
type=ref,event=pr
111+
type=sha,prefix={{branch}}-
112+
type=semver,pattern={{version}}
113+
type=semver,pattern={{major}}.{{minor}}
114+
type=raw,value=latest,enable={{is_default_branch}}
115+
116+
- name: Build and push Docker image
117+
uses: docker/build-push-action@v5
118+
with:
119+
context: .
120+
file: ./Dockerfile
121+
push: true
122+
tags: ${{ steps.meta.outputs.tags }}
123+
labels: ${{ steps.meta.outputs.labels }}
124+
cache-from: type=gha
125+
cache-to: type=gha,mode=max
126+
platforms: linux/amd64,linux/arm64
127+
128+
- name: Generate SBOM
129+
uses: anchore/sbom-action@v0
130+
with:
131+
image: ${{ secrets.DOCKER_HUB_USERNAME }}/${{ env.DOCKER_IMAGE_NAME }}:${{ github.sha }}
132+
format: spdx-json
133+
output-file: sbom.spdx.json
134+
135+
- name: Upload SBOM
136+
uses: actions/upload-artifact@v4
137+
with:
138+
name: sbom
139+
path: sbom.spdx.json
140+
141+
# Job 4: Security Scan
142+
security-scan:
143+
name: Security Vulnerability Scan
144+
runs-on: ubuntu-latest
145+
needs: docker-build-push
146+
if: github.event_name == 'push'
147+
permissions:
148+
contents: read
149+
security-events: write
150+
151+
steps:
152+
- name: Checkout code
153+
uses: actions/checkout@v4
154+
155+
- name: Log in to Docker Hub
156+
uses: docker/login-action@v3
157+
with:
158+
username: ${{ secrets.DOCKER_HUB_USERNAME }}
159+
password: ${{ secrets.DOCKER_HUB_TOKEN }}
160+
161+
- name: Run Trivy vulnerability scanner
162+
uses: aquasecurity/trivy-action@master
163+
with:
164+
image-ref: ${{ secrets.DOCKER_HUB_USERNAME }}/${{ env.DOCKER_IMAGE_NAME }}:${{ github.sha }}
165+
format: 'sarif'
166+
output: 'trivy-results.sarif'
167+
severity: 'CRITICAL,HIGH'
168+
169+
- name: Upload Trivy results to GitHub Security
170+
uses: github/codeql-action/upload-sarif@v3
171+
if: always()
172+
with:
173+
sarif_file: 'trivy-results.sarif'
174+
175+
- name: Dependency Check
176+
uses: dependency-check/Dependency-Check_Action@main
177+
with:
178+
project: 'reservation-service'
179+
path: '.'
180+
format: 'HTML'
181+
args: >
182+
--failOnCVSS 7
183+
--enableRetired
184+
185+
- name: Upload Dependency Check report
186+
uses: actions/upload-artifact@v4
187+
if: always()
188+
with:
189+
name: dependency-check-report
190+
path: reports/
191+
192+
# Job 5: Deploy to Development
193+
deploy-dev:
194+
name: Deploy to Development
195+
runs-on: ubuntu-latest
196+
needs: [docker-build-push, security-scan]
197+
if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/dev-update'
198+
environment:
199+
name: development
200+
url: https://dev-reservation-service.exhibitflow.com
201+
202+
steps:
203+
- name: Checkout code
204+
uses: actions/checkout@v4
205+
206+
- name: Deploy to Development Server
207+
uses: appleboy/ssh-action@v1.0.0
208+
with:
209+
host: ${{ secrets.DEV_SERVER_HOST }}
210+
username: ${{ secrets.DEV_SERVER_USER }}
211+
key: ${{ secrets.DEV_SERVER_SSH_KEY }}
212+
port: ${{ secrets.DEV_SERVER_PORT }}
213+
script: |
214+
cd /opt/reservation-service
215+
docker compose pull
216+
docker compose up -d
217+
docker system prune -f
218+
219+
- name: Verify deployment
220+
run: |
221+
sleep 10
222+
curl -f ${{ secrets.DEV_SERVER_URL }}/actuator/health || exit 1

0 commit comments

Comments
 (0)