Skip to content
GitHub Actions as CI for Go
Branch: master
Clone or download

GitHub Actions for Go

GitHub Actions includes CI/CD for free for Open Source repositories. This document contains information on making it work well for Go. See them in action:

$ cat .github/workflows/test.yml
on: [push, pull_request]
name: Test
        go-version: [1.12.x, 1.13.x]
        platform: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.platform }}
    - name: Install Go
      uses: actions/setup-go@v1
        go-version: ${{ matrix.go-version }}
    - name: Checkout code
      uses: actions/checkout@v1
    - name: Test
      run: go test ./...


Each workflow file has a number of jobs, which get run on specified events.

Each job runs on a configuration matrix. For example, we can test two major Go versions on three operating systems.

Each job has a number of steps, such as installing Go, or checking out the repository's code.


What about module support?

If your repository contains a go.mod file, Go 1.12 and later will already use module mode by default. To turn it on explicitly, set GO111MODULE=on.

How do I set environent variables?

They can be set up via env for an entire workflow, a job, or for each step:


How do I set up caching between builds?

We haven't been able to find a simple way to accomplish this. It would be useful to persist Go's module download and build caches.

How do I run a step conditionally?

You can use if conditionals, using their custom expression language:

- name: Run end-to-end tests on Linux
  if: github.event_name == 'push' && matrix.platform == 'ubuntu-latest'
  run: go run ./endtoend

How do I set up a custom build matrix?

You can add options to existing matrix jobs, and you can exclude specific matrix jobs.

How do I run multiline scripts?

- name: Series of commands
  run: |
    go test ./...
    go test -race ./...

Should I use two workflows, or two jobs on one workflow?

As far as we can tell, the only differences are in the UI and in how each workflow can be triggered on a different set of events. Otherwise, there doesn't seem to be a difference.

How do I set up a secret environment variable?

Follow these steps to set up the secret in the repo's settings. After adding a secret like FOO_SECRET, use it on a step as follows:

- name: Command that requires secret
  run: some-command
    FOO_SECRET: ${{ secrets.FOO_SECRET }}

How do I install private modules?

It's possible to install modules from private GitHub repositories without using your own proxy. You'll need to add a personal access token as a secret environment variable for this to work.

- name: Configure git for private modules
  run: git config --global url."https://YOUR_GITHUB_USERNAME:${TOKEN}".insteadOf ""

How do I install Linux packages?

Use sudo apt, making sure to only run the step on Linux:

- name: Install Linux packages
  if: matrix.platform == 'ubuntu-latest'
  run: sudo apt update && sudo apt install -y --no-install-recommends mypackage

How do I set up a GOPATH build?

Declare GOPATH and clone inside it:

      GOPATH: ${{ runner.workspace }}
      GO111MODULE: off
    - name: Checkout code
      uses: actions/checkout@v1
        path: ./src/${{ github.repository }}

Quick links

Known bugs

The setup-go action doesn't set PATH, so currently it's not possible to go install a program and run it directly. Until that's fixed, consider absolute paths like $(go env GOPATH)/bin/program.

git config core.autocrlf defaults to true, so be careful about CRLF endings in your plaintext testdata files on Windows. To work around this, set up the following .gitattributes:

* -text

GOCACHE won't be accessible on Windows by default, since %LocalAppData% isn't defined. To temporarily work around the error below, set GOCACHE manually:

build cache is required, but could not be located: GOCACHE is not defined and %LocalAppData% is not defined

os.TempDir on Windows will contain a short name, since %TEMP% also contains it. Note that case sensitivity doesn't matter, and that os.Open should still work; but some programs not treaing short names might break.

> echo %TEMP%
You can’t perform that action at this time.