Github Actions

Github Actions is a new feature of Github to use their platform directly to run tasks. Those tasks can be unit tests, compiling and everything else that you can imagine, similar to other platforms like CircleCI or TravisCI.

As with the other platforms, the pipeline is written in a YAML syntax and allows the use of plugins to simplify the use of i.e. checkout or installing tools like the compiler. The action triggers are specified in the different workflow files and get executed based on pushes, merges and/or many more events.

Github Actions for Zephykus

I had the issue that although I was already hosting my code of Zephykus on Github, I did not always push the latest docker images with the latest features. I had really good experience with CircleCI to build code, but wanted to give Github Actions a try anyway. My requirement is to build a typescript frontend with a golang backend and distribute the docker file to docker hub.

Initial configuration is easy, but to me not completely transparent. It was a bit more of trying out till it worked than really fully understanding the semantics. The basics are simple though. I wanted a pipeline that gets run on each push:

name: docker
on: [push, pull_request]

jobs:
  build-frontend:
    runs-on: ubuntu-latest
    timeout-minutes: 3
    steps:
    - name: Checkout
      uses: actions/checkout@v1
    - name: Setup Node.js
      uses: actions/[email protected]
    - name: Install Frontend dependencies
      run: make frontend-dep
    - name: Build Frontend
      run: |
        make build-webpack

Build docker image

Building and pushing a docker image is simple too, through the use of pre-defined actions. Predefined actions were used already in the previous example, i.e. checkout. These actions are on the Github Marketplace and abstract away often used tasks. Hint: Secrets are defined in the Settings of the repository.

jobs:
  publish:
    - name: Docker Hub Push
      uses: azure/docker-login@v1
      with:
        login-server: https://index.docker.io/v1/
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_PASSWORD }}
    - run: |
        version=$(cat ./VERSION)
        echo $VERSION
        cp ./backend/zephykus ./zephykus
        chmod +x ./zephykus
        docker build . -t timonback/zephykus:${version} -t timonback/zephykus:latest
        docker push timonback/zephykus:latest
        docker push timonback/zephykus:${version}

Advanced usage

While not required for everyone, these features have proven helpful for me.

Conditionals

While it is a great advantage to run the pipeline on each commit, I do not want to push (a possibly broken) docker image for each commit. Only when the changes are being pushed/merged to master. For that use-case, conditionals are handy:

    if: github.ref == 'refs/heads/master'

Staged builds

Also, I did not want to build everything in one go, but rather seperate different aspects. Possible parallelism is a welcome advantage. Jobs can depend on others, through which a job hierarchy is created. As it turns out, these jobs are completely independent of each other, so no out of the box data sharing. Luckily, artifacts can be shared with the upload-artifact and download-artifact action. Check my workflow as a functional example.

Caching

Caching is simple, just like on the other platforms:


    - name: Cache node modules
      uses: actions/cache@v1
      with:
        path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-nodebuild-${{ env.cache-name }}-
          ${{ runner.os }}-nodebuild-

Summary

In general, I really like Github Actions. The start was a bit difficult, but I hope my workflow at https://github.com/timonback/zephykus/blob/master/.github/workflows/docker.yaml can help others. The big advantage is the direct integration into the Github platform and the marketplace which removes the burden of configuring additional tools like compilers and tools.

Still, I see a space for other platforms like CircleCi and Travis when you are comfortable with those or want to distribute artifacts. For simple projects, Github Actions is enough and then it only matters how well the integration is done. Let’s see how the community feels about Github Actions.