Skip to content

Latest commit

 

History

History
382 lines (258 loc) · 7.9 KB

File metadata and controls

382 lines (258 loc) · 7.9 KB

Continuous Integration and Continuous Delivery (CI/CD) with GitHub Workflows


Andres Rios Tascon

Princeton Winter Training 2026

What is CI and CD

  • Continuous Integration:
    Frequent merging of changes into main branch with active quality verification.

  • Continuous Deployment:
    Automatic release of new software versions.

What is CI for?

  • Running tests (dynamic and static)
    • Check if new changes break any existing functionality
    • Check if code follows formatting guidelines

What is CI for?

  • Building documentation
    • Run Doxygen/Sphinx/etc generate documentation in pdf or html form
    • Check if examples in the documentation work

What is CI for?

  • Build static websites
    • Build and publish a website to GitHub Pages/ReadTheDocs/etc

What is CI for?

  • Generating pull requests for updates and other maintenance
    • Update dependencies
    • Fix typos and coding style

What is CI for?

  • Whatever your project needs!

What are the benefits?

  • Consistent, controlled environment between runs
  • Runs every PR/commit/tag/whatever you choose
  • Can't be skipped or forgotten, no contributor setup
  • Can run lots of OS's, Python versions, compilers, etc

Some major CI services

  • Travis CI: Very popular for years, but not anymore.
  • Jenkins: A self-host only OSS solution.
  • Circle CI: The first more “modern” design.
  • GitLab CI: For years, this was one of the best services. Still very good.
  • Azure Pipelines: Very modular design is easy to upgrade and maintain.
  • GitHub Actions (GHA): Extremely simple and popular. Actions are easy to write and share.

Let's look at a couple of repositories and see how they use CI/CD

Today we will be focusing on GitHub Actions


We'll first do a crash course on YAML and exit codes.

YAML

YAML (YAML Ain’t Markup Language, originally Yet Another Markup Language) is a human-readable data serialization language.

  • Easy to read and use
  • Very commonly used in CI configuration files.
  • File extension is .yml or .yaml

YAML

Defining scalar values:

number-value: 42
boolean-value: true # can also be on or yes
string-value: "Hello world"
another-string: String without quotes

YAML

Defining lists:

colors:
  - red
  - green
  - blue

more_colors: [black, white]

YAML

Defining dictionaries:

person:
  name: John Smith
  age: 33
  occupation: accountant

same_person: {name: John Smith, age: 33, occupation: accountant}

YAML

Defining multi-line strings:

some-text: >
  Multiple
  lines
  of
  text
same-text: "Multiple lines of text\n"

YAML

Defining multi-line strings:

some-text: |
  Multiple
  lines
  of
  text
same-text: "Multiple\nlines\nof\ntext\n"

Exit codes

  • Your CI will check if each command ran successfully and stop if it runs into an error.
  • Every time you run a command in a shell there is an exit code that indicates if it ran successfully.
  • An exit code of 0 indicates that the command ran successfully, other numbers (usually) indicate an error.
  • Sometimes different numbers correspond to different errors.

Exit codes

> mkdir test
> echo $?
0
> mkdir test
mkdir: test: File exists
> echo $?
1
> mkdir -z test
mkdir: illegal option -- z
usage: mkdir [-pv] [-m mode] directory_name ...
> echo $?
64

Exit codes

  • CI workflows will typically stop once they encounter a non-zero exit code.
  • Sometimes you may need to run a command that might fail, but you want the workflow to proceed.
  • Some scripts and binaries don't respect this standard and return non-zero exit codes even when successful.

Exit codes

Error codes can be ignored using logical or (||)

> mkdir -z test || echo "ignore"
ignore

It is also useful to use logical and (&&) to run a command only if another one is successful.

> <command1> && <command2>

Setting up GitHub workflows

  • Each workflow is configured by a yaml file placed in .github/workflows
  • Can be set to trigger by a wide variety of events
  • Can run your own commands or use actions written by you or third-parties

Setting up GitHub workflows

This is the basic structure of a workflow file.

on: <event or list of events>

jobs:
  job_1:
    name: <name of job>
    runs-on: <type of machine>
    steps:
      - uses: <some third-party action>
      - name: <name of step>
        run: <command>

  job_2:
    runs-on: <type of machine>
    steps:
      - run: <command>

CI/CD hands-on workshop

Go to the following link:

https://github.com/ariostas-talks/2026-01-15-cicd

Exercise 1

Add a workflow that checks out the NumPy repository at version 2.4.0, then runs the ruff formater (either from a pip install or with the GitHub action), and then prints the diff of the changes (if any).

(In practice, it is more common to use pre-commit for this, but that's a topic for another day)

Exercise 2

Create a new workflow that generates these slides and publishes them to GitHub pages. Things you need:

Exercise 2

Start by checking out the repo.

- name: Check out repo
  uses: actions/checkout@v6

Exercise 2

Then set up Python.

- name: Set up Python
  uses: actions/setup-python@v6
  with:
    python-version: "3.11"

Exercise 2

Install markdown-slides.

- name: Install markdown slides
  run: pip install git+https://gitlab.com/da_doomer/markdown-slides.git

Exercise 2

Generate the slides.

- name: Generate slides
  run: mdslides slides.md --output_dir slides

Exercise 2

Upload pages artifact

- name: Upload pages artifact
  uses: actions/upload-pages-artifact@v4
  with:
    path: ./slides

Exercise 2

Deploy to GitHub Pages

deploy:
  permissions:
    pages: write
    id-token: write
  environment:
    name: github-pages
    url: ${{ steps.deployment.outputs.page_url }}
  runs-on: ubuntu-latest
  needs: build
  steps:
    - name: Deploy to GitHub Pages
      id: deployment
      uses: actions/deploy-pages@v4

There's many more things to learn, but with this basic knowledge there is lots of things you can do!