Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 105 additions & 23 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: build Maven
name: CI/CD Pipeline with DevSecOps

on:
pull_request:
Expand All @@ -10,34 +10,101 @@ on:
- reopened

jobs:
test_and_build:
# Build and Test
build_and_test:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: '23'
distribution: 'temurin'

- name: Build and Test with Maven
run: |
mvn clean install
mvn test

- name: Create JAR File
run: mvn clean package

- name: Upload Build Artifact
uses: actions/upload-artifact@v3
with:
name: build-artifact
path: target/*.jar

static_code_analysis:
runs-on: ubuntu-latest
needs: build_and_test
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Checkout Repository
uses: actions/checkout@v4

- name: Set up Java 23
uses: actions/setup-java@v4
with:
java-version: '23'
distribution: 'temurin'
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '23'

- name: Install dependencies and run tests
run: mvn clean install
- name: Build the project
run: mvn clean install -DskipTests

- name: Run tests with Maven
run: mvn test
- name: Cache SonarQube packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=yashsahsani_Learning-SpringBoot

- name: create jar file
run: mvn clean package

create-docker:

# Security Scanning
security_scanning:
runs-on: ubuntu-latest
needs: test_and_build
needs: build_and_test
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Snyk Dependency Scan
uses: snyk/actions/setup@master
- name: Run Snyk Test
run: snyk test --all-projects --severity-threshold=high
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

- name: Monitor the project on Snyk
run: snyk monitor --all-projects
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

- name: Scan for Vulnerable Dependencies with Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
ignore-unfixed: true

# Docker Image Build and Scan
docker_build_and_scan:
runs-on: ubuntu-latest
needs: [build_and_test, security_scanning,static_code_analysis]
steps:
- name: Checkout the repository
- name: Checkout Repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
Expand All @@ -48,9 +115,24 @@ jobs:
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build Docker image

- name: Build Docker Image
run: docker build -t ${{ secrets.DOCKER_USERNAME }}/spring-learning:${{ github.sha }} .

- name: Push Docker image to Docker Hub
run: |
docker push ${{ secrets.DOCKER_USERNAME }}/spring-learning:${{ github.sha }}
# - name: Snyk Docker Image Scan
# uses: snyk/actions/docker@master
# with:
# image: ${{ secrets.DOCKER_USERNAME }}/spring-learning:${{ github.sha }}
# args: --severity-threshold=high
# env:
# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

- name: Scan Docker Image with Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ secrets.DOCKER_USERNAME }}/spring-learning:${{ github.sha }}
severity: 'CRITICAL,HIGH'
ignore-unfixed: true

- name: Push Docker Image to Docker Hub
run: docker push ${{ secrets.DOCKER_USERNAME }}/spring-learning:${{ github.sha }}
37 changes: 37 additions & 0 deletions .github/workflows/sonar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: SonarQube
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
name: Build and analyze
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 23
uses: actions/setup-java@v4
with:
java-version: 23
distribution: 'temurin' # Alternative distribution options are available.
- name: Cache SonarQube packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=yashsahsani_Learning-SpringBoot
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ COPY . .
RUN mvn clean package

# Stage 2: Run the application
FROM openjdk:23-jdk-slim
FROM openjdk:24-jdk-slim
WORKDIR /app
COPY --from=builder /app/target/learning-spring.jar app.jar
EXPOSE 8080
Expand Down
8 changes: 8 additions & 0 deletions kubernetes/configMap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: spring-boot-app-config
namespace: spring
data:
DATASOURCE_URL: jdbc:mysql://db-service:3306/learning_spring
SPRING_PROFILES_ACTIVE: prod
21 changes: 12 additions & 9 deletions kubernetes/db-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
labels:
app: db
spec:
replicas: 1
replicas: 2
selector:
matchLabels:
app: db
Expand All @@ -20,16 +20,19 @@ spec:
image: mysql:latest
env:
- name: MYSQL_ROOT_PASSWORD
value: "prodroot"
valueFrom:
secretKeyRef:
name: db-secret
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE
value: "learning_spring"
ports:
- containerPort: 3306
# volumeMounts:
# - name: mysql-data
# mountPath: /var/lib/mysql
# volumes:
# - name: mysql-data
# persistentVolumeClaim:
# claimName: mysql-pvc
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc

8 changes: 8 additions & 0 deletions kubernetes/db-secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: db-secrets
namespace: spring
type: Opaque
data:
MYSQL_ROOT_PASSWORD: cGFzc3dvcmQ=
9 changes: 9 additions & 0 deletions kubernetes/secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: spring-boot-app-secret
namespace: spring
type: Opaque
data:
DATASOURCE_USERNAME: cm9vdA==
DATASOURCE_PASSWORD: cHJvZHJvb3Q=
29 changes: 23 additions & 6 deletions kubernetes/spring-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
labels:
app: spring-boot-app
spec:
replicas: 1
replicas: 4
selector:
matchLabels:
app: spring-boot-app
Expand All @@ -18,14 +18,31 @@ spec:
containers:
- name: spring-boot-app
image: yashsahsani/spring-learning:latest
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
allowPrivilegeEscalation: false
env:
- name: DATASOURCE_URL
value: jdbc:mysql://db-service:3306/learning_spring
valueFrom:
configMapKeyRef:
name: spring-boot-app-config
key: DATASOURCE_URL
- name: DATASOURCE_USERNAME
value: root
valueFrom:
secretKeyRef:
name: spring-boot-app-secret
key: DATASOURCE_USERNAME
- name: DATASOURCE_PASSWORD
value: prodroot
valueFrom:
secretKeyRef:
name: spring-boot-app-secret
key: DATASOURCE_PASSWORD
- name: SPRING_PROFILES_ACTIVE
value: prod
valueFrom:
configMapKeyRef:
name: spring-boot-app-config
key: SPRING_PROFILES_ACTIVE
ports:
- containerPort: 8080
- containerPort: 8080

13 changes: 10 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
</scm>
<properties>
<java.version>23</java.version>
<sonar.organization>yashsahsani</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
</properties>
<distributionManagement>
<repository>
Expand All @@ -37,15 +39,20 @@
</distributionManagement>
<dependencies>

<dependency>
<!-- <dependency>
<groupId>dev.fastball</groupId>
<artifactId>fastball-runtime-spring-devtools</artifactId>
<version>0.4.0</version>
</dependency>

</dependency> -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.1</version>
</dependency>

<dependency>
Expand Down
5 changes: 5 additions & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sonar.projectKey=yashsashani_Learning-SpringBoot
sonar.organization=yashsahsani
sonar.host.url=https://sonarcloud.io
sonar.sources=.
sonar.java.binaries=target/classes
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public String updateDepartmentById(@PathVariable("id") Long departmentId,@Valid
}

@DeleteMapping("/deleteDepartment/{id}")
public String deleteMethodName(@PathVariable String id) {
public String deleteMethodName(@Valid @PathVariable String id) {

return departmentService.deleteDepartment(id);
}

Expand Down
Loading