Ramblings of a Tampa engineer
A figurine of an oktokat in the center, in the background a laptop with the main page of the GitHub open.
Photo by Roman Synkevych / Unsplash

GitHub Actions when it launched saved me from an honestly dated Jenkins experience and Travis CI crippling its service to favor towards the enterprise community.

I moved all my hobby projects and work projects from PHP testing, Laravel deployments, Apktool building, AWS CodeDeploy, JavaScript linting and much more.

After a solid amount of time, I've got a good deal of random features I really wish would make it into Actions.


Secrets per branch

GitHub (secrets vs environment secrets)

There is an immediate problem you run into when working in private projects and also moving your deployments to the system. It may be AWS keys or some secret, but any repository secret is ripe for abuse.

It just takes 1 person adapting the workflow on their own branch and they can have access to that secret to do whatever they want. GitHub in the past year has produced something to resolve this called Environments, which is only available to GitHub Enterprise or public repositories.

The short version of Environment Secrets is you define the branches allowed to access that secret. So imagine you create a key used to deploy to production, you can only expose that secret to production. Assuming proper merge restrictions are set up - there is no way that secret could be exposed to anything but code running on production.

The downside - it took upgrading to Enterprise from Pro to get this feature. GitLab had this since I remember using GitLab CI.


Rerunning a single job

GitLab rerunning a specific job.

At some point you'll have a complicated job. It may run various versions of PHP to lint/test in some complex matrix. If you get a random internal error - your build fails and thus deployment is skipped. However, you can't re-run the single failed step (Like GitLab can). So you have to restart the entire build and as far as I can tell - you incur the charges of all the minutes used again. Even if the original failure was an issue from the GitHub side.


Specifying specific OS versions

When you run a GitHub Action build - you basically select Linux, Mac or Windows including a specific major version if using their runners. This example will be on Ubuntu 20.04 so when I run a build - I see the following:

Virtual Environment
  Environment: ubuntu-20.04
  Version: 20210913.1

This corresponds to a specific version that is released on a pattern by GitHub. They keep things up to date, update the underlying images and much more. One thing I have noticed and never ever once experienced on GitLab was regressions.

The comparison isn't fair though. A GitLab CI file can be built in many ways and I've used the Docker runner for all my uses. So locking an image like in GitLab has the same possibility for the php docker image tag of 7.4 to update and include a new minor change that is unaccounted for.

However, the motto with GitHub Actions is to not use Docker for each step as the minutes really add up. Its more beneficial to use the host machine and run/install what is needed.

Now what has happened 3 times is a minor version update of the OS that is not configurable by me has updated and broken our builds. I'm not alone and this happens semi often and is resolved quite quickly, but still itches my brain. I'm not sure if the solution is supporting minor versions or having more automated checks, but our builds failing randomly and how crucial they are to work becomes a major problem.


YAML Features

GitHub is YAML, much like GitLab and one thing I've noticed is GitHub does not support any of the cool features like templates, anchors and aliases when it comes to writing workflows.

The matrix feature can help a bit, but after building some real complete workflows. I guarantee you'll want some of the interesting YAML features. Now I have to deal with a lot of duplicated logic across many workflows and any enhancement takes way longer to port to every location vs updating a few templates.


The Text Oddities

I don't know if folks have noticed, but if the build is running on a long running step and you load that workflow. Chances are the text of that specific step will not load till its complete. If you watch the build from the beginning - no issue.

This happens nearly every time for me, so it must be some bug with how text renders in GitHub Actions when you open a build while its on a step. So if you have a build running on a long deployment step and open it up to check progress. Chances are it will refuse to show anything and you have to debate waiting endlessly with no output or cancel it.


Cross Workflow Dependencies

GitHub Workflow

As workflows become more complex you'll have a natural extinct to split them up. Since it would be pretty cool to have a separate workflow for linting, testing and deployment.

However, you cannot do that as you can only depend on jobs within your own workflow. As builds get more complex - you might be looking at 1000 line+ files. While you could wire up talking to the actual GitHub API and attempt to replicate the behavior of same workflow in multiple files the pure overhead for that would tempt most away.

Additionally, if cross workflow depending worked you could easily put different code owner protections in place for the deployment process while letting others tweak/adapt the linting/testing process.


Overall Status

One thing I quickly encountered is wanting to build a Slack notification on complete of the build - including the pass/fail/cancelled status. At first I thought I could use $GITHUB_STATUS to include the status of the entire build, but it does not work as I expect.

Imagine a workflow where you have the deployments at the end (if applicable) since as you know - you can't have split workflows. So if this is a build that is not going to be deployed and you put your Slack call at the end - it never completes.

If you include all the previous jobs as requirements so it doesn't fire immediately - it won't fire since a previous step was not completed. If you adapt the call to allow any output, then how do you determine if it was pass/fail? I haven't found a way since $GITHUB_STATUS is misleading.

It seems a generic property of "This is the build status up to this point of any workflow that ran" would be pretty swell. The skipped jobs are natural all the time so they should not be counted.


In closing, GitHub Actions is swell and it can't be expected that it will have all features that Jenkins has had for a decade. It'll get there, but until then I'll have a wishlist.

You’ve successfully subscribed to Connor Tumbleson
Welcome back! You’ve successfully signed in.
Great! You’ve successfully signed up.
Success! Your email is updated.
Your link has expired
Success! Check your email for magic link to sign-in.