GitHub Actions were announced late last year. I immediately signed up for the beta and, after a lot of waiting, finally got access. Before long I encountered a real-world use case that let me learn how to put them into action and, lo and behold, they’re pretty great.
The use case I encountered is this: at SchoolStatus we wanted a better way of keeping our customer support team up to date on changes deployed during a sprint, to avoid the problem of them not seeing a change until the end of the sprint or when a customer encounters an issue with something we’d changed. We could just hook up GitHub’s Slack integration to the support team’s channel, but that would result in a lot of noise for them — not everything we do is changelog worthy or even something they’d ever care to know about. So we decided that we could do something to tag certain commits as changelog worthy and then send only those commits to a special “these are the important daily changes to our app” channel.
What We’re Going to Build
What we’re going for here is really, really simple. We want something that looks at every push to the master branch and, if it’s tagged for the changelog, sends a message to a Slack channel.
There are tons of pre-built actions for you to utilize, but I was having trouble stringing them together to do what I needed. For example, there’s a pre-built filter action but it doesn’t allow you to filter based off of commit message content. There’s a pre-built Slack command, but it doesn’t let you send information about the change that caused the action to run. Luckily, writing an action from scratch is pretty darn easy.
How to Build It
Actions live inside of a .github
directory in your project’s root. Once you’ve created that,
go ahead and add a file named main.workflow
. If you’ve played with their visual
builder, then it’s worth noting that all you’re really doing via the visual builder is modifying
this file.
In this file, put the following:
This is defining a new workflow that fires on push events. The resolves
keyword points to the action that we’ll actually be running, “Commit Message Filter”. Inside
of the action, uses
points to the code that’s going to be run for this action. You can check out the
documentation for creating an action
here.
In there, it gives us this as an example directory structure:
It’s worth noting that I actually put my action inside of my .github
directory. It ended
up looking like this:
You can go with whatever structure you want — just make sure that you adjust your
path in the main.workflow
file from above.
While we’re talking about how you can do whatever you want with the directory structure, let’s stop and talk about the main takeaway from this whole experience. Guess what: you’re just writing a Dockerfile, with which you can really do whatever you want. It’s really that simple.
Easy example: you’ll notice that the documentation on GitHub has an entrypoint.sh
file while
my example has entrypoint.rb
. When I started on this process I was attempting to link all
sorts of actions together and it was just a little too painful… but then I realized I could
just do it all in one Ruby script. Why make something complicated when it can be
simple? You’re just writing a Dockerfile and a script.
So with that in mind, here’s my Dockerfile:
All it’s really doing is setting me up with Ruby, tacking on a few labels like GitHub tells us to do, and then setting our entrypoint.
Then, for our entrypoint, we can just write a script like we would for anything else:
I’m still working on making this all work in real life, and nobody else on my team has
looked at it, so criticism
is more than welcome. The thing you really want to take note of are the environment variables
like ENV['GITHUB_EVENT_PATH']
that holds all of the event information about the event that
caused the action to run. This environment variable is one provided by
GitHub
to give us information about what’s going on in the action. The other places you see me
using env vars are actually me using
secrets
I’ve set on the action.
Note that secrets seem to be universal - once you add one to any action in a workflow, you’re able to share it across other actions in the workflow but you have to click the action and mark a checkbox to give the action permission to use the secret.
The last thing to note are the exit 78
calls in my run
method. There are a couple of
exit codes
you can use to return different statuses for your action.
Overall, my main takeaway was that, wow, we’re just writing a Dockerfile with which we can pretty much do anything we want. Once you wrap your head around that, it’s easy to let your imagination see a million neat things you can do with GitHub Actions. If you’re short on ideas, check out this talk from re:Invent this talk by Jess Frazelle, Clare Liguori, and Abby Fuller in which they discuss a neat way to handle giving easy environments to preview pull requests. I’ve already thought of a couple of different ways I’m going to use this at work, and I’m really excited to see all of the ways they end up being used.