Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

GitHub Actions SDK (Go)

GoDoc GitHub Actions

This library provides an SDK for authoring GitHub Actions in Go. It has no external dependencies and provides a Go-like interface for interacting with GitHub Actions' build system.


Download the library:

$ go get -u


The easiest way to use the library is by importing it and invoking the functions at the root:

import (

func main() {
  val := githubactions.GetInput("val")
  if val == "" {
    githubactions.Fatalf("missing 'val'")

You can also create an instance with custom fields that will be included in log messages:

import (

func main() {
  actions := githubactions.WithFieldsMap(map[string]string{
    "file": "myfile.js",
    "line": "100",

  val := actions.GetInput("val")
  if val == "" {
    actions.Fatalf("missing 'val'")

For more examples and API documentation, please see the Go docs.


There are multiple ways to publish GitHub Actions written in Go:

By default, GitHub Actions expects actions to be written in Node.js. For other languages like Go, you need to provide a Dockerfile and entrypoint instructions in an action.yml file:

# your-repo/Dockerfile
FROM golang:1.18
RUN go build -o /bin/app .
ENTRYPOINT ["/bin/app"]
# your-repo/action.yml
name: My action
author: My name
description: My description

  using: docker
  image: Dockerfile

And then users can import your action by the repository name:

# their-repo/.github/workflows/thing.yml
- name: My action
  uses: username/repo@latest

However, this will clone the entire repo and compile the Go code each time the action runs. Worse, it uses the Go base container which is a few hundred MBs and includes a ton of unnecessary things.

Fortunately, GitHub Actions can also source from a Docker container directly from Docker Hub:

- name: My action
  uses: docker://username/repo:latest

Now we can precompile and publish our Go Action as a Docker container, but we need to make it much, much smaller first. This can be achieved using multi-stage Docker builds:

FROM golang:1.18 AS builder

  GOOS=linux \

RUN apt-get -qq update && \
  apt-get -yqq install upx

COPY . .

RUN go build \
  -ldflags "-s -w -extldflags '-static'" \
  -o /bin/app \
  . \
  && strip /bin/app \
  && upx -q -9 /bin/app

RUN echo "nobody:x:65534:65534:Nobody:/:" > /etc_passwd

FROM scratch

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /etc_passwd /etc/passwd
COPY --from=builder --chown=65534:0 /bin/app /app

USER nobody

The first step, uses a fat container to build, strip, and compress the compiled Go binary. Then, in the second step, the compiled and compressed binary is copied into a scratch (bare) container along with some SSL certificates and a nobody user in which to execute the container.

This will usually produce an image that is less than 10MB in size, making for much faster builds.