Build your own GitHub Action with a Docker Container
Tags: github, devops, githubactions, docker
Published: 2021-02-16 19:59:00

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](https://lab.github.com/githubtraining/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.

```sh
// 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.

```sh
// 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](https://octokit.github.io/rest.js/v18/) library or better [github-script](https://github.com/actions/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](https://github.com/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:

{% youtube NRCqL9ifpcw %}

_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._

{% link https://dev.to/github/generate-your-own-github-action-with-the-actions-toolkit-cli-1lno %}