Initial GitHub Action experiments

Next in my unhurried investigation of hosted build systems for my small collection of Free Software are GitHub Actions. A fully hosted task runner that can Build, test, and deploy your code right from GitHub. As someone not exclusively using GitHub to manage all their source code the idea of being completely tied into a single provider isn’t a great one but the technology looks interesting enough to justify running a few simple experiments.

For this experiment I’m mostly keeping things simple, skipping more advanced aspects like having a build matrix for example, and instead just checking out a repository, installing some gem dependencies and failing the build if the rspec tests fail. The one twist I decided to add was having Actions run rubocop over the PR but not failing the build if it detects violations, just showing them in the results. This gave me a reason to try using a third party action in my tests.

Before we go into the code let us bask in the shiny of the UI.

GitHub WebUI showing rake spec output

The basic action configuration will be familiar to anyone who has used a service like TravisCI or CircleCI in the past. It is also, of course, YAML. This first part of the configuration is mostly setup. We specify the event that should trigger our action, in this case push as I want to test pull requests as they arrive. We set an environment variable, PUPPET_GEM_VERSION that my Gemfile uses and after creating a ruby 2.5 environment we install some gems and run our tests via bundle exec rake spec. The workflow, much like the config itself, is simple and quick to get started with.

name: Ruby

on: [push]

jobs:
  build:
    env:
      PUPPET_GEM_VERSION: "~> 6.10.0"
    runs-on: ubuntu-18.04

    steps:
    - uses: actions/checkout@v1
    - name: Set up Ruby 2.5
      uses: actions/setup-ruby@v1
      with:
        ruby-version: 2.5.x
    - name: Build and test with Rake
      run: |
        gem install bundler
        bundle install --jobs 4 --retry 3
        bundle exec rake spec

The second part of our config, an additional job I creatively named lint uses a third party action extension named Rubocop Linter Action to run rubocop over my code and post the results to the GitHub Checks API. I found this to be helpful as it allows you to view the results directly in the pull request rather than clicking through to another site. The last line of this configuration section is the most magical. In order to publish results to the GitHub APIs you need a valid GitHub Token. Rather than forcing you to manage your own secrets and handle rotations and revocations you can use the internal secrets.GITHUB_TOKEN to authenticate using a temporary token you never have to store and has a scope limited to the repository your workflow is within.

  lint:
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@v1
    - name: Rubocop Linter
      uses: andrewmcodes/rubocop-linter-action@v2.0.1
      with:
        fail_level: 'fatal'
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

You can see the results of this part of the configuration, and my shame at 24 offences, below.

WebUI showing rubocop violations

It’s very early days for my relationship with GitHub Actions (and I’ve been hurt before) but early impressions are very good. Jobs run quickly, there’s a broad range of third party extensions and documentation and it has the benefits of the integrated auth model. I think a few more complicated and matrix based builds are the logical next step on my list of things to try but for now it does exactly what I’ve asked of it.

You can see the the full Add GitHub Actions Pull Request and click around to see what the output looks like on my GitHub repo. The first post in this adhoc series was Initial CircleCI experiments