Using Julia in GitHub Actions

Hey everyone,

I’ve created a GitHub Action that sets up a Julia environment as a base for CI and other automation tasks.

The action lets you setup 32- and 64-bit Julia environments on all supported OSes (Windows Server 2016 & 2019, Ubuntu 16.04 & 18.04 and macOS X Mojave 10.14).

It still lacks some features like version shortcuts or support for nightly builds but it’s enough to try out GH Actions so I’ve decided to share it already. Check the readme for more info on what’s still missing.

Example workflow: Manually running package tests
name: Run tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        julia-version: [1.0.4, 1.2.0, 1.3.0-rc1]
        julia-arch: [x64, x86]
        os: [ubuntu-latest, windows-latest, macOS-latest]
        # 32-bit Julia binaries are not available on macOS
        exclude:
          - os: macOS-latest
            julia-arch: x86
    
    steps:
      - uses: actions/checkout@v1.0.0
      - name: "Set up Julia"
        uses: julia-actions/setup-julia@v0.2
        with:
          version: ${{ matrix.julia-version }}
          arch: ${{ matrix.julia-arch }}
      - name: "Run tests"
        run: |
          julia --project=@. -e "using Pkg; Pkg.instantiate();"
          julia --project=@. -e "using Pkg; Pkg.test(\"Example\");"

You can find “real world” examples in the Exercism.jl package and in the Exercism Julia track, a non-package project.

More infos about setting up workflows in general can be found in the GitHub docs.


Actions allow you to hook into any repo event, not just pushes and PRs which could be used for some interesting automation that doesn’t require running and trusting apps.
Even if you’re not interested in that, I think they are worth a look because in my (limited) testing, they run a lot faster than Travis CI and also allow more parallel builds.

If you run into any issues, please open an issue and if you create any Julia-related actions, please share them, I’m interested to see what people use them for!

18 Likes

If you’ve tried them out or are interested in actions, I’d like to hear some input on the following issue that came up about what package CI workflows should look like: https://github.com/julia-actions/julia-runtest/issues/1

1 Like

I have completely moved StringBuilders.jl over to use these new GitHub Actions for its CI testing. So far so good. It seems really fast, plus we get Windows, Mac and Linux all in one service (and all running in parallel).

The current configuration looks like this.

Just be warned: we are still tinkering with the exact design of these actions, so at this point this is probably not super stable in terms of the API of these actions.

10 Likes

The current configuration looks like this .

got 404 :sob:

PkgTemplates.jl has up-to-date example workflows: Testing & Coverage, Testing & Docs deployment

4 Likes

Unfortunately, there seems to be an issue with the julia-actions/julia-uploadcodecov, see, for instance,
GitHub - JuliaGeometry/CoordinateTransformations.jl: A fresh approach to coordinate transformations.... Coverage reports don’t get uploaded. Is there any solution to this? Should I file an issue somewhere?

I’ve actually moved away from the julia-uploadcodecov action and am using the native codecov action instead. Main benefit is that it should work without a token in many cases. You can take a look at what I’m using right now here.

4 Likes

This thread makes it look easy to switch from travis … to github actions. I’m thinking about doing this and am still confused. I almost understand things well enough (I got Greetings Octocat to work) to do the experiment, but don’t want to break what I already have.

Do the normal things (CI + codecov + documenter) “just work” if one makes the obvious changes and follows the templates from @davidanthoff and @SaschaMann? Any gotchas
I should know about? Any downside in switching from travis?

Novice question: You have docdeploy as a separate .yml file. Is that the optimal way to do this? Are you using Documenter.jl? I don’t see the references to version numbers that I would in a .travis.yml file.

Is all this encoded in julia-actions/julia-docdeploy@releases/v1? The example from

https://juliadocs.github.io/Documenter.jl/stable/man/hosting/

has more of the things from .travis.yml. Are they not really needed?

My travis stuff is

include:
    - stage: "Documentation"
      julia: 1.5
      os: osx
      script:
        - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd()));
                                               Pkg.instantiate()'
        - julia --project=docs/ docs/make.jl

For most packages, they should “just work”. The examples in this thread may be a bit outdated, I personally would use PkgTemplates for the CI files, and Documenter docs for deploying docs, and adapt those if necessary.

2 Likes

I got the template from Documenter.jl to work with minimal tweaking. I’m amazed at how much faster my docs are processed now. Very happy so far. Having doc.yml as a stand-alone file makes this stuff easier to keep track of as well.

1 Like

When I do simple updates like correcting typos in README.md, I can put [skip-ci] in the comments to keep travis from doing anything.

Is there a way to do this with github actions?

1 Like

A practical question: this eats up minutes of runtime from the free allowance (practically 3000 for Pro), right? Is there some provision for public repos like Travis?

How does this work out in practice for people, do you ever use up the free tier?

1 Like

It doesn’t. The minutes are only for private repos and not affected by public repos. Public repos are free and not limited

3 Likes

Not natively, but there are some workarounds: https://github.community/t/github-actions-does-not-respect-skip-ci/17325/14

I’ve been using

on:
  push:
    branches:
      - master
    paths-ignore:
      - 'LICENSE.md'
      - 'README.md'
      - '.github/workflows/CompatHelper.yml'
      - '.github/workflows/TagBot.yml'
  pull_request:
    branches:
      - master
    paths-ignore:
      - 'LICENSE.md'
      - 'README.md'
      - '.github/workflows/CompatHelper.yml'
      - '.github/workflows/TagBot.yml'

which means only run CI on PRs or pushes to master (which avoids the issue of pushing to a branch and having CI run on that and on the PR), and ignore any changes which only affect the license, readme, or CompatHelper or TagBot. Not as flexible as [ci skip] since you have to hardcode the list, but on the other hand at least you don’t have to write [ci skip] either.

4 Likes

I didn’t know you could ignore some files, that’s a useful feature that I wish all CI services had!

2 Likes

I just tried this with a commit of a change to README.md and it did not work. What I did was mostly I cut/paste job from your post. Did I miss a space or a tab? My docs.yml file is

name: Documentation

on:
  push:
    branches:
      - 'master'
      - 'release-'
    tags: '*'
    paths-ignore:
      - 'LICENSE.md'
      - 'README.md'
      - '.github/workflows/TagBot.yml'
  pull_request:

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        julia-version: [1.5]
        julia-arch: [x86]
        os: [ubuntu-latest]
    steps:
      - uses: actions/checkout@v2
      - uses: julia-actions/setup-julia@latest
        with:
          version: ${{ matrix.julia-version }}
      - name: Install dependencies
        run: julia --project=docs/ -e 'using Pkg;
              Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
      - name: Build and deploy
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
        run: julia --project=docs --color=yes docs/make.jl

However, after reading the documentation I’m less convinced it’s implemented in a good way. In my opinion it should be “when all modified files match the patters”, instead of “at least of file matches the patterns”

Are you sure that’s the right interpretation? They have this example

A workflow with the following path filter will only run on push events that include at least one file outside the docs directory at the root of the repository.

on:
  push:
    paths-ignore:
    - 'docs/**'

that I thought meant it was doing the right thing (i.e. only skip CI if all the paths are ignored).

1 Like