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
jobs:
test:
strategy:
matrix:
go-version: [1.13.x, 1.14.x]
platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- name: Install Go
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- 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.
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
.
They can be set up via env
for an entire
workflow,
a job, or for each step:
env:
GOPROXY: "https://proxy.company.com"
jobs:
[...]
Use actions/cache. For example, to cache downloaded modules:
- uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
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
You can add options to existing matrix jobs, and you can exclude specific matrix jobs.
- name: Series of commands
run: |
go test ./...
go test -race ./...
The biggest difference is the UI; workflow results are shown separately. Grouping jobs in workflows can also be useful if one wants to customize the workflow triggers, or to set up dependencies via needs.
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
env:
FOO_SECRET: ${{ secrets.FOO_SECRET }}
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
env:
TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
run: git config --global url."https://YOUR_GITHUB_USERNAME:${TOKEN}@github.com".insteadOf "https://github.com"
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
Declare GOPATH and clone inside of it:
jobs:
test-gopath:
env:
GOPATH: ${{ github.workspace }}
GO111MODULE: off
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: ./src/github.com/${{ github.repository }}
-
Concepts, rate limits, etc: https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions
-
Syntax and fields reference: https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions
-
Environment reference: https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
-
To report bugs: https://github.community/t5/GitHub-Actions/bd-p/actions
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
.
A workaround is to use a built-in workflow command
to add GOBIN
to the system's PATH
. Note that shell: bash
is supported on
all platforms:
- name: Add GOBIN to PATH
run: echo "::add-path::$(go env GOPATH)/bin"
shell: bash
Note that the upcoming actions/setup-go@v2
fixes this issue, but is still in
beta as of April 2020.
- https://github.community/t5/GitHub-Actions/git-config-core-autocrlf-should-default-to-false/m-p/30445 and actions/checkout#135
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
- https://github.community/t5/GitHub-Actions/TEMP-is-broken-on-Windows/m-p/30432/thread-id/427 and https://github.com/actions/runner/issues/424
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 %USERPROFILE%
C:\Users\runneradmin
> echo %TEMP%
C:\Users\RUNNER~1\AppData\Local\Temp