GitHub Actions CI/CD Tutorial Series — Part 3
In Part 2 of this tutorial series, we covered the following steps:
*) Used of CNAME
*) Enabled SSL certificates for subdomains
*) Installed Docker
If you missed Part 2, you can find it here: Part 2
Check out Repo
In order to follow along, fork my GitHub Repo and check out the branch start-project-v1
:
You find the fork symbol on the top right side
IMPORTANT
Make sure you check out my Medium article: Kotlin Spring Boot Tutorial Part 3: Creating REST endpoints for a task app or my YouTube video: Kotlin Spring Boot Tutorial - Part 13 | application.yml Secrets about how to set up environments variables in IntelliJ IDE. When you have successfully set up everything then run the app.
Create the Dockerfile — Yalla | يلا
Now when you have opened the app in your IDE, create in the root folder the Dockerfile
.
Remember that a Dockerfile
doesn’t have a type at the end.
Add these lines to your Docker app:
# Use a specific OpenJDK version
FROM openjdk:20-slim as builder
# Set the working directory
WORKDIR /build
# Copy the files from the current directory to the working directory
COPY . .
# Build the application
RUN ./gradlew build
# Use a specific OpenJDK version for the runtime image
FROM openjdk:20-slim
# Create a new user and group for better security
RUN groupadd -r app && useradd --no-log-init -r -g app app
# Set the working directory
WORKDIR /app
Now, in your IntelliJ IDE navigate to build
-> libs
:
When you have pressed the play button for your app there should be a JAR file in your build
-> libs
folder. If the app doesn’t start make sure you read the IMPORTANT part from above, you also will need your supabase.com credentials.
If there is no JAR file then first build your project and then run your project:
Because we need to reference this “cicd-tutorial-0.0.1-SNAPSHOT.jar” in the next lines of your Dockerfile
:
# Copy the compiled JAR file from the builder stage
COPY --from=builder /build/build/libs/cicd-tutorial-0.0.1-SNAPSHOT.jar task-app-api.jar
Here we rename “cicd-tutorial-0.0.1-SNAPSHOT.jar” to “task-app-api.jar” when copying the JAR file.
IMPORTANT even though you might see the file has “-plain” before the dot in build
-> libs
remove the ”-plain” and just name it “cicd-tutorial-0.0.1-SNAPSHOT.jar”
The next lines are:
# Use the created user
USER app
# Set the entrypoint command
ENTRYPOINT ["java", "-jar", "task-app-api.jar"]
And for reference, this is the complete Dockerfile:
# Use a specific OpenJDK version
FROM openjdk:20-slim as builder
# Set the working directory
WORKDIR /build
# Copy the files from the current directory to the working directory
COPY . .
# Build the application
RUN ./gradlew build
# Use a specific OpenJDK version for the runtime image
FROM openjdk:20-slim
# Create a new user and group for better security
RUN groupadd -r app && useradd --no-log-init -r -g app app
# Set the working directory
WORKDIR /app
# Copy the compiled JAR file from the builder stage
COPY --from=builder /build/build/libs/cicd-tutorial-0.0.1-SNAPSHOT.jar task-app-api.jar
# Use the created user
USER app
# Set the entrypoint command
ENTRYPOINT ["java", "-jar", "task-app-api.jar"]
GitHub Actions CI/CD Pipeline
Now in order for the GitHub Actions CI/CD Pipeline to work we need to create two new folders in our project.
Because the GitHub Actions Pipeline will look for a folder in your project named .github
After you have created the directory .github
you need to create another directory inside of .github
and name it workflows
because continuous integration and continuous deployment (CI/CD) are a workflow.
IMPORTANT it is really necessary that you name your directories exactly like that otherwise the CI/CD will not work.
Inside workflows
create a YAML file and name it cicd.yml
Then give your workflow a name like “Build & Deployment” and add that it should trigger for push and pull-request events for the master branch.
name: Build & Deployment
on:
push:
branches:
- master
pull_request:
branches:
- master
After that add the jobs section the first job will be to build the project and because our Ubuntu instance is 22.04 we should also define the job that should run in Ubuntu 22.04.
jobs:
build:
name: Build Project
runs-on: ubuntu-22.04
Next, you can add the first steps for your build job. The first step will be to get a Slack notification when the Pipeline has started. You can give each step a name and then decide which action to use.
steps:
- name: Slack Notification Ci/Cd started
uses: 8398a7/action-slack@v3.15.1
with:
status: ${{ job.status }}
fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
text: 'CI/CD started :eyes: In the Name of God the Merciful, the Compassionate / Bismillahir Rahmanir Raheem /بسم الله الرحمن الرحيم'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
In this code snippet, a GitHub Actions workflow step is defined to send a Slack notification when the CI/CD process starts. Here’s a breakdown of the step:
name
: The name of the step, which is "Slack Notification Ci/Cd started".uses
: Specifies the GitHub Actions action to be used, in this case,8398a7/action-slack@v3
, a popular Slack notification action.with
: This section defines the input parameters for the action:
status
: The status of the job, which is dynamically set using${{ job.status }}
.fields
: A list of fields to be included in the Slack message, such as repository, commit message, author, etc.text
: The custom text message to be sent as a Slack notification, which includes a phrase in Arabic to signify the beginning of the CI/CD process.
4. env
: This section defines the environment variables for the action:
SLACK_WEBHOOK_URL
: The Slack webhook URL, which is stored as a secret in the repository settings, allows the action to send notifications to the specified Slack channel.
When the workflow reaches this step, a Slack notification will be sent to the configured channel with the specified message and fields. This helps you maybe your team informed about the status of the CI/CD pipeline and allows you to track the progress in real-time.
Set up Slack
Now open your Slack app or download it from https://slack.com/ .
First Create a new channel by clicking on “+ Add channels”
Second, give your channel a name and click on “Create”
Go to “Settings & administration” -> “Manage apps”
On the top right corner, you will find the button “Build” and click on it.
Then click on “Create an App”
Select next “From scratch”
Then give it an app name and select your workspace and click on “Create App”.
Then you should see the “Basic Information” side and select there “Incoming Webhooks”.
Toggle the “On” button at “Incoming Webhooks”.
Scroll down and click on “Add New Webhook to Workspace”
After that select your channel “cicd-pipeline” and click on “Allow”
In your Slack channel you should see something like this:
From the Slack settings web page copy the curl command
Paste it in your terminal and press enter:
Then jump to your Slack channel again:
Create your first GitHub Secret
Below our curl command copy “Webhook URL”
Jump back to your GitHub Repo (Make sure you forked my repo: https://github.com/habibicoding/cicd-tutorial-mediumcom) go to “Settings”
Click on “Secrets and variables” and select “Actions”
Then click on “New repository secret”
Because we have defined our slack secret in our cicd.yml
as ${{ secrest.SLACK_WEBHOOK_URL }}
we need to name it as SLACK_WEBHOOK_URL
and past the Webhook URL from the Slack settings webpage and click on “Add secret”.
With that, we conclude the third part of this tutorial series. If you found it useful and informative, give it a clap. Here is Part 4.
Don’t forget to check out the video version of this article on our YouTube channel at https://www.youtube.com/@habibicoding.