iTranslated by AI
A Complete CI Workflow for Go Packages with GitHub Actions
In this article, I will introduce how to use GitHub Actions to automate the following tasks for Go package repositories.
- Vulnerability scanning for dependent packages (on push or pull request)
- Lint & test (on push or pull request)
- Build & deploy (when a version tag is added)
Vulnerability scanning for dependent packages
For scanning dependent packages, nancy seems like a good choice. An official GitHub Action is also provided.
To run nancy with GitHub Actions, place a YAML file with the following content in the .github/workflows/ directory.
name: vulns
on:
push:
branches:
- main
pull_request:
jobs:
vulns:
name: Vulnerability scanner
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: ^1.19
- name: WriteGoList
run: go list -json -m all > go.list
- name: Nancy
uses: sonatype-nexus-community/nancy-github-action@main
With this, vulnerability scanning will run on pull requests and on pushes to the main branch[1].
I use my own tool depm to collect module information. It looks like this:
- name: install depm
run: go install github.com/goark/depm@latest
- name: WriteGoList
run: depm list --json > go.list
You can choose whichever method you prefer.
Lint & Test
For Go linters, golangci-lint is highly recommended. golangci-lint is an excellent tool that aggregates results from multiple linters, including go vet. An official GitHub Action is also available.
To run golangci-lint with GitHub Actions, place a YAML file with the following content in the .github/workflows/ directory.
name: lint
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: ^1.19
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest
# Optional: working directory, useful for monorepos
# working-directory: somedir
# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true
# Optional: if set to true then the all caching functionality will be complete disabled,
# takes precedence over all other caching options.
# skip-cache: true
# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true
# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
- name: testing
run: go test -shuffle on ./...
With this, golangci-lint will run on pull requests and on pushes to the main branch[1:1]. By the way, the following part of the steps items:
- name: testing
run: go test -shuffle on ./...
is the section that executes Go tests. If you need more complex tests using the make command or similar instead of a simple go test, you will need to add a bit more detail.
Build & Deploy
If it is Pure Go, GoReleaser can handle everything from cross-compilation to deployment on the Release page automatically. Settings are written in .goreleaser.yml[2]. An official GitHub Action is also provided.
To run GoReleaser with GitHub Actions, place a YAML file with the following content in the .github/workflows/ directory.
name: build
on:
push:
tags:
- v*
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ^1.19
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
With this, cross-compilation and deployment via GoReleaser will run when a version tag is added.
Adding GitHub Action Badges
You can add badges that display the status of your GitHub Actions to documents such as README.md. Use the following format to specify the badge:
[](https://github.com/{user}/{repo}/actions)
For example, for the repository https://github.com/goark/koyomi:
[](https://github.com/goark/koyomi/actions)
It will be displayed like this:
Note that the name for {action} corresponds to the name field on the first line of the YAML, not the file name.
Reference Pages
-
How to Add a GitHub Actions Badge to Your Project - DEV Community
-
Vulnerability scanning for Go dependent packages | text.Baldanders.info
-
Using golangci-lint in GitHub Actions | text.Baldanders.info
-
Cross-compiling with GitHub Actions (GoReleaser edition) | text.Baldanders.info
-
It seems GitHub Code Scanning can now be used with Go code | text.Baldanders.info
-
Various updates to GitHub Actions for CI | text.Baldanders.info
-
Since October 2020, the default branch name for new GitHub repositories has become
main. Please note that in older repositories, it remains asmaster. ↩︎ ↩︎ -
I will omit details on how to use GoReleaser. You can probably find information in Japanese by searching for it. ↩︎
Discussion