Scripting Bits
Published in

Scripting Bits

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.

For JavaScript projects today, the CI workflow looks something like: provision a Docker container and then run

git clone
cd my-repo
yarn test

Travis CI has done an excellent job of knowing which commands to run for a large number of programming languages and frameworks. For my typical JavaScript project, my .travis.yml looks like:

language: node_js
node_js: node

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)
  • Run yarn and yarn test

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.

GitHub Actions

Ok! I’m going to convert one of my projects over to GitHub Actions.

Current Setup

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:

  • on specifies when to execute the jobs in the workflow
  • jobs a 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.
  • strategy enables running the same job with different parameters in parallel. This is exactly like the build matrix feature offered by Travis CI.
  • runs-on allows 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.
  • services a 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
  • uses allows folks to share and reuse steps in a job. I think this is a lot more convenient than chaining Docker images together with FROM or 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 and 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 current or lts. Fortunately, this is on their radar.

Comparing the build times between Travis CI and GitHub Actions, I notice that GitHub Actions is 30 seconds (or 20%) faster.

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



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store