Contents

CI/CD Using Github Action

/images/devops.png

Continuous integration is a coding philosophy and set of practices that drive development teams to frequently implement small code changes and check them in to a version control repository. Most modern applications require developing code using a variety of platforms and tools, so teams need a consistent mechanism to integrate and validate changes. Continuous integration establishes an automated way to build, package, and test their applications. Having a consistent integration process encourages developers to commit code changes more frequently, which leads to better collaboration and code quality.

Continuous delivery picks up where continuous integration ends, and automates application delivery to selected environments, including production, development, and testing environments. Continuous delivery is an automated way to push code changes to these environments.

CI/CD Benefits

There are 4 benefits of CI/CD:

  • Increase speed of innovation and ability to complete in the marketplace.
  • Code in production is making money instead of sitting in a queue waiting to be deployed.
  • Greate ability to attract and retain talent.
  • Higher quality code and operation due to specialization.

Automated deployment is a practice that allows you to ship code fully or semy-automatically accross several stages of the development process from initial development right through to production. The automated deployment can:

  • Reduce possibility of errors especially human error
  • Saving time
  • Consistency and repeatable

CI/CD Tools

There are several CI/CD tools that are commonly used, namely:

Jenkins CircleCI Bamboo Gitlab CI Github Actions
Open source Yes No No No Yes
Ease of use & setup Medium Medium Medium Medium Easy
Built-in features 3/5 4/5 4/5 4/5 3/5
Integration
Hosting On premise & Cloud On premise & Cloud On premise & Bitbucket as Cloud On premise & Cloud Cloud
Free Version Yes Yes Yes Yes Yes
Supported OS Windows, Linux, MacOS, Unix-like OS Linux or MacOS Windows, Linux, MacOS, Solaris Linux distributions: Ubuntu, Debian, CentOS, Oracle Linux Linux, Windows, MacOS

Github Actions

/images/github-action.png

At the most basic level, GitHub Actions brings automation directly into the software development lifecycle on GitHub via event-driven triggers. These triggers are specified events that can range from creating a pull request to building a new brand in a repository.

GitHub Actions is a CI/CD tool for the GitHub flow. You can use it to integrate and deploy code changes to a third-party cloud application platform as well as test, track, and manage code changes. GitHub Actions also supports third-party CI/CD tools, the container platform Docker, and other automation platforms.

Project Preparation

Before we used a Github Actions, prepare a spring boot project. You can start from Spring Initializer to create a spring boot project. And create Dockerfile into a project.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Import base JDK from Linux
FROM adoptopenjdk/openjdk11:alpine

# Set work directory
WORKDIR /app

# Copy application files
COPY target/*.jar app.jar

# Expose PORT
EXPOSE 8080

# Run application
ENTRYPOINT ["java", "-jar", "app.jar"]

Pipeline

In github action, we will create a pipeline like following image below.

/images/pipeline.png

Github Actions Script

Put .yaml file into .github/workflows, we will use a push trigger to run github actions jobs. First we create for unit testing step.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name: CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  run_test:
    name: Unit Test
    runs-on: ubuntu-18.04
    steps:
      - run: echo "Starting execute unit test"
      - uses: actions/[email protected]
      - name: Setup JDK 11
        uses: actions/[email protected]
        with:
          java-version: 11
          distribution: 'adopt'
      - name: Maven Verify
        run: mvn clean verify
      - name: Maven Sonar Code Coverage
        run: mvn sonar:sonar -Dsonar.projectKey=springboot-cicd -Dsonar.login=${{ secrets.SONAR_TOKEN }}

Description :

  • Using ubuntu-18.04 runner
  • Checkout latest code from main branch
  • Using java 11
  • Execute command mvn clean verify
  • Execute command mvn sonar:sonar -Dsonar.projectKey=springboot-cicd -Dsonar.login=${{ secrets.SONAR_TOKEN }}

We can change the trigger using create a tags like following below.

1
2
3
4
on:
  create:
    tags:
      - '*SNAPSHOT'

Then, create another job for build package and build images.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
build:
  name: Build
  runs-on: ubuntu-18.04
  needs: run_test
  steps:
    - run: echo "Starting build package"
    - uses: actions/[email protected]
    - name: Setup JDK 11
      uses: actions/[email protected]
      with:
        java-version: 11
        distribution: 'adopt'
    - name: Maven Build
      run: mvn clean package -Dmaven.test.skip=true
    - name: Login to docker hub
      uses: docker/[email protected]
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    - name: Build docker image
      uses: docker/[email protected]
      with:
        context: .
        push: true
        tags: user/images:tag

Description :

  • Using ubuntu-18.04 runner and need job run_test successfully
  • Checkout latest code from main branch
  • Setup java 11
  • Execute command mvn clean package -Dmaven.test.skip=true
  • Login to docker hub with credential on github secrets
  • Execute build image from Dockerfile and push into images registry

Finally, create job for deploying into server using SSH.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
deployment:
  name: Deploy container using SSH
  runs-on: ubuntu-18.04
  needs: build
  steps:
    - run: echo "Starting deploy container"
    - uses: actions/[email protected]
    - name: Copy environment file via ssh
      uses: appleboy/[email protected]
      with:
        host: ${{ secrets.SSH_HOST }}
        port: 22
        username: ${{ secrets.SSH_USERNAME }}
        key: ${{ secrets.SSH_PRIVATE_KEY }}
        source: .env
        target: /home/${{ secrets.SSH_USERNAME }}
    - name: Deploy using ssh
      uses: appleboy/[email protected]
      with:
        host: ${{ secrets.SSH_HOST }}
        port: 22
        username: ${{ secrets.SSH_USERNAME }}
        key: ${{ secrets.SSH_PRIVATE_KEY }}
        script: |
          docker stop the_container
          docker rmi user/images:tag
          docker pull user/images:tag
          docker run -d --rm --name the_container -p 80:8080 --env-file=.env --network another_network user/images:tag          

/images/github-action-pipeline.png

Summary

Developing a CI/CD pipeline is a standard practice for businesses that frequently improve applications and require a reliable delivery process. Once in place, the CI/CD pipeline lets the team focus more on enhancing applications and less on the details of delivering it to various environments.

CI/CD pipelines are typically complex and have a lot of tools that range from testing applications to integration tests to container platforms and application platforms, among other things. GitHub Actions simplifies the process with Node and Docker integrations and allows you to specify which version you want to use and then connect your code to a target environment and application platform.

Reference