Continuous Integration#

works on my machine

Reddit - Programmer Humor - Works on my Machine


How to start?#

  • Many ways to do CI; use the one you prefer
    • Github Actions
    • Azure DevOps
    • Circle CI
    • Travis
  • List of CI services
  • We will use Github Actions

works on my machine
Turing Way - CC-BY 4.0 licence. DOI: 10.5281/zenodo.3332807

Create a workflow#

  • Create folder .github/workflows

  • Add a name_of_workflow.yml


When should the workflow be executed?#

name: Build documentation and upload artifact

on:
  pull_request:
    branches: main
  push:
    branches:
      - "*"
    tags:
      - "v*"
  schedule:
    - cron: 0 9 * * 1
  workflow_call:
  workflow_dispatch:

Run on pull-request#

on:
  pull_request:
    branches: main

Triggered when

  • A pull request is made against the main branch

  • Can make a list of branches [development, main, "v[0-9].[0-9]+.[0-9]+"]

  • Cheatsheet for patterns


Run on push#

on:
  push:
    branches:
      - "*"
    tags:
      - "v*"

Triggered when

  • A push a commited to any branch

  • A tag starting with v is created


Run on schedule#

 schedule:
    - cron: 0 9 * * 1

Triggered when

  • Specific UCT time in POSIX cron syntax

  • Easy interpreter at: Crontab.guru


Run from another workflow#

on:
  workflow_call:
  • Incredibly powerful feature that makes it possible to make chains of workflows

jobs:
  build-docs:
    uses: ./.github/workflows/build_docs.yml
  deploy:
    needs: [build-docs, pre-commit]

Chained workflow example#

Chained workflow

Source: jorgensd/dolfinx_mpc


Run workflow manually#

on:
  workflow_dispatch:
Run a workflow manually on CI Manual workflow call

Environment variables#

env:
  PUBLISH_DIR: ./_build/html
  PYTHON_VERSION: "3.10"
  • Can be accessed as ${PUBLISH_DIR} or ${{ env.PUBLISH_DIR }} depending on context


Setting up a set of jobs#

jobs:
  build:
    runs-on: ubuntu-22.04
    steps:
      - name: Run echo
        run:  echo "HELLO WORLD"
      - name: Multiple commands
        run: |
          echo "HI"
          ls
  • Github supports several architectures

    • Ubuntu (20.04, 22.04)

    • Windows (2019, 2022)

    • Mac (macos-11, macos-12)


Complex dependencies? Use containers!#

jobs:
  build:
    runs-on: ubuntu-22.04
    container: ghcr.io/fenics/dolfinx/dolfinx:nightly
    steps:
      - name: Run echo
        run:  python3 -c "import dolfinx; print(dolfinx.__version__)
  • Docker containers hosted anywhere


Complex steps to setup your problem? Create an action!#

Github marketplace for actions: https://github.com/marketplace?category=&query=&type=actions

jobs:
  clone-repo:
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout current repo on current branch
        uses: actions/checkout@v4
      - name: Look at current files
        run: ls

Exercise#

  • Make a branch in your repository

  • Create a workflow that runs on Ubuntu 22.04

  • Workflow should run:

    • On every commit on main

    • On every pull request to any branch

  • List the files in the repository


Actions can take inputs#

jobs:
  clone-repo:
    runs-on: ubuntu-22.04
    steps:
      - name: Setup python
        uses: actions/setup-python@v4
        with:
          python-version: ${PYTHON_VERSION}

You can create your own actions#

    - name: Install DOLFINx
      uses: ./.github/actions/install-dolfinx
      with:
        dolfinx: main
        ufl: main
        ffcx: main
        basix: main
        petsc_arch: ${PETSC_ARCH}

You can use actions across repositories#

Example from: https://github.com/jorgensd/actions

name: Use a remote action
on:
  push:
    branches: ["dokken/ci"]
jobs:
  test:
    runs-on: ubuntu-latest
    container: ghcr.io/fenics/dolfinx/dolfinx:nightly
    steps:
      - name: "Use remote action"
        uses: jorgensd/actions/install-dolfinx@v0.1.0

Upload data#

      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          path: ${{ env.PUBLISH_DIR }}
          if-no-files-found: error
          name: documentation
Github artifact

Download data#

      - name: Download docs artifact
        uses: actions/download-artifact@v3
        with:
          name: documentation
          path: "./public"