Build your own GitHub Action with a Docker Container
Brian Douglas
Posted on February 16, 2021
GitHub Actions is a powerful platform that empowers your team to go from code to cloud, all from the comfort of your repositories.
In this post, I will briefly walk through how you can build a reusable GitHub Action using a Dockerfile.
If you would like to go into more detail, check out the GitHub Actions: Write Docker container actions course.
Begin
Most GitHub Actions are open source GitHub repos, making it easy to search and discover community-built Actions. To create your own action, you will start by creating a GitHub repo, and in that repo, you will need a Dockerfile. You do not need to be an expert on Docker, but at a high-level, Docker will make it possible to run your code as a script.
In this action, the Docker image (alpine) will provide an environment to run a bash script. So far now, we can put some Docker stuff in the Dockerfile and move on.
One this to point out is the creation of the ENTRYPOINT. An entrypoint.sh
will be the place we write our bash. This could be an index.rb
or index.js
if a different language is preferred. The biggest thing we need is an executable file for the entrypoint.
I also want to explain executable and what that means. It just means I can run this from the command line only using the file path. It's helpful for easy scripting. There are other languages that we could have written this in to make executable is like example go and for the sake of explanation and the fact that I already had this code written out in mash, we're going to stick with bash today.
// Dockerfile
FROM alpine
RUN apk add --no-cache jq
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
The bash code below retrieves a few items from the GITHUB_EVENT_PATH, one of the standard environment variables in the actions runner. The code also includes a conditional for the comment body confirming that it includes the .take
keyword.
// entrypoint.sh
#!/bin/sh
BODY="$(jq '.comment.body' $GITHUB_EVENT_PATH)"
ISSUE_NUMBER="$(jq '.issue.number' $GITHUB_EVENT_PATH)"
LOGIN="$(jq '.comment.user.login' $GITHUB_EVENT_PATH | tr -d \")"
REPO="$(jq '.repository.full_name' $GITHUB_EVENT_PATH | tr -d \")"
if [[ $BODY == *".take"* ]]; then
echo "Assigning issue $ISSUE_NUMBER to $LOGIN"
echo "Using the link: https://api.github.com/repos/$REPO/issues/$ISSUE_NUMBER/assignees"
curl -H "Authorization: token $GITHUB_TOKEN" -d '{"assignees":["'"$LOGIN"'"]}' https://api.github.com/repos/$REPO/issues/$ISSUE_NUMBER/assignees
fi
Note at the end of the bash, and we are leveraging a curl command to talk directly to the GitHub API. This curl command is meant for simplicity. All of this could have been done using the octokit.rest.js library or better github-script.
And now you can push this to GitHub to test it from a repo. I leverage this actual action in my repo bdougie/take-action got a response back from my action, it looks like it worked okay.
If you are interested in the full version of this tutorial, this was an excerpt from my previously recorded video on YouTube:
This is part of my 28 days of Actions series. To get notified of more GitHub Action tips, follow the GitHub organization right here on Dev.
Posted on February 16, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.