Skip to main content

Github Actions

Introduction#

Automation is key for streamlining the work processes, and GitHub Actions are the best way to supercharge the workflow.

GitHub actions is a tool within GitHub that enables continuous integration and a wide range of automation. It supports the three major operating systems, Windows, MacOS and Linux, and any programming language supported by those can be ran. Apart from being triggered by pull requests and commits, actions allows to respond to any GitHub event. It allows to trigger certain GitHub Actions workflow (including open source actions) based on:

  • the creation of issues
  • comments
  • the joining of a new member to the repository
  • changes to the GitHub project board

Prerequisites#

Pricing model#

Types#

  • Community-powered workflows : created, tested and published by GitHub’s large community at the marketplace
  • Custom actions

Location#

  • .github/workflows directory

Syntax and rules#

  • Extension : .yml or .yaml

  • Contains at least one job

  • Each job contains a set of steps that perform individual tasks

  • Steps can run commands or use an action. learn more

  • Example

    a worflow starts with a name

    name: main-worklfow

    Use the on field to define the events that will trigger the worflow

    on: push: branches:

      - master

    pull_request: branches:

      - master

    A workflow is composed of independent jobs. run-tests will run the application's unit tests

    jobs: run-tests:

    # Every job requires an operating system to run on. Here, Ubuntu will used runs-on: ubuntu-latest# Jobs contain a list of steps, which are executed consecutively. # Often, the first step is to clone the repository to use the source code it contains. # This will be done by using an action provided by Github, called actions/checkoutsteps:  - name: Check out source code    uses: actions/checkout@v1  # In this step, run field will be used to execute a command to install pytest and run tests  - name: Test with pytest    run: |      pip install pytest      pytest tests.py 

Environment variables#

  • Case sensitive
  • GitHub reserves the GITHUB_ environment variable prefix for internal use by GitHub. Setting an environment variable or secret with the GITHUB_ prefix will result in an error
  • Use _PATH suffix to point to a filesystem location except for HOME and GITHUB_WORKSPACE default variables

Default environment variables#

  • GitHub sets default environment variables that are available to every step in a workflow run

    steps:

    • name: Hello run: echo Hello ${{ secrets.GITHUB_ACTOR }}

Custom environment variables#

  • Hardcoded, not recommended !

    steps:

    • name: Hello run: echo Hello $FIRST_NAME $Last_Name env: FIRST_NAME: Abdelkerim Last_Name: Lemaadi
  • Using secrets

    steps:

    • name: Hello run: echo Hello ${{ secrets.FIRST_NAME }} ${{ secrets.LAST_NAME }}

Authenticating with the GITHUB_TOKEN secret#

  • Use the GITHUB_TOKEN secret which is automatically created by GitHub, or
  • Create a personal access token to perform an action that requires permissions that are not available in the GITHUB_TOKEN

Persistence of workflow data through artifacts#

job_1:  name: job_1 demonstrates the print of a String  runs-on: ubuntu-latest  steps:    - shell: bash      run: |        echo "Hello" > string-print.txt    - name: Upload stdout result for job 1      uses: actions/upload-artifact@v1      with:        name: stringPrint        path: string-print.txt
job_2:  name: job_2 demonstrates the print of another String value  needs: job_1  runs-on: windows-latest  steps:    - name: Download data from job_1      uses: actions/download-artifact@v1      with:        name: stringPrint      - shell: bash        run: |          value=`cat stringPrint/string-print.txt`          echo $value "World!" > stringPrint/string-print.txt      - name: Upload string result for Job2        uses: actions/upload-artifact@v1        with:          name: stringPrint          path: stringPrint/string-print.txtjob_3:  name: Display output  needs: job_2  runs-on: macOS-latest  steps:    - name: Download output      uses: actions/download-artifact@v1      with:        name: stringPrint

Caching dependencies and build outputs#

- name: Set up Python 3.7  uses: actions/setup-python@v1  with:    python-version: 3.7- name: Install pipenv and libpq  run: |    sudo apt-get install libpq-dev -y    pip install pipenv- name: Cache pipenv virtualenv  id: cache-pipenv  uses: actions/cache@v1  with:    path: ~/.local/share/virtualenvs    key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}    restore-keys: |      ${{ runner.os }}-pipenv-      ${{ runner.os }}-- name: Install dependencies  if: steps.cache-pipenv.outputs.cache-hit != 'true'  run: pipenv install

Matrix builds#

  • Building software on more than one supported version of a language, operating system or tool

    jobs:
    test:
    name: Test on node ${{ matrix.node_version }} and ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy: matrix:
    python_version: [2.7, 3.5, 3.6, 3.7, 3.8] os: [ubuntu-latest, windows-latest, macos-latest]

     steps: - uses: actions/checkout@v1
     - name: Set up Python ${{ matrix.python_version }}   uses: actions/setup-python@v2   with:     python_version: ${{ matrix.python_version }}

    A matrix build can generate at most 256 jobs per workflow run.

Runners#

## Build on an integrated package and container registry

  • Free for public repositories, see more

  • Publish and consume packages from GitHub Package Registry or any other registry

  • Docker example

    $ docker login docker.pkg.github.com --username username $ docker tag app docker.pkg.github.com/username/repo/app:1.0 $ docker push docker.pkg.github.com/username/repo/app:1.0.0

Linting code#

Using Flake8#

  - name: Lint with flake8    run: |      pip install flake8      flake8 .

Using pre-commit#

  • With custom invocations
- uses: pre-commit/[email protected]  with:    extra_args: flake8 --all-files
  • In private repositories
  • uses: pre-commit/[email protected] with: token: ${{ secrets.GITHUB_TOKEN }}

Testing code#

- name: Test with pytest  run: |    pip install pytest    pytest tests.py

Live logs#

  • Always use significant words for jobs's and steps's name (compile, build, test, deploy, release, ...)
  • Include emojis

Some useful actions#

Last updated on by lemaadi