Feedback

Chat Icon

Cloud-Native Microservices With Kubernetes - 2nd Edition

A Comprehensive Guide to Building, Scaling, Deploying, Observing, and Managing Highly-Available Microservices in Kubernetes

Continuous Integration, Delivery, and Deployment of Microservices: A Hands-on Guide
97%

CI Workflows for Our Microservice with GitHub Actions

GitHub Actions are workflows triggered by specific events that occur in a GitHub repository. These events can include actions such as pushing code, opening a pull request, creating an issue, publishing a release, or even running on a schedule (via cron syntax). Each workflow is defined using a YAML file located in the .github/workflows/ directory of your repository.

Workflows are composed of jobs, and each job consists of one or more steps. Steps can run commands directly in the runner’s environment or call reusable actions (prebuilt tasks that automate common CI/CD steps, such as checking out code, setting up a language runtime, or deploying to a cloud service).

In our case, we want to trigger a workflow when we push to the main or master branch of the repository. This means that every time new commits are pushed or merged into these branches, GitHub Actions automatically execute the defined workflow.

Here’s an example of a basic workflow configuration:

name: CI Pipeline

on:
  push:
    branches: [ main, master ]

jobs:
  build:
    runs-on: ubuntu-24.04

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

In this example, we have defined a workflow named "CI Pipeline" that triggers on pushes to the main or master branches. The workflow contains a single job called build, which runs on the latest Ubuntu environment. The job consists of several steps: "Checkout repository", "Set up Node.js", "Install dependencies", and "Run tests".

By defining workflows like this, you can automate repetitive tasks, enforce quality gates, and ensure consistent delivery pipelines directly from your GitHub repository. This could be ideal for GitHub users who want to implement CI/CD practices without relying on external tools or services. GitLab CI/CD and many other CI/CD tools share similar concepts and terminology.

Actions are the building blocks of GH Actions workflows. They are reusable and, most importantly, shareable components. You can create your own actions or use some of the many actions shared by the community in the GitHub Marketplace.

You can find (or create) different types of actions with different scopes, such as:

  • Static code analysis
  • Code coverage
  • Code quality
  • Code linting
  • Code formatting
  • Security scanning (DAST, SAST, IAST, etc.)
  • etc.

Setting Up GitHub Actions

Setting Up Secrets

Before proceeding, we need to configure the GitHub Actions secrets for our GitHub repository. These secrets will be used by the CI/CD platform to push our Docker image to Docker Hub:

  • DOCKER_USERNAME: Your Docker Hub username
  • DOCKER_PASSWORD: Your Docker Hub password

Let's do this using the GitHub CLI:

# Replace 
# with your github username
export DOCKER_USERNAME=""

# Replace 
# with your github password
export DOCKER_PASSWORD=""

# Replace 
# with your docker hub repository name
export DOCKER_REPOSITORY_NAME=

# Create the secrets
gh secret set DOCKER_USERNAME \
  -b"${DOCKER_USERNAME}"

gh secret set DOCKER_PASSWORD \
  -b"${DOCKER_PASSWORD}"

gh secret set DOCKER_REPOSITORY_NAME \
  -b"${DOCKER_REPOSITORY_NAME}"

ℹ️ GitHub Actions secrets are encrypted environment variables that you create in a repository. They are used to store sensitive information, such as passwords or access tokens, which you don't want to expose in your code and CI/CD workflows.

Creating the Workflow File

Each workflow is defined in a YAML file (".github/workflows/main.yml"), so let's create the necessary directory first:

cd $HOME/cicd && mkdir -p .github/workflows

Let's see, step by step, what we need to do to create our workflow. This is the first part of the file:

name: Test, build, push Docker image and release Helm chart
on:
  push:
    branches: [main, master]
  workflow_dispatch:

Our workflow will automate the testing, building, and pushing of Docker images, as well as the release of Helm charts. Here is a breakdown of the code above:

  • name: - This line specifies the name of the workflow.
  • on: - This section defines the events that trigger the workflow. In this case, any push to the 'main' or 'master' branch initiates the workflow.
  • We have also added workflow_dispatch to allow us to manually trigger the workflow without having to push to the repository.

Unit Tests

Next, we need to define the first job:

jobs:
  perform_unit_tests:
    runs-on: ubuntu-24.04
    steps:

      - name: Checkout Code
        uses: actions/checkout@v4.1.0

      - name: Set up Python
        uses: actions/setup-python@v4.7.0
        with:
          python-version: '3.10'
          architecture: 'x64'

      - name: Install Requirements
        run: pip install -r app/requirements.txt

      - name: Run Unit Tests
        run: |
          python app/test_app.py
          if [ $? -eq 0 ]; then
            echo "Unit tests passed!"
          else
            echo "ÂŻ\(Âş_o)/ÂŻ"
            exit 1
          fi

What we've added here is the perform_unit_tests: job, which is responsible for running unit tests. This is a name we chose for the job; you can name it whatever you like.

  • It specifies that the job should run on a server with Ubuntu 24.04.

  • It checks out the code using the actions/checkout action.

  • It sets up Python using the actions/setup-python action.

  • It then installs the application's requirements and runs the unit tests. We are using | to add a multi-line command in the run field.

ℹ️ Actions like actions/checkout and actions/setup-python are reusable components that simplify common tasks in CI/CD workflows.

Building and Pushing Docker Image

Let's add the second job that builds and pushes the Docker image:

build_and_push_to_docker_hub:
  runs-on: ubuntu-24.04
  needs: perform_unit_tests
  steps:

    - uses: actions/checkout@v4.1.0

    - run: |
        echo "${{ secrets.DOCKER_PASSWORD }}" |
        docker login -u "${{ secrets.DOCKER_USERNAME }}" \
        --password-stdin

    - run: |
        docker build -t ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPOSITORY_NAME }}:latest -f app/Dockerfile app

    - run: |
        docker push ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPOSITORY_NAME }}:latest

The job build_and_push_to_docker_hub: builds a Docker image and pushes it to Docker Hub:

  • This job runs on Ubuntu and depends on the successful completion of the 'perform_unit_tests' job (needs: perform_unit_tests).

  • It checks out the code using the actions/checkout, which runs the equivalent of git clone.

  • It logs in to Docker using the secrets DOCKER_USERNAME and DOCKER_PASSWORD. This is not a necessary step if you are using a public Docker registry that does not require authentication.

  • It builds the Docker image using the Dockerfile located in the app directory and pushes it to Docker Hub (tagged as latest).

You can use your preferred container registry instead of Docker Hub. Just make sure to adjust the login, build, and push commands accordingly.

Releasing the Helm Chart

Next, we will add the Helm chart release job:

  # This job is responsible
  # for releasing the Helm chart
  release_helm_chart:
    permissions:
      contents: write
    runs-on: ubuntu-24.04
    needs: build_and_push_to_docker_hub
    steps:

      # Checks out the repository contents to
      # $GITHUB_WORKSPACE, so that your workflow
      # can access them.
      - name: Checkout
        uses: actions/checkout@v4.1.0
        with

Cloud-Native Microservices With Kubernetes - 2nd Edition

A Comprehensive Guide to Building, Scaling, Deploying, Observing, and Managing Highly-Available Microservices in Kubernetes

Enroll now to unlock all content and receive all future updates for free.