Skip to content

Latest commit

 

History

History
559 lines (342 loc) · 15.6 KB

File metadata and controls

559 lines (342 loc) · 15.6 KB
size 14580
<style> { font-size: 16pt; } </style>

Alexandre Abadie, Thierry Martinez (SED) Two-hours training, 15 december 2022


GitHub Actions

  • Providing GitHub-hosted runners for Linux, MacOS and Windows.

  • File-based workflow specification: .github/workflows/*.yml. A command-line tool, act is available for running workflows locally (or from other continuous integration platforms): https://github.com/nektos/act

  • Very easy to extend (new reusable actions can be defined in git repositories), Linux runners can run docker containers, user-provided runners can be used.


Continuous integration (CI): practice of short-lived development cycles, automatically tested and shared regularly between developers involved in a project.

Continuous integration platforms: Github Actions, ci.inria.fr, gitlab.inria.fr.

Automating testing (and CI in general) relies on version control and automated builds.

  • speed up development process,

  • ease collaboration

  • allow programmers to be more confident for not introducing regression and bugs.

This is a step towards broader goals such as reproducible builds and reproducible research.


Version control systems are software dedicated for managing

  • history and
  • collaborative edition of source code or any other kind of documents.

The prominent software for version control is now git, initially developed in 2005 by Linus Torvalds to manage the Linux source code.

git is a decentralized tool (where versions are directly exchanged between peers) but most uses of it now rely on software forges, like [GitHub] or gitlab.inria.fr for instance. Software forges provide other services related to version control, such as [CI/CD] facilities.

Keeping the history of a code is central

  • to make change in the code without losing information and
  • to identify where regressions have been introduced (bisection).
  • to allow code to be modified concurrently by offering merging facilities (three-way merge).

  • Hardware specification for Windows and Linux virtual machines:

    • 2-core CPU (x86_64)
    • 7 GB of RAM
    • 14 GB of SSD space
  • Hardware specification for macOS virtual machines:

    • 3-core CPU (x86_64)
    • 14 GB of RAM
    • 14 GB of SSD space

Usage limits, billing: available for free for public repositories,

  • up to 20 concurrent jobs (Linux/Windows),
  • 5 concurrent jobs for macOS.


Example of workflow

In .github/workflows/example.yml:

on: [push]
jobs:
  build-example:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Compile
        run: |
          gcc -o hello_word hello_world.c
      - name: Test
        run: |
          ./hello_word > output.txt
          diff output.txt excepted.txt

Dependency graph

  • Workflow can have arbitrary complex directed acyclic graph as dependency graph.


Status feedback

  • On repository index

  • In README.md badges:
[![CI][ci-badge]][ci-link]

height:25mm


Status feedback

  • In pull requests (in addition, posts can generated by bots invoked from CI)


Repository initialization

gh repo fork --clone aabadie/github-actions-python-example

(to create a new repository instead: gh repo create <repo name> --public --clone)

  • Edit workflow in github-actions-primer/.github/workflows/continuous-integration.yml

See Choosing GitHub hosted runners for a list of available platforms for runs-on entry. Note that ubuntu-latest is currently Ubuntu 20.04. There is ubuntu-22.04 available in beta.


Build environments can be prepared once for all in a Docker image to reduce build times:

  • docker build -t ghcr.io/‹user›/‹image name› .

  • create a personal access token with scope write:packages, save it in a file

  • docker login ghcr.io -u ‹user› --password-stdin < ‹token path›

  • docker push ghcr.io/‹user›/‹image name›

  • create a personal access token with scope read:packages, store it in a secret (using gh secret set)

  • reference the container in the job

    container:
      image: ghcr.io/‹user›/‹image name›
      credentials:
        username: ${{ github.actor }}
        password: ${{ secrets.‹secret name› }}
  • to run the workflow locally, use act --secret-file ‹file name›

Matrix job


Use a job to build the environment

  • Store a personal access token] with scope write:packages in a secret.

  • Check out the repository! Add the following action

      - name: Checkout
        uses: actions/checkout@v3
  • Steps for docker build and docker push.

⚠️ checkout action wipes out the current directory! Should be run before any actions writing useful things in it (local setup, etc.).


Run a job only if a file has changed

  • Checkout with the input fetch-depth: 2 to get the two last commits (by default, only the last commit is checked out, i.e. git fetch --depth=1)

  • Use git diff --quiet --exit-code HEAD^ HEAD -- ‹path› to check if a file changed.

⚠️ Commands should succeed (with return code 0). Use if-then-else-fi to control the result of git diff.


Using artifacts and deploy release


  • In Project Settings › Actions › Runners, button New self-hosted runner. Follow the instructions. Tags match the values of runs-on: field.

  • ./run.sh can be run in tmux or as a service.


  • Annotations: error/notice/warning
echo "::error file=app.js,line=1::Missing semicolon"
echo "::add-matcher::matcher.json"

Matcher for gcc: ammaraskar/gcc-problem-matcher@master

  • Grouping log lines
::group::{title}
::endgroup::
  • Masking a value
::add-mask::{value}

  • Setting an environment variable
echo "{environment_variable_name}={value}" >> $GITHUB_ENV
  • Output parameter (steps seeting outputs should have id:)
echo "{name}={value}" >> $GITHUB_OUTPUT

In subsequent steps, refer to `${{ steps.{id}.outputs.{name} }}"

  • Job summary
echo "### Hello world! :rocket:" >> $GITHUB_STEP_SUMMARY
  • Adding a system path
echo "{path}" >> $GITHUB_PATH

Docker and registry

Docker is a tool to run programs in containers, that is to say

  • sandboxes that share the same kernel as the running OS,

  • but in a chroot (isolated filesystem),

  • with limited access to resources (process groups, network, and more generally limited system calls).


container: key specifies a Docker image (otherwise, the job runs directly on the VM).


Pushing a Docker image to GitHub registry

Build environments can be prepared once for all in a Docker image to reduce build times:

  • docker build -t ghcr.io/‹user›/‹image name› .

  • create a personal access token with scope write:packages, save it in a file

  • docker login ghcr.io -u ‹user› --password-stdin < ‹token path›

  • docker push ghcr.io/‹user›/‹image name›

  • create a personal access token with scope read:packages, store it in a secret (using gh secret set)

  • reference the container in the job

    container:
      image: ghcr.io/‹user›/‹image name›
      credentials:
        username: ${{ github.actor }}
        password: ${{ secrets.‹secret name› }}
  • to run the workflow locally, use act --secret-file ‹file name›

Use a job to build the environment

  • Store a personal access token with scope write:packages in a secret.

  • Check out the repository! Add the following action

      - name: Checkout
        uses: actions/checkout@v3
  • Steps for docker build and docker push.

⚠️ checkout action wipes out the current directory! Should be run before any actions writing useful things in it (local setup, etc.).


Continuous Delivery/Continuous Deployment

Continuous Delivery: Preparing new releases

Continuous Deployment: Pushing on pypi


Publishing documentation

      - name: Deploy
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          folder: build

Creating custom actions

  • 3 types of actions can be created: Docker, Javascript and Composite

  • Docker actions can only be used on Linux runners

  • Composite actions combines multiple workflow steps in a single action


Describing an action

  • An action is described by a single action.yml file

  • One can define the inputs, outputs end environnement variables of an action

  • If the action is designed to be reusable and public, use a dedicated public repository for the action The name of the action corresponds to the name of the repo, e.g orga/repo name@branch/tag name

  • If the action is local to a repository, place the yml file in .github/actions/‹action name›/action.yml

  • Local actions are used in a workflow as follows, the checkout action must be called before:

    - uses: actions/checkout@master
    - name: Run local custom action
      uses: ./.github/actions/local-action
      ...

Example: a Docker action


Example: a Javascript action


Example: a composite action


Example: an action published to the marketplace