Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@ node_modules/
.classpath
.project
.settings/
jenkins/jenkins_home/
74 changes: 74 additions & 0 deletions README(2).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# ENSF 400 - Winter 2025 - Course Project

## Project Overview

In this project, you will work based on a software project by incorporating/extending a complete CI/CD (Continuous Integration/Continuous Deployment) pipeline. This is based on an open-source sample application: https://github.com/7ep/demo

This project can also be any application that requires the project of build, test, and deployment.
You will leverage GitHub for source control, Docker for containerizing your application, and a CI/CD tool (Jenkins) to automate the build, testing, and verification process. The goal is to validate every code change automatically through container builds, unit tests, code quality checks, and end-to-end functional tests.


## Project Requirements

By the end of this project, your group must deliver the following:

1. Manage your project on GitHub and follow proper Git workflows (branching, pull requests, code reviews). Document the process of how you use Git workflows to collaborate with your team members.

1. Containerize your application for builds and deployments. Upload and download your container images to a public or private image repository (e.g., Docker Hub or GitHub Container Registry). Ensure a container image is built with unique build tag(s) matching the triggering commit from any branch.

1. Set up an automated CI/CD with Jenkins in a Codespace environment. Configure the pipeline to trigger upon pull requests merging changes into the main branch.

1. Document the CI/CD process and provide clear instructions on replicating your environment. Submit a video demo at the end of the project.

### Existing Pipelines

You will also demonstrate the delivery of the following process and artifacts that come with the project.

1. Run static analysis quality-gating using SonarQube
1. Performance testing with Jmeter
1. Security analysis with OWASP's "DependencyCheck"
1. Build Javadocs
___________________________________________________________________________________________________________________________________________________

# Organization of our ENSF 400 CI/CD Project

## Team Members

- Josral Frederick UCID: 30195360
- Muhammad Aun Raza My UCID: 30172183
- Natnael Tekli UCID: 30171167
- Jaden Chow UCID: 30173676

## Project Description
The main objective in this project is to create software that incorporates/extends a complete CI/CD
(Continuous Integration/Continuous Deployment) pipeline.

## Git Workflow
Our team follows a structured Git workflow to manage our project efficiently on GitHub.

We begin by cloning the repository using git clone <repository_url>. Before making changes, we create a new feature branch with git checkout -b feature/feature-name to keep our work organized.

Once changes are made, we stage and commit them using git add . and git commit -m "Description of changes", ensuring clear commit messages.

To keep our branch up-to-date, we sync it with the main branch by switching to main, pulling the latest changes (git pull origin main), and merging them into our feature branch (git merge main). If merge conflicts arise, we resolve them before proceeding.

After finalizing our changes, we push our branch to the remote repository using git push origin feature/feature-name. We then open a Pull Request (PR) on GitHub, providing a description of our modifications.

Team members participate in a code review process, leaving feedback and suggesting necessary improvements. Once approved, the PR is merged into main, typically by a team lead or someone with write access.

After merging, we delete the feature branch both locally (git branch -d feature/feature-name) and remotely (git push origin --delete feature/feature-name). To stay updated, we sync our local repository with the latest changes using git pull origin main.

We follow GitFlow best practices, using descriptive branch names (e.g., feature/login-page, bugfix/error-handling) and ensuring every change is reviewed via a PR before merging into main.
External contributors fork the repository, create a new branch, make their changes, and open a PR to contribute to the project.

This workflow ensures a structured and collaborative development process, keeping our codebase clean and organized.

## Containerization

To containerize our application, we use Docker and Docker Hub. After creating and reviewing the Dockerfile as a team, we build the Docker image with a unique tag matching the commit hash or branch name. This ensures traceability by linking each image to the exact code version it was built from. We generate the commit hash using COMMIT_HASH=$(git rev-parse --short HEAD), build the image with docker build -t natnaelt2/ensf400-demo:$COMMIT_HASH ., and push it to Docker Hub using docker push natnaelt2/ensf400-demo:$COMMIT_HASH. This process guarantees consistency and simplifies tracking across deployments.

To deploy the application, we pull the Docker image from Docker Hub using the command docker pull natnaelt2/ensf400-demo:commit-hash. Finally, we run the Docker container using the command docker run -p 8080:8080 natnaelt2/ensf400-demo:commit-hash. Then visit the application with your browser at http://localhost:8080/demo.




2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ plugins {

// gretty is a gradle plugin to make it easy to run a server and hotswap code at runtime.
// https://plugins.gradle.org/plugin/org.gretty
id 'org.gretty' version '3.0.4'
id 'org.gretty' version '3.1.5'

// provides access to a database versioning tool.
id "org.flywaydb.flyway" version "6.0.8"
Expand Down
50 changes: 50 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
services:
jenkins:
build: ./jenkins
privileged: true
user: root
ports:
- 8081:8080
- 50000:50000
container_name: jenkins
volumes:
- /home/codespace:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
networks:
- dev-network
depends_on:
- sonarqube

sonarqube:
image: sonarqube:8.9-community
container_name: sonarqube
environment:
- SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
- SONARQUBE_JDBC_USERNAME=sonar
- SONARQUBE_JDBC_PASSWORD=sonar
ports:
- "9000:9000"
volumes:
- sonarqube_data:/opt/sonarqube/data
networks:
- dev-network

db:
image: postgres:latest
container_name: sonar-db
environment:
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=sonar
- POSTGRES_DB=sonar
volumes:
- db_data:/var/lib/postgresql/data
networks:
- dev-network

networks:
dev-network:

volumes:
jenkins_home:
sonarqube_data:
db_data:
6 changes: 6 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM gradle:7.6.1-jdk11
WORKDIR /ensf400-demo
COPY . .
RUN ./gradlew build
EXPOSE 8080
CMD ["gradle", "appRun"]
Binary file modified docs/BDD_video.mp4
Binary file not shown.
21 changes: 21 additions & 0 deletions jenkins/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM jenkins/jenkins:alpine
USER root

RUN apk add --update docker openrc

RUN apk add --no-cache \
openjdk11 \
bash \
docker \
curl \
unzip
ENV GRADLE_VERSION=7.6
ENV GRADLE_HOME=/opt/gradle

RUN mkdir -p ${GRADLE_HOME} && \
curl -fsSL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -o /tmp/gradle.zip && \
unzip /tmp/gradle.zip -d /opt/gradle && \
rm /tmp/gradle.zip

ENV PATH="${GRADLE_HOME}/gradle-${GRADLE_VERSION}/bin:${PATH}"
RUN gradle -v
68 changes: 35 additions & 33 deletions jenkins/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,70 +8,72 @@ pipeline {
// This is set so that the Python API tests will recognize it
// and go through the Zap proxy waiting at 9888
HTTP_PROXY = 'http://127.0.0.1:9888'
// Default Java Home for Jenkins (JDK 17)
JAVA_HOME = '/usr/lib/jvm/java-17-openjdk'
PATH = "${JAVA_HOME}/bin:${PATH}"
}

stages {

// build the war file (the binary). This is the only
// place that happens.
stage('Build') {
environment {
// Override JAVA_HOME to use JDK 11 for this stage
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
PATH = "${JAVA_HOME}/bin:${PATH}"
}
steps {
sh './gradlew clean assemble'
}
}

@@ -23,6 +31,11 @@ pipeline {
// run all the unit tests - these do not require anything else
// to be running and most run very quickly.
stage('Unit Tests') {
environment {
// Override JAVA_HOME to use JDK 11 for this stage
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
PATH = "${JAVA_HOME}/bin:${PATH}"
}
steps {
sh './gradlew test'
}
post {
always {
junit 'build/test-results/test/*.xml'
}
}
}

@@ -36,6 +49,11 @@ pipeline {
// run the tests which require connection to a
// running database.
stage('Database Tests') {
environment {
// Override JAVA_HOME to use JDK 11 for this stage
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
PATH = "${JAVA_HOME}/bin:${PATH}"
}
steps {
sh './gradlew integrate'
}
post {
always {
junit 'build/test-results/integrate/*.xml'
}
}
}

// These are the Behavior Driven Development (BDD) tests
@@ -50,6 +68,11 @@ pipeline {
// See the files in src/bdd_test
// These tests do not require a running system.
stage('BDD Tests') {
environment {
// Override JAVA_HOME to use JDK 11 for this stage
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
PATH = "${JAVA_HOME}/bin:${PATH}"
}
steps {
sh './gradlew generateCucumberReports'
// generate the code coverage report for jacoco
sh './gradlew jacocoTestReport'
}
post {
always {
junit 'build/test-results/bdd/*.xml'
}
}
}

@@ -65,147 +88,15 @@ pipeline {
// Runs an analysis of the code, looking for any
// patterns that suggest potential bugs.
stage('Static Analysis') {
steps {
sh './gradlew sonarqube'
// wait for sonarqube to finish its analysis
sleep 5
sh './gradlew checkQualityGate'
}
}
environment {
// Override JAVA_HOME to use JDK 11 for this stage
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
PATH = "${JAVA_HOME}/bin:${PATH}"
}

steps{
sh './gradlew sonarqube -Dsonar.host.url=http://sonarqube:9000 -Dsonar.login="admin" -Dsonar.password="ensf400"'


// Move the binary over to the test environment and
Expand Down