Setting Up a CI Pipeline with GitHub Actions

Automating your build, test, and deployment steps can significantly improve your development workflow, reduce manual errors, and maintain high-quality code. GitHub Actions makes this process easier by enabling you to create workflows directly in your GitHub repository.

This guide walks through setting up a Continuous Integration (CI) pipeline using GitHub Actions. We’ll cover .github/workflows basics, writing a build/test YAML file, configuring triggers like push, pull requests (PRs), and cron jobs, and running checks on every commit. Additionally, we’ll include a Spring Boot example to demonstrate CI for a Java-based project.

Table of Contents

  1. What is GitHub Actions?
  2. Understanding .github/workflows
  3. Writing a Basic Build/Test YAML
  4. Triggers in GitHub Actions
  5. Running Checks on Every Commit
  6. Integrating GitHub Actions with Spring Boot
  7. Final Thoughts

What is GitHub Actions?

GitHub Actions is a powerful CI/CD tool built into GitHub. It enables you to define workflows through YAML files, which automate common tasks like building, testing, and deploying your application.

Key Benefits:

  • Built-in Integration: GitHub Actions runs directly from your repository.
  • Flexibility: Supports a wide range of programming languages and configurations.
  • Custom Workflows: Easily define pipelines using YAML and community-contributed actions.
  • Free Usage Tiers: Generous free tier for public repositories or smaller teams.

Understanding .github/workflows

The .github/workflows directory is where the magic happens. It hosts YAML files that define your CI/CD workflows.

Creating the .github/workflows Directory

Inside your repository, create the following folder structure:

.github/
  └── workflows/
      └── ci-pipeline.yml

The ci-pipeline.yml file defines your workflow. Each workflow file contains the following key elements:

  1. Name: A descriptive name for the workflow.
  2. Triggers: Events that kick off the workflow (e.g., commits, pull requests).
  3. Jobs: Tasks to perform, such as building or testing code.
  4. Steps: Commands or actions to execute in each job.

Example Structure of Workflow YAML:

name: CI Pipeline

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

Writing a Basic Build/Test YAML

To create your pipeline, define jobs and their corresponding steps in the ci-pipeline.yml file.

Example Build/Test Workflow

For instance, if you’re building and testing a Spring Boot application, your pipeline might look like this:

name: Java CI Workflow

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Build with Maven
        run: mvn clean package

      - name: Run tests
        run: mvn test

Explanation of Steps:

  1. Checkout: Uses the actions/checkout plugin to clone the repository.
  2. Set up JDK: Configures the Java Development Kit (JDK).
  3. Build: Runs mvn clean package to build the project and compile the application.
  4. Test: Executes mvn test to automatically run unit tests.

YAML Validation

Ensure your YAML file syntax is correct. You can use tools like YAML Validator to avoid syntax issues.


Triggers in GitHub Actions

Triggers define when a GitHub Action workflow runs. There are three common types of triggers.

Push Trigger

Run a workflow every time code is pushed to your repository:

on:
  push:
    branches:
      - main

Pull Request Trigger

Run tests for features or bug fixes before merging changes:

on:
  pull_request:
    branches:
      - main

Use Case: Set up a mandatory PR check to ensure all tests pass before merging:

  1. Go to the repository settings.
  2. Enable branch protection rules to require successful checks.

Scheduled Builds (Cron)

Schedule workflows to run at specific times, such as daily builds:

on:
  schedule:
    - cron: '0 12 * * *'

The above trigger runs the workflow every day at noon (UTC).


Running Checks on Every Commit

To ensure each commit is verified, configure workflows to run automatically with every push. This ensures that no broken code reaches the main branch.

Example: Simplify every-commit validation:

on:
  push:
    branches:
      - '**'

Enhance the pipeline with additional checks:

  1. Static Code Analysis (e.g., SonarQube, CheckStyle).
  2. Dependency Scanning to identify vulnerabilities.

Integrating GitHub Actions with Spring Boot

Now, let’s apply what we’ve learned to build a CI pipeline for a Spring Boot application.

Prerequisites

  1. A Spring Boot project with a pom.xml or build.gradle file.
  2. GitHub repository to host the project.

Example GitHub Action for Spring Boot

Create a ci-spring-boot.yml file in .github/workflows/:

name: Spring Boot CI Pipeline

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'

    - name: Install dependencies
      run: mvn install --no-transfer-progress

    - name: Build Application
      run: mvn clean package

    - name: Run Tests
      run: mvn test

  sonar-analysis:
    runs-on: ubuntu-latest
    needs: build-and-test

    steps:
    - name: Run SonarQube Analysis
      uses: sonarsource/sonarqube-scan-action@master
      with:
        host-url: ${{ secrets.SONAR_HOST_URL }}
        login-token: ${{ secrets.SONAR_TOKEN }}

New Additions:

  1. SonarQube Analysis to perform static code analysis.
  2. Secrets Management: Use GitHub secrets (SONAR_HOST_URL and SONAR_TOKEN) to securely store sensitive values.

Advanced Tip

Integrate dependency caching in Maven workflows to improve pipeline speed:

- name: Cache Maven dependencies
  uses: actions/cache@v3
  with:
    path: ~/.m2/repository
    key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}

Final Thoughts

Setting up a CI pipeline with GitHub Actions simplifies and automates essential development workflows. Whether you’re building a Spring Boot application or a project in another language, following best practices like using triggers, automated testing, and dependency caching ensures efficient pipelines and robust code quality.

Experiment with your pipeline, introduce advanced tools like SonarQube, and optimize for speed and reliability. With GitHub Actions, you can focus on writing great code while letting automation handle the rest!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *