Using babashka for GitHub Actions

Tzafrir Ben Ami
4 min readAug 5, 2020

I wanted to play around with GitHub Actions for some time but didn’t find the “proper” opportunity to do so. Lately I had the chance to create a new GitHub Action that executes a babashka script, and since I couldn’t found a similar one in GitHub marketplace, I’ve decided to publish it to the marketplace.

Image from GitHub Actions page

Please note that the purpose of this post is not to “teach” you how to create GitHub Actions and workflows (you can read more about it in the GitHub documentation) nor do I pretend to be expert of it. My goal here is to provide a general overview of what actions are and how you benefit from using it in your project(s).

TL;DR you can access the final output of this post in this GitHub repository or in the GitHub Actions marketplace.

GitHub Actions

In a nutshell, GitHub Actions allows you to automate your software development life cycle (SDLC) process. If you used to abstract GitHub as “just” a place to host and manage your Git repositories (with some cool collaboration tools), while the rest of your development life cycle takes place somewhere else (Jenkins for CI/CD as an example) — you can now use GitHub Actions to manage many of those SDLC tasks directly in your Git repository.

Let’s take a common real-life continuous integration (CI) workflow: each time someone in a development team commits new code, the integrity of the new code is being evaluated by running the project unit-tests and performing some code analysis using a linter or similar tool(s). Those CI jobs runs on a Jenkins server and triggered when the new code is pushed to the project Git repository. You might use a different CI server or have an additional jobs in your CI workflows, of course, but those are very common tasks.

With GitHub Actions, you can execute the CI jobs directly in your Git repository without using an external CI server. You can also trigger CI tasks on a pull request or have a much more complex workflow like spin up new EC2 spot instances on AWS and execute end-to-end tests (it can be accomplished with other CI tools like Jenkins as well, of course). This example is not a suggestion to ditch your CI server and migrate with GitHub Actions, there are obviously other factors and dependencies to this decision, but can help you understand what GitHub Actions are and its capabilities.

There’s much more to say about GitHub Actions, but this is a deep as we’ll dive in this post (if you want more details, the official docs are great or you can follow some blog posts that guide you through the actual steps of creating workflows). I would mention, however, that GitHub Actions can run on a custom Docker container, which means that it can support using basically any programing language in your workflows.

Babashka (Clojure)

babashka was developed by Michiel Borkent as a scripting language on top of Clojure:

The default GitHub-hosted Ubuntu runners do have Leiningen installed, so you can potentially use lein run in order to execute a Clojure app in your workflows. But, as stated in the babashka documentation, writing a Clojure app to accomplish “simple” tasks is probably an overkill. If you are well familiar with Bash, you might be able to write most of your workflows using Bash. Other scripting languages such as Python\PHP\Ruby are also available in by default in the virtual environment if you are familiar with it.

However, if you’re coming from a Clojure background and you’re not really a Bash ninja, yet you need some complex scripting capabilities in your workflows, a babashka script can be very handy. Just think of writing a Bash script to validate your project edn files, or convert JSON to edn for some reason. Might be a bit complex for a Bash script, but pretty straightforward using babashka.

Put it all together

Now that we understand the need (hopefully), there’s still a minor yet important step of pulling it all together. Since GitHub Actions support creating a Docker container action and there’s is already an official babashka Docker image, we can use both in order to create a Docker container with babashka installed and execute babashka scripts on it.

Once we have that Docker image, the next step would be to create an entrypoint script that will execute our workflows. To implement the entry point script I’ve used the fact that babashka is installed on the Docker container and wrote a babashka script that will get the babashka script and arguments to execute.

The babashka GitHub Actions can handle few optional arguments documented in its README. The main idea was to enable users to execute both a script hosted in the Git repository and from remote repositories as well (as long as the script is public and can be fetched from the remote repository)

“Tell me and I forget. Teach me and I remember. Involve me and I learn.”

Benjamin Franklin

Following those wise words, please feel free to let me know what you think of the babashka GitHub Actions, send any feedback\issues\suggestions you might have

--

--

a "Full stack technology leader", trying to solve complex business problems with technology - mainly on the Web and large-scale systems (but not just)