Thanks to a pull-request "Install TagBot as a GitHub Action", which was created by a bot, I realized now is the time to move one of my Julia projects, Recommendation.jl, from Travis CI to GitHub Actions.
Since I haven't had enough time to work on the project for a year, migration was not straightforward as I expected. Hence, this post summarizes what I've undergone to get there. As always, I referred to some of the most actively/recently maintained official Julia packages (e.g., Statistics.jl, Tokenize.jl) to see what is the most 'modern' way to organize a Julia project.
Original .travis.yml
I've written the following Travis CI configuration more than a year ago:
language: julia
os:
- linux
- osx
julia:
- 0.7
- 1.0
- nightly
matrix:
allow_failures:
- julia: nightly
notifications:
email: false
after_success:
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
jobs:
include:
- stage: "Documentation"
julia: 1.0
os: linux
script:
- julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd()));
Pkg.build("Recommendation");
Pkg.instantiate()'
- julia --project=docs/ docs/make.jl
after_success: skip
The workflow breaks down into three pieces:
- Unit testing over multiple Julia versions
- Profiling test coverage
- Building and publishing a documentation page to GitHub Pages
Running a Workflow over multiple Julia versions
First and foremost, what I like about GitHub Actions is the easiness of using a build matrix.
For every pull-requests onto the master branch, as well as push event to the master with an arbitrary tag, the following workflow executes 3x3=9 jobs for 3 Julia versions and 3 operating systems:
name: CI
on:
pull_request:
branches:
- master
push:
branches:
- master
tags: '*'
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- '1.0'
- '1' # automatically expands to the latest stable 1.x release of Julia
- 'nightly'
os:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x64
steps:
# (actual tasks are defined here)
Having a comprehensive build matrix is particularly important for Julia because Julia is one of the rare programming languages that aggressively introduce backward-incompatible changes as the version number grows.
Notice that I dropped Julia 0.7 from the matrix when I switched out the Travis config with GitHub Workflow; considering the stable version is 1.5.3 as of Nov 2020, it's reasonable not to support Julia < 1.0 anymore.
Testing and reporting coverage
Next, we could leverage julia-actions/julia-runtest and julia-actions/julia-processcoverage as follows:
jobs:
test:
# (define a build matrix - see above)
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
file: lcov.info
As long as your repository is registered to Codecov.io, test coverage is automatically reported in a pull-request. See this comment as an example.
Documenting and hosting on GitHub Pages
Finally, we can define a dedicated job for building and publishing a documentation page using Documenter.jl.
Luckily, there is an official step-by-step guide: Hosting Documentation, and the definition of the job looks like:
jobs:
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- run: |
julia --project=docs -e '
using Pkg
Pkg.develop(PackageSpec(path=pwd()))
Pkg.instantiate()'
- run: julia --project=docs docs/make.jl
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
DOCUMENTER_DEBUG: true
secrets.GITHUB_TOKEN
is automatically set by GitHub Workflow.
Meanwhile, secrets.DOCUMENTER_KEY
can be generated as explained in Authentication: SSH Deploy Keys and be configured as a custom GitHub repository secret at: https://github.com/{user}/{repository}/settings/secrets/
.
It is important to note that we should accordingly update TagBot Workflow:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
+ ssh: ${{ secrets.DOCUMENTER_KEY }}
Moreover, in case you're using an old version of Documenter.jl like me, you probably need to update the version in docs/Project.toml
first of all because GitHub Actions are supported since Documenter.jl 0.24:
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
[compat]
- Documenter = "~0.20"
+ Documenter = "0.24"
That's all, and here is a complete set of GitHub Actions Workflows for my Julia project.
Share
Categories
See also
- 2019-07-26
- Lightning Talk about Recommender Systems in Julia at #JuliaCon 2019
- 2019-03-31
- Publishing My Master's Thesis with Documenter.jl
- 2017-06-26
- Deploying Static Site to GitHub Pages via Travis CI
Last updated: 2022-08-06
Author: Takuya Kitazawa
Takuya Kitazawa is a freelance software developer based in British Columbia, Canada. As a technologist specializing in AI and data-driven solutions, he has worked globally at Big Tech and start-up companies for a decade. At the intersection of tech and society, he is passionate about promoting the ethical use of information technologies through his mentoring, business consultation, and public engagement activities. See CV for more information, or contact at [email protected].
Now Gift a cup of coffeeDisclaimer
- Opinions are my own and do not represent the views of organizations I am/was belonging to.
- I am doing my best to ensure the accuracy and fair use of the information. However, there might be some errors, outdated information, or biased subjective statements because the main purpose of this blog is to jot down my personal thoughts as soon as possible before conducting an extensive investigation. Visitors understand the limitations and rely on any information at their own risk.
- That said, if there is any issue with the content, please contact me so I can take the necessary action.