GitHub Actions as CI for Go

Overview

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
jobs:
  test:
    strategy:
      matrix:
        go-version: [1.15.x, 1.16.x]
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
    - name: Install Go
      uses: actions/[email protected]
      with:
        go-version: ${{ matrix.go-version }}
    - name: Checkout code
      uses: actions/[email protected]
    - name: Test
      run: go test ./...

Summary

Each workflow file has a number of jobs, which get run on specified events, and run concurrently with each other. You can have workflow status badges.

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.

FAQs

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 environment variables?

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

env:
  GOPROXY: "https://proxy.company.com"
jobs:
  [...]

How do I set environment variables at run-time?

You can use workflow commands to set environment variables or add an element to $PATH. For example:

steps:
- name: Set env vars
  run: |
      echo "CGO_ENABLED=0" >> $GITHUB_ENV
      echo "${HOME}/goroot/bin" >> $GITHUB_PATH

Note that these take effect for future steps in the job.

How do I set up caching between builds?

Use actions/cache. For example, to cache downloaded modules:

- uses: actions/[email protected]
  with:
    path: ~/go/pkg/mod
    key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
    restore-keys: |
      ${{ runner.os }}-go-

You can also include Go's build cache, to improve incremental builds:

- uses: actions/[email protected]
  with:
    # In order:
    # * Module download cache
    # * Build cache (Linux)
    # * Build cache (Mac)
    # * Build cache (Windows)
    path: |
      ~/go/pkg/mod
      ~/.cache/go-build
      ~/Library/Caches/go-build
      %LocalAppData%\go-build
    key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
    restore-keys: |
      ${{ runner.os }}-go-

This is demonstrated via the test-cache job in this very repository.

See this guide for more details.

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.os == 'ubuntu-latest'
  run: go run ./endtoend

How do I set up a custom build matrix?

You can include extra 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?

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.

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
  env:
    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, as well as configure GOPRIVATE.

- 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"
env:
  GOPRIVATE: "*.company.com"
jobs:
  [...]

How do I install Linux packages?

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

- name: Install Linux packages
  if: matrix.os == '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 of it:

jobs:
  test-gopath:
    env:
      GOPATH: ${{ github.workspace }}
      GO111MODULE: off
    defaults:
      run:
        working-directory: ${{ env.GOPATH }}/src/github.com/${{ github.repository }}
    steps:
    - name: Checkout code
      uses: actions/[email protected]
      with:
        path: ${{ env.GOPATH }}/src/github.com/${{ github.repository }}

Quick links

Caveats

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

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 treating short names might break.

> echo %USERPROFILE%
C:\Users\runneradmin
> echo %TEMP%
C:\Users\RUNNER~1\AppData\Local\Temp
Issues
  • $HOME/.cache/go-build caching

    $HOME/.cache/go-build caching

    The readme says for How do I set up caching between builds? the path can be ~/go/pkg/mod. However it seems that's only for source files to be cached.

    If you are like me and you do cross-compilation of binaries to 10+ architectures, you probably need to cache ~/.cache/go-build/ directory as well. Otherwise you're waiting for all Go stdlibs (and deps cached in ~/go/pkg/mod) to recompile ––which is the majority of the time spent.

    Thoughts?

    opened by ahmetb 5
  • Make caching work by removing comments

    Make caching work by removing comments

    Path is a multiline string, which includes comments in its value. This means that the caching was not working at all, because it would include the comment in the path. Here I'm removing the comments, which fixes the caching so it works.

    You might have to change the cache key for your own repository to make it work there. You can check that the caching was broken here and see how it was being parsed. I figured out it was broken because the restore step always said Cache Size: ~0 MB (22 B)

    opened by bouk 4
  • Private modules checkout failed with actions/checkout@v2

    Private modules checkout failed with actions/[email protected]

    After configuring the ci.yml to this:

    env:
      GOPRIVATE: "github.com/company"
    jobs:
    .....
      - name: Check out code into the Go module directory
         uses: actions/[email protected]
    
      - 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"
    

    I am still saw following error:

    go: github.com/company/[email protected]: invalid version: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in /home/runner/go/pkg/mod/cache/vcs/4902ad5423d70bf8a819e419fc1d6e0667f5a8f1542bd02ff6253926ac8fcb35: exit status 128:
    	remote: Repository not found.
    	fatal: repository 'https://github.com/company/repo/' not found
    Error: Process completed with exit code 1.
    

    If I change uses: actions/[email protected] to uses: actions/[email protected] seems solve the issue

    Is there additional setup required for [email protected]?

    opened by ray-x 3
  • docs: `platform` should be `os`

    docs: `platform` should be `os`

    in your readme, it specifies to use platform, but it should be os.

    platform: [ubuntu-latest, macos-latest, windows-latest]
    

    https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#example-running-with-more-than-one-operating-system

    opened by ghostsquad 3
  • Adding GOBIN to PATH

    Adding GOBIN to PATH

    First, I just wanted to say, huge thanks for this repo/README, it helped me a ton. I've been working on setting up github actions for Caddy.

    In your README, you note:

    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.

    I just wanted to point out that I figured out that you can just do this on any step after setup-go, pretty much entirely smoothes that issue over:

    echo "::add-path::$(go env GOPATH)/bin"
    
    opened by francislavoie 3
  • Github Action Failing even tho the Tests passed

    Github Action Failing even tho the Tests passed

    When I run this Github Action:

    on: [push, pull_request]
    name: Test
    jobs:
      test:
        strategy:
          matrix:
            go-version: [1.16.x]
            os: [ubuntu-latest]
        runs-on: ${{ matrix.os }}
        steps:
          - name: Install Go
            uses: actions/[email protected]
            with:
              go-version: ${{ matrix.go-version }}
          - name: Checkout code
            uses: actions/[email protected]
          - name: Setup Redis
            # You may pin to the exact commit or the version.
            # uses: zhulik/[email protected]e16ea5
            uses: zhulik/[email protected]
          - name: Setup PostgreSQL
            # You may pin to the exact commit or the version.
            # uses: Harmon758/[email protected]
            uses: Harmon758/[email protected]
            with:
              # POSTGRES_DB - name for the default database that is created
              postgresql db: shoppinglistboom
              # POSTGRES_USER - create the specified user with superuser power
              postgresql user: shoppinglist
              # POSTGRES_PASSWORD - superuser password
              postgresql password: postgres
          - name: Build
            working-directory: ./backend
            run: go build ./...
          - name: Test
            working-directory: ./backend
            run: go test ./...
            env:
              DB_HOST: localhost
              DB_USER: shoppinglist
              DB_DATABASE: shoppinglistboom
              DB_PASSWORD: postgres
              REDIS_HOST: localhost
              REDIS_PORT: 6379
              DATABASE_DSN: host=localhost user=shoppinglist password=postgres dbname=shoppinglistboom sslmode=disable
              TESTING: true
    

    it fails every time due to the Tests. But when I look at the logs it says that the Tests passed. grafik

    It gives me the exit code 2 but I dont know what to do with that.

    opened by Urento 2
  • How to use shields with github actions ?

    How to use shields with github actions ?

    I have some projects using travis and this allowed me to have shields when the project passed.

    How can we do this with github actions ?

    BTW, thank you very much for your helpful project.

    opened by chmike 2
  • Testing for Go v1 apps without go mod

    Testing for Go v1 apps without go mod

    Is it possible to test for Go v1 apps that's not having/using go mod?

    This is what I'm getting -- https://github.com/suntong/shuttlebot/runs/2701444155?check_suite_focus=true

    Run go test ./...
    main.go:16:2: cannot find package "github.com/caarlos0/env" in any of:
    	/opt/hostedtoolcache/go/1.15.12/x64/src/github.com/caarlos0/env (from $GOROOT)
    	/home/runner/go/src/github.com/caarlos0/env (from $GOPATH)
    logging.go:8:2: cannot find package "github.com/go-kit/kit/log" in any of:
    	/opt/hostedtoolcache/go/1.15.12/x64/src/github.com/go-kit/kit/log (from $GOROOT)
    	/home/runner/go/src/github.com/go-kit/kit/log (from $GOPATH)
    . . .
    

    Would it be possible that I set my own GOPATH and do go get myself?

    opened by suntong 1
  • GOPATH: ${{ runner.workspace }} Do not work with actions

    GOPATH: ${{ runner.workspace }} Do not work with actions

    I used your template for set GOPATH env variable, but there is an error.

    - Your workflow file was invalid: The pipeline is not valid. .github/workflows/go.yml (Line: 9, Col: 15): Unrecognized named-value: 'runner'. Located at position 1 within expression: runner.workspace,.github/workflows/go.yml (Line: 26, Col: 7): Unexpected value 'with'

    My line 9 has: GOPATH: ${{ runner.workspace }}

    opened by alonyb 1
  • Warn about Pwsh quoting of Go commands arguments on Windows

    Warn about Pwsh quoting of Go commands arguments on Windows

    I had the bad experience that this doesn't work on Windows:

          - name: Run coverage
            run: go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
    

    Output:

    no required module provides package .out; to add it:
    	go get .out
    Error: Process completed with exit code 1.
    

    But this works:

          - name: Run coverage
            run: go test -v -race -coverprofile coverage.out -covermode atomic ./...
    

    The only difference is that = is replaced with space.

    I suspect this is a PowerShell quoting issue.

    opened by dolmen 6
  • Caching test results across action runs

    Caching test results across action runs

    I've found this repo very helpful, thank you! I've noticed that using the actions-cache as demonstrated in the repo doesn't result in tests being cached. I know on my local machine when I rerun tests for packages that haven't changed the results are cached, but when I run on GitHub Actions even with all the cache directories setup the tests aren't cached.

    It'd help speed up tests for a lot of Go projects if we could figure that out.

    opened by leighmcculloch 10
  • Cache keys

    Cache keys

    This is an awesome resource, thank you!

    I noticed you use ${{ hashFiles('**/go.sum') }} as a cache key for the module cache. I am not sure that does what it is intended for, since the go.sum file does not contain a hash of the module itself, and it might be missing from a module with no dependencies. If hashFiles includes the file names in the key, you could just use the go.mod files instead, but even that would exclude modules that did not update.

    opened by FiloSottile 4
Owner
Daniel Martí
I work on stuff in Go.
Daniel Martí
GitHub CLI extension to preview your markdown similar to the style of GitHub.

gh markdown-preview GitHub CLI extension to preview your markdown similar to the style of GitHub gh markdown-preview is a GitHub CLI extension to prev

Yusuke Wada 132 Jul 29, 2022
Ghissue - This repo contains a github issue parser, that is useful for Enterprise Github accounts.

Ghissue - This repo contains a github issue parser, that is useful for Enterprise Github accounts. Sometimes is needed to parse the content of the issue for some data extraction or statistics purposes.

niloofargheibi 1 Feb 6, 2022
lazyhub - Terminal UI Client for GitHub using gocui.

lazyhub - Terminal UI Client for GitHub using gocui.

ryo-ma 161 Jul 29, 2022
A tool to sent comments to Issues or Pull Requests in Github from CI tools.

CommentCI A tool to sent comments to Issues or Pull Requests in Github from CI tools. Usage Required environment variables: GITHUB_COMMENT_USER - User

Aliaksandr Shulyak 9 Apr 10, 2022
GitHub’s official command line tool

GitHub CLI gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already

GitHub CLI 29.4k Aug 6, 2022
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.

Table of contents Introduction Reference Contributing Introduction Overview git-xargs is a command-line tool (CLI) for making updates across multiple

Gruntwork 622 Aug 7, 2022
🐙🐱🖥️ GitHub stats in your terminal

?? ?? ??️ octotui - GitHub stats in terminal Inspired by metrics & github-profile-summary-cards & github-tui ?? Data - irevenko/octostats TUI - termui

Ilya Revenko 197 Jul 14, 2022
github stats from the command line

Retrieve GitHub statistics per username from the command line: no need to open the browser anymore!

Gennaro Tedesco 31 Jul 18, 2022
CLI tool for manipulating GitHub Labels across multiple repositories

takolabel Installation Mac $ brew install tommy6073/tap/takolabel Other platforms Download from Releases page in this repository. Usage Set variables

Takayuki NAGATOMI 9 Feb 16, 2022
🙌 Bulk-upload GitHub Issues

?? Bulk-upload GitHub Issues

Hunter Gatewood 22 Jul 23, 2021
An extension for the GitHub Cli application that displays your current contribution graph

gh-graph An extension for the GitHub Cli application that displays your current contribution graph in the terminal (logged out contribution graph) Ins

Benjamin Chadwick 14 Sep 29, 2021
CLI to output stargazer ⭐️ histogram for a GitHub repository

bestgo bestgo is a CLI that pulls live data from https://api.bestofgo.dev (UI coming soon). This is an application that scrapes GitHub data for Go rep

Michael Fridman 9 Jun 30, 2022
Go terminal app listing open pull requests in chosen GitHub repositories

go-pr-watcher About Shows open pull requests on configured GitHub repositories. Getting started Create GitHub personal token with read permissions Cre

Oleg 0 Oct 29, 2021
A command-line to create a pull request to review the entire content of a Github repository.

Pull Request Me Pull Request Me (PRMe) creates a pull request for the entire content of a Github repository. This is useful to solicit review comments

Ivan Fetch 3 Nov 2, 2021
Github user stats fetch written in golang

TACOMA It's like neofetch, but for github users. I saw something similar on reddit and decided to recreate it using only golang. Original inspiration:

Daniel M. Matongo 3 Dec 24, 2021
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command

git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command. You give git-xargs:

Maxar Infrastructure 1 Feb 5, 2022
GitHub on the command line with golang

GitHub CLI gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already

null 0 Dec 31, 2021
🦜 Navigate github repos in a tui

goh Navigate github repos in a tui Why I am constantly refering to my github repos and repos from others for code snippets that are relevant to what I

Taylor Gamache 11 Dec 10, 2021
Simple command line Github Search

ghs is a simple command line tool which will open the corresponding url for your github search in your default web browser.

Hasan Ocak 2 Nov 10, 2021