Getting Started #
In this article you are going to learn how to create a custom GitHub Action in Go. GitHub provides us two ways to build custom GitHub Actions, you can either build actions using JavaScript š© or you can use Docker š³. I am going to use Docker + Go to build custom GitHub Action, while doing so I will point out some important things to take note of.
This articles assumes the following pre-requisites:
- You know what GitHub Actions are and you have used them before.
- You have basic understanding of Docker.
Writing Go Code #
For now lets keep the code simple and just print a message. Create a main.go
file and add the following code to it.
package main import "fmt" func main() { fmt.Println("Hello World From GitHub Action") }
main.go
Writing Dockerfile #
There is no need to do anything specific for the Dockerfile
, all you need is a regular docker image that runs the go code. Create a new Dockerfile
and add the following code to it.
FROM golang:1.18.3-alpine3.16 WORKDIR /app COPY ./ ./ RUN go build -o /bin/app main.go ENTRYPOINT ["app"]
Dockerfile
You might have noticed that (RUN go build -o /bin/app main.go
) when building the go code the executable is being stored inside the bin
directory. This is not a requirement, you can store the executable wherever you want.
Writing action.yml #
action.yml
is the file that tells GitHub "Hey GitHub! This repository contains a GitHub Action". You can define a lot of metadata related to the action in this file. I highly recommend to give this documentation a read if you are developing a GitHub Action š Metadata syntax for GitHub Actions.
Create a new action.yml
file and add the following code to it.
name: "github-action-go" description: "An example of building github actions with Go" runs: using: docker image: Dockerfile
action.yml
The runs
section is the one where you can specify to GitHub to run this action using Docker.
Publishing the Action #
Now you are all set to go, create a new repository and push the code. Before you can use an action you need to publish it by creating a release on GitHub. On the repository click on create a new release.
You will need to create a tag before the release, create a tag named v1
(you can name it whatever you want but keeping proper versions is highly recommended).
Give the release a title and click on Publish Release.
Using the Action #
Once the release is created you can start using the action in any github repositories, an example workflow file would look something like this:
jobs: github-action-go: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: gurleensethi/github-action-go@v1 # š using custom action
.github/workflows/workflow.yml
You can also use your custom action in the same repository as the action itself.
jobs: github-action-go: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: ./ # š using action from the repository itself.
.github/workflows/workflow.yml
How GitHub runs Docker actions #
Since the action is supposed to run in as a docker container GitHub uses the docker run
command to run it, it provides a bunch of arguments. Brave yourself to see the giant command.
docker run --name e225889822a53557c5068f1d4400b154c_a1b5de --label 72882e
--workdir /github/workspace --rm -e HOME -e GITHUB_JOB -e GITHUB_REF -e GITHUB_SHA
-e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER -e GITHUB_RUN_ID
-e GITHUB_RUN_NUMBER -e GITHUB_RETENTION_DAYS -e GITHUB_RUN_ATTEMPT
-e GITHUB_ACTOR -e GITHUB_WORKFLOW -e GITHUB_HEAD_REF -e GITHUB_BASE_REF
-e GITHUB_EVENT_NAME -e GITHUB_SERVER_URL -e GITHUB_API_URL -e GITHUB_GRAPHQL_URL
-e GITHUB_REF_NAME -e GITHUB_REF_PROTECTED -e GITHUB_REF_TYPE -e GITHUB_WORKSPACE
-e GITHUB_ACTION -e GITHUB_EVENT_PATH -e GITHUB_ACTION_REPOSITORY
-e GITHUB_ACTION_REF -e GITHUB_PATH -e GITHUB_ENV -e GITHUB_STEP_SUMMARY
-e RUNNER_OS -e RUNNER_ARCH -e RUNNER_NAME -e RUNNER_TOOL_CACHE -e RUNNER_TEMP
-e RUNNER_WORKSPACE -e ACTIONS_RUNTIME_URL -e ACTIONS_RUNTIME_TOKEN
-e ACTIONS_CACHE_URL -e GITHUB_ACTIONS=true -e CI=true
-v "/var/run/docker.sock":"/var/run/docker.sock"
-v "/home/runner/work/_temp/_github_home":"/github/home"
-v "/home/runner/work/_temp/_github_workflow":"/github/workflow"
-v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands"
-v "/home/runner/work/github-action-go/github-action-go":"/github/workspace" 72882e:225889822a53557c5068f1d4400b154c
There is bunch of good stuff here, it sets the working directory --workdir /github/workspace
, passes a bunch of environment variables using the -e
flag and attaches a lot of volumes. Give this command a good read it might help you in something you are developing.