Github Actions in Practice

Review of the GitHub Actions beta

BitBucket has held my repos for years, primarily due to their free unlimited private repos, and more recently, their excellent CI offering. On the whole, I prefer GitHub's user experience, so you can imagine my excitement to see GitHub's announcement of free unlimited private repos, and a platform-native option for automation.

Here are some of my initial thoughts after exploring the beta of GitHub Actions a bit. My review frequently uses Bitbucket Pipelines as a point of reference, since it's one of the largest competing offerings. (GitLab also has a fantastic CI product, so I've heard.)

Getting Started

Opening the newly added Actions tab of your repository provides an easy way to get started, with a “Create a new workflow” button.

Clicking create workflow brings you a standard GitHub UI for editing a file, with a twist—you're presented with a visual editor, prompting you to create your first action.

As you'll note, the underlying workflow file is dropped into ./.github/main.workflow. GitHub will prompt you to open the visual editor when adding files named .workflow to this directory.

Dragging to create an initial action prompts you with a list of actions. Searching the list of actions, which are based on Docker containers. According to the GitHub docs, you'll be able to use any Docker containers to run actions inside.

For the purposes of this experiment, I'll be publishing this Hugo-based blog to an S3 bucket. My first search in this direction was for a Hugo action for compiling my blog before pushing it to S3. My search turned up nothing, but a visit to the GitHub Marketplace turned up Hugo Actions which is exactly what I'm looking for. Searching the Marketplace for actions directly from the Visual Editor would've been very useful in this case.

After adding the action to my workflow, I'm given a few configuration options.

Adding a label is a useful way to identify the step within the pipeline, but runs and args are not what I was expecting to see. In the context of ‘actions as containers’ these options make sense, but I was hoping to be able to drop in short scripts to run in the context of the container. As it stands, GitHub seems to intend actions to be used as one-off commands within a larger workflow. This is far from ideal for more complex workflows, as you'll either need to separately build a custom Docker image to execute your script, or break up your script into discrete ‘actions’.

Now that the static assets for my site are being built, I need to deploy them to S3 via the AWS CLI. As you'd expect, the environment context is shared between actions. I will note that (based on the logs) the environment context doesn't appear to be copied between containers running your actions, which is very useful.

Searching through the list of actions for a pre-created AWS action turns up a GitHub Action for AWS. A few environment variables later, here's what I'm looking at:

Thanks to s3 sync, I'm able to upload my site static assets with one command, no abusing of the runs parameter needed.

Committing the file kicks off the build, and we're off to the races. Unfortunately, it was at this point that I realized I forgot to update the S3 bucket used by the AWS command, and my workflow was updating my production bucket. Turns out there's no cancel button for workflows!

A log is provided with each action, but unfortunately you don't have access to the log until the build is complete.

Complete pipeline runs (as measured by GH Actions) consistently took less than 45 seconds, although this is a fairly light workload.

Conclusions

Needing to break up your CI pipeline to fit into into discrete actions is a major detractor from the platform. There doesn't seem to be any feasible solutions for even moderately complex workloads. A simple freeform action that takes a Docker image and a short script would work wonders here.

While experimenting with the platform, I ran into a situation where the Docker image I specified couldn't be pulled. The action was marked failed, but there was no indication as to the underlying failure and no logs were available.

Secrets for actions are easily added, and manageable with a dedicated section in the Settings tab. Unfortunately, environment variables didn't receive the same treatment, and you'll have to manually copy and paste them between actions if you'd like to share them.

On the whole, I was quite impressed with the amount of polish that's gone into this product. I only experimented with the push trigger for this article, but many different types of triggers are supported and the possibilities for automation are quite intriguing. Easy sharing of Actions via the GitHub Marketplace will become more and more useful as time goes on and more Actions are added.

Further Reading

GitHub's workflow configuration options provide a great deal of useful info on the workflow files themselves.