Continuous Integration with GitHub Actions - gecos-lab/PZero GitHub Wiki

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.


Introduction

A workflow is a configurable automated process that will run one or more jobs. Workflows are defined by a YAML file checked into your repository and will run when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule. Workflows are defined in the .github/workflows directory in a repository, and a repository can have multiple workflows, each of which can perform a different set of tasks. For example, you can have one workflow to build and test pull requests, another workflow to deploy your application every time a release is created, and still another workflow that adds a label every time someone opens a new issue.


How to create a basic workflow

  1. If it's not already there create a folder inside PZero called .github.

  2. If it's not already there create a folder inside the .github folder called workflows (note the final s in workflows, if you type workflow it won't work).

  3. Create a YAML file, for example, the file responsible for testing the code is called testing.yml.

  4. Now you can proceed to modify the YAML file:

    1. Choose a workflow name:

      name: Unit Testing
      
    2. Now you need to define which event triggers the workflow. In the following example, this workflow will start when pushing on the GitHub repository to the branch 'master':

       on:
        push:
          branches:
            - 'master'
      

      Of course, you can insert multiple branches and multiple triggering events, for more details see here. Another triggering event I want to mention is the schedule one, which can be useful if we want to run a workflow every interval of a certain time.

    3. Set at least one job. A job is a set of steps that can be performed on a single OS machine (in the following example we have two jobs: the Ubuntu and Windows ones):

      jobs:
        # Linux
        linux-testing:
          name: Linux Unit Testing
          runs-on: ubuntu-latest
      
        # Windows
        windows-testing:
          name: Windows Unit Testing
          runs-on: windows-latest
      
      
    4. Inside each job, create a set of steps that could be performed (I will show only the Ubuntu one for ease of readability and also I will explain later each step):

      jobs:
        # Linux
        linux-testing:
          name: Linux Unit Testing
          runs-on: ubuntu-latest
        
        steps:
          - name: Checkout Repo
            uses: actions/checkout@v3
      
        - name: Create Conda Environment
          uses: conda-incubator/setup-miniconda@v2
          
        - name: Test with pytest
          run: |
            conda install pytest-html
            pytest --html=win-test-report.html tests/
      
      
      

      Note the indentation matter! Actually, I will explain each step:

      1. Checkout Repo: it uses actions/checkout@v3, a predefined action created by GitHub that checks out your repository under $GITHUB_WORKSPACE, so your workflow can access it. Reference here.
      2. Create Conda Environment: it uses conda-incubator/setup-miniconda@v2, a predefined action created that sets up a base conda environment. It's used also inside PyVista because it's lightweight and fast. Reference here.
      3. Test with pytest: it runs two commands from the OS terminal, the first one is to install pytest-html extension with conda and the other one is to run pytest with --html flag on the tests folder

      There are more commands and a lot of possibilities to customize the steps if you want to go more in-depth follow the official guide. Other ideas can be to check other repositories like Pyvista.


Choices made inside 'testing.yml'

  1. Usage of action conda-incubator/setup-miniconda with mamba instead of conda terminal commands like:
conda env create -n pzero -f environment.yml
conda activate pzero

The main reason was to save time and mamba combined with setup-miniconda action really speeds up the environment installation in all the available OS (Ubuntu, Windows, macOS).