Reader small image

You're reading from  GitHub Actions Cookbook

Product typeBook
Published inApr 2024
PublisherPackt
ISBN-139781835468944
Edition1st Edition
Concepts
Right arrow
Author (1)
Michael Kaufmann
Michael Kaufmann
author image
Michael Kaufmann

Michael Kaufmann believes that developers and engineers can be happy and productive at work. He loves DevOps, GitHub, Azure, and modern work. Microsoft has awarded him with the title Microsoft Regional Director (RD) and Microsoft Most Valuable Professional (MVP) – the latter in the category of DevOps and GitHub. Michael is also the founder and managing director of Xebia Microsoft Services, Germany – a consulting company that helps its customers become digital leaders by supporting them in their cloud, DevOps, and digital transformation. Michael shares his knowledge in books, training, and as a frequent speaker at international conferences.
Read more about Michael Kaufmann

Right arrow

Build and Validate Your Code

In this chapter, you will learn how to use GitHub Actions to build and validate code, validate changes in pull requests, and keep your dependencies up to date. You will learn where to store build output and how to optimize your workflow runs with caching.

We will cover the following recipes:

  • Building and testing your code
  • Building different versions using a matrix
  • Informing the user on details of your build and test results
  • Finding security vulnerabilities with CodeQL
  • Creating a release and publishing the package
  • Versioning your packages
  • Generating and using software bills of materials (SBOMs)
  • Using caching in workflows

Technical requirements

For this chapter, you will need an up-to-date version of NodeJS and Visual Studio Code. You can also use GitHub Codespaces.

Building and testing your code

In this recipe, we will create a simple Continuous Integration (CI) pipeline that builds and validates code and gets integrated into pull request validation. We’ll use this code in subsequent recipes – that’s why we’re using a very simple JavaScript package.

Getting ready

I think it is best to build a new repository and npm package from scratch. Even if you’re not familiar with JavaScript, this should not be a challenge. You can compare your code or copy it from the following repository: https://github.com/wulfland/package-recipe. If you struggle with this, just clone this repository and work with it.

  1. Create a new public repository called package-recipe. Initialize it with a .gitignore file and a README file and pick Node as the template for the .gitignore file.
  2. Clone your repository locally or open it in Codespaces.
  3. Run the following command:
    $ npm init

    Follow the wizard. The name of the package...

Building different versions using a matrix

In this recipe, we are going to build and test our software for different versions, in our case, of the NodeJS environment.

Getting ready

Make sure you have cloned the repository from the previous recipe. Create a new branch to modify the workflow:

$ git switch -c build-matrix

Open the .github/workflows/ci.yml file in an editor.

How to do it…

  1. Add the following code to the workflow file:
    strategy:
      matrix:
        node-version: ["21.x", "20.x"]

    Adjust the versions if needed.

  2. In the actions/setup-node action, set the node version to the corresponding value from the matrix context:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
        check-latest: true
  3. Commit and push your changes and create a pull request:
    $ git add .
    $ git commit
    $ git push -u origin build-matrix
    $ gh pr create --fill...

Informing the user on details of your build and test results

In this recipe, we are going to decorate pull requests and workflow summaries with details of our test results. We’ll also add badges to the README file to indicate the quality of a branch or release.

Getting ready

Create a new branch to do the modification:

$ git switch -c add-badges

How to do it…

You can download badges for workflows using the following URL:

https://github.com/OWNER/REPO/actions/workflows/FILE.yml/badge.svg

You can also filter by branch or event by adding query parameters (for example, ?branch=main or ?event=push). We want a badge for the main branch, so add the following image to the markdown of your README:

![main](https://github.com/OWNER/package-recipe/actions/workflows/ci.yml/badge.svg?branch=main)

The badge will use the name in the workflow file and look like Figure 6.4 in the preview:

Figure 6.4 – Badge for the CI workflow

Figure 6.4 – Badge for the CI workflow

...

Finding security vulnerabilities with CodeQL

This is a short recipe that we will use to add a CodeQL analysis to our existing CI build. CodeQL is the code analysis engine from GitHub, and it is free for public repositories.

Getting ready

Create a new branch in the package-recipe repository:

$ git switch -c add-codeql

How to do it…

  1. Open the .github/workflows/ci.yml file and grant the build job permissions to write security events:
    build:
      permissions:
        pull-requests: write
        security-events: write
  2. Add an init action (github/codeql-action/init) to the job. For languages that must be compiled, this has to go before the build process. As JavaScript is a static language, you can add it to the end of the job. Set the language to javascript-typescript and select the security-and-quality query suite:
          - name: Initialize CodeQL
            ...

Creating a release and publishing the package

In this recipe, we are going to create a workflow that will publish our package whenever a release is created.

Getting ready

Create a new branch:

$ git switch -c add-release-workflow

How to do it…

  1. Create a new .github/workflows/release.yml workflow file. Name the workflow Release and trigger it on the creation of GitHub releases:
    name: Release
    on:
      release:
        types: [created]
  2. Add a publish job and give it read permission for the repository and write for packages:
    jobs:
      publish:
        runs-on: ubuntu-latest
        permissions:
          packages: write
          contents: read
  3. Check out the code and configure the NodeJS environment with the correct version. Also, set the registry to use GitHub:
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node...

Versioning your packages

If you now created a new release, the workflow would fail as it would try to publish version 1.0.0 again to the package registry. You would manually have to set the version number in the package.json file. In this recipe, we will use GitVersion to automate this process.

Getting ready

Switch to a new branch:

$ git switch -c add-gitversion

How to do it…

  1. For GitVersion to automatically determine the version of your git workflow, you have to download all references and not just the HEAD branch. We do this by adding the fetch-depth parameter to the checkout action and setting it to 0:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
  2. Set up GitVersion in a specific version:
    - name: Install GitVersion
      uses: gittools/actions/gitversion/setup@v0.10.2
      with:
        versionSpec: '5.x'
  3. Execute GitVersion to determine the version number:
    - name: Determine Version...

Generating and using SBOMs

An SBOM (see https://www.cisa.gov/sbom) declares the nested inventory of components that make up the software. The United States government is required to obtain an SBOM for any product they purchase by the Cyber Supply Chain Management and Transparency Act of 2014.

You can manually export an SBOM in GitHub under Insights | Dependency graph | Export SBOM (see Figure 6.19):

Figure 6.19 – Manually exporting an SBOM in a repository

Figure 6.19 – Manually exporting an SBOM in a repository

The SBOM is a JSON file following the Software Package Data Exchange (SPDX) standard.

In this recipe, we will automate the process of generating an SBOM from the current dependencies of the repository and attach it to the release as an additional attachment.

Getting ready

Switch to a new branch:

$ git switch -c upload-sbom

How to do it…

  1. Edit the .github/workflows/release.yml file. Modify the permission for the publish job to allow write access to permissions:
    jobs...

Using caching in workflows

In this recipe, we will use caching to optimize the speed of workflows.

Getting ready

Switch to a new branch:

$ git switch -c cache-npm-packages

How to do it…

  1. Edit the .github/workflows/ci.yml file. After the setup-node action, add the following script to get the npm cache directory for the correct npm version and store it as an output variable:
    - name: Get npm cache directory
      id: npm-cache-dir
      run: echo "dir=$(npm config get cache)" >> "${GITHUB_OUTPUT}"
  2. Add the actual cache step right after that. Also, give it a name and create a key from the hash of the package-lock.json file:
    - uses: actions/cache@v3
      id: npm-cache
      with:
        path: ${{ steps.npm-cache-dir.outputs.dir }}
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
        ...
lock icon
The rest of the chapter is locked
You have been reading a chapter from
GitHub Actions Cookbook
Published in: Apr 2024Publisher: PacktISBN-13: 9781835468944
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Michael Kaufmann

Michael Kaufmann believes that developers and engineers can be happy and productive at work. He loves DevOps, GitHub, Azure, and modern work. Microsoft has awarded him with the title Microsoft Regional Director (RD) and Microsoft Most Valuable Professional (MVP) – the latter in the category of DevOps and GitHub. Michael is also the founder and managing director of Xebia Microsoft Services, Germany – a consulting company that helps its customers become digital leaders by supporting them in their cloud, DevOps, and digital transformation. Michael shares his knowledge in books, training, and as a frequent speaker at international conferences.
Read more about Michael Kaufmann