Trying GitHub Actions
And reflecting on past experiences with CI tooling
Up To Now
I’ve been using CI/CD workflows with my projects since 2012. When I choose a CI service, some important points of comparison have been:
For open source projects, CI services tend to be free, as established very early on by Travis CI. Pricing for private projects, however, vary quite a bit — from free with CircleCI to $63 per month with Travis CI. And, for companies opposed to using externally hosted services, self hosted CI products, which are generally open source, are popular as well.
I remember that for many of my new but private projects, the team chose CircleCI solely for its free price tier.
Ease of Configuration
Almost all of the programming languages I’ve encountered have a standardized way of running tests, and if they don’t, they have one or two popular frameworks that do.
git clone https://github.com/vinsonchuong/my-repo
.travis.yml looks like:
I just have to declare my language and the version of Node.js to use (usually the newest version).
At the other end of the spectrum, with self-hosted products like Jenkins or Concourse, after figuring out how to install the product, configuring it to build a project looks like:
- Install git if it isn’t installed.
- Generate and share SSH keys for accessing the repository.
- Clone the repository.
- Install an interpreter for the programming language the project is using (and make sure that it stays current)
Usually, some percentage of the above needs to happen in a Docker image, requiring project teams to learn Docker and find somewhere to host their Docker images.
Ideally, all of these steps should be automatic, if not out-of-the-box by the product, then through sharable plugins.
Availability of Specific Features
Products like Concourse are built to support complex workflows for large teams or organizations. Some of them come with specialized features, like pipelines.
In my experience, any specialized features that get popular tend to be added to other products and services pretty quickly.
Overall, my go-to has always been Travis CI for its ease of configuration. But, it’s frequent downtime has left me wondering for a while if I should be looking for something more reliable.
Ok! I’m going to convert one of my projects over to GitHub Actions.
This is an open source project running on Travis CI. The configuration is:
yarn release uses semantic-release to publish the package to npm and the documentation to GitHub Pages. A GitHub token and an npm token are provided via secure environment variables.
Figuring Out How to Get Started
In the “Actions” tab of my GitHub repo, I see:
When I click on “Set up this workflow” for “Node.js”, it takes me to an editor with some pre-filled configuration:
After a bit of searching, I find some documentation for their configuration syntax. Skimming through, some salient points include:
onspecifies when to execute the jobs in the workflow
jobsa list of jobs that get run in parallel along with the ability to configure a job to run only after another job is finished. This is exactly the pipelines feature first introduced by Concourse.
strategyenables running the same job with different parameters in parallel. This is exactly like the build matrix feature offered by Travis CI.
runs-onallows me to specify the machine to run jobs on. This allows me to run jobs on Linux, OSX, Windows, or even an external server that I own.
servicesa list of Docker images to use alongside a running job, e.g. one that runs a database. Services was something that CircleCI did really well
usesallows folks to share and reuse steps in a job. I think this is a lot more convenient than chaining Docker images together with
FROMor learning how to manage Concourse resources.
For managing credentials, GitHub Actions requires me to add them in their UI and then refer to them in my configuration files. I like how Travis CI allows me to manually encrypt and store credentials in my configuration file — it keeps everything in one place and allows for programmatic adding of credentials.
I’ll have to wait for GitHub to add an API endpoint for managing secrets before I can completely automate the bootstrapping of a Node.js project.
Here’s my GitHub Actions config:
Comparing Old and New
Comparing the configuration syntax, both are concise and readable. The GitHub Actions configuration file is 8 lines longer due to having to specify:
name, which is fine since we can have different kinds of workflows.
on, which is also fine since we can work with more than just commits.
uses: actions/cache@v1: I can probably extract this into its own reusable plugin to save 4 lines here.
run: yarn test: Travis CI is able to infer these two commands as soon as we specify
language: node_js, but I appreciate the explicitness, especially since GitHub Actions isn’t focused solely on CI.
I don’t like having to explicitly specify the version of Node.js. I would rather specify
lts. Fortunately, this is on their radar.
Comparing pricing, both are free for open source projects, but GitHub Actions provides a free tier for private projects, which seems more than sufficient to build a small project for free indefinitely.
GitHub Actions also provides badges.
My New Go To
GitHub Actions compares well against Travis CI and other CI products I’ve used. It has every other product’s features. It’s pricing for private projects seems good as well, especially compared to Travis CI.
A few issues have to be addressed before I can switch all of my other projects over though:
- Ability to programmatically add secrets
- Ability to specify the latest stable or LTS version of a language interpreter