Newer
Older
# GitLab CI template for Go
This project implements a generic GitLab CI template for [Go](https://golang.org/).
It provides several features, usable in different modes (by configuration).
## Usage
In order to include this template in your project, add the following to your `gitlab-ci.yml`:
```yaml
include:
file: '/templates/gitlab-ci-golang.yml'
```
## Global configuration
The Go template uses some global configuration used throughout all jobs.
| Name | description | default value |
| --------------------- | ---------------------------------------------- | ----------------- |
| `GO_IMAGE` | The Docker image used to run Go for `go-build` <br/>:warning: **set the version required by your project** | `golang:buster` |
| `GO_TEST_IMAGE` | The Docker image used to run Go for `go-test` <br/>:warning: **set the version required by your project** | _none_ |
| `GO_PROJECT_DIR` | Go project root directory | `.` |
| `GOPROXY` | URL of Go module proxy | _none_ |
## Jobs
### build & test jobs
The build target platform is the one defined by the docker image but it can be overriden using the `GO_TARGET_OS` and `GO_TARGET_ARCH` variables.
```yaml
variables:
GO_TARGET_OS: "windows"
GO_TARGET_ARCH: "amd64"
```
Build and tests can be done in separate jobs.
If `GO_TEST_IMAGE` is not set (default), the `go-build-test` job will run build and tests at once.
If `GO_TEST_IMAGE` is set, separate `go-build` and `go-test` jobs will be run in the `build` phase in parallel.
Separating `build` and `test` jobs can be useful to use different images (and hence different tools) or if you want to build muli-platform binaries.
Here is a `.gitlab-ci.yml` example that triggers a build on 3 target platforms using the [parallel matrix jobs](https://docs.gitlab.com/ee/ci/yaml/#parallel-matrix-jobs) pattern:
```yaml
variables:
GO_IMAGE: "golang:1.17-buster"
GO_TEST_IMAGE: "golang:1.17-buster"
go-build:
parallel:
matrix:
- GO_TARGET_OS: "windows"
GO_TARGET_ARCH: "amd64"
- GO_TARGET_OS: "linux"
GO_TARGET_ARCH: "amd64"
- GO_TARGET_OS: "linux"
GO_TARGET_ARCH: "arm"
```
These jobs use the following variable:
| Name | description | default value |
| ----------------------- | ---------------------------------------- | ----------------- |
| `GO_BUILD_FLAGS` | Flags used by the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) | `-mod=readonly` |
| `GO_BUILD_PACKAGES` | Packages to build with the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) | `./...` |
| `GO_TEST_FLAGS` | Flags used by the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages) | `-mod=readonly -v -race` |
| `GO_TEST_PACKAGES` | Packages to test with the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages) | `./...` |
| `GO_LIST_ARGS` | Arguments used by the list command | `list -u -m -mod=readonly -json all` |
| `GO_TARGET_OS` | The `GOOS` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) | _none_ (fallback to go docker image `GOOS`)
| `GO_TARGET_ARCH` | The `GOARCH` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) | _none_ (fallback to go docker image `GOARCH`)
### `go-ci-lint` job
This job enables a manual [GolangCI-Lint](https://github.com/golangci/golangci-lint) analysis.
It is bound to the `build` stage, and uses the following variables:
| Name | description | default value |
| --------------------- | -------------------------------------------- | ----------------- |
| `GO_CI_LINT_IMAGE` | The Docker image used to run `golangci-lint` | `golangci/golangci-lint:latest-alpine` |
| `GO_CI_LINT_ARGS` | `golangci-lint` [command line arguments](https://github.com/golangci/golangci-lint#command-line-options) | `-E gosec,goimports ./...` |
| `GO_CI_LINT_DISABLED` | Set to `true` to disable this job | _none_(enabled) |
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Golang Security Checker can be a long operation and therefore the job is configured to be ran **manually** by default (overridable).
### `go-mod-outdated` job
This job enables a manual [Go-mod-outdated](https://github.com/psampaz/go-mod-outdated) analysis.
It is bound to the `test` stage, and uses the following variables:
| Name | description | default value |
| --------------------- | -------------------------------------------- | ----------------- |
| `GO_MOD_OUTDATED_ARGS` | `god-mod-outdated` [command line arguments](https://github.com/psampaz/go-mod-outdated#usage) | `-update -direct -style markdown -ci` |
Checking outdated modules can be a long operation and therefore the job is configured to be ran **manually** by default (overridable).
## SonarQube analysis
If you're using the SonarQube template to analyse your Go code, here is a sample `sonar-project.properties` file:
```properties
# see: https://docs.sonarqube.org/latest/analysis/languages/go/
# set your source directory(ies) here (relative to the sonar-project.properties file)
sonar.sources=.
# exclude unwanted directories and files from being analysed
sonar.exclusions=bin/**,**/*_test.go,**/vendor/**
# set your tests directory(ies) here (relative to the sonar-project.properties file)
sonar.tests=.
sonar.test.inclusions=**/*_test.go
sonar.test.exclusions=**/vendor/**
# tests report: JSON format
sonar.go.tests.reportPaths=reports/sonar-tests-report.json
# coverage report
sonar.go.coverage.reportPaths=reports/coverage.out
# golanci-lint report
sonar.go.golangci-lint.reportPaths=reports/golangci-lint-report.xml
```
More info:
* [Go language support](https://docs.sonarqube.org/latest/analysis/languages/go/)
* [test coverage & execution parameters](https://docs.sonarqube.org/latest/analysis/coverage/)
* [third-party issues](https://docs.sonarqube.org/latest/analysis/external-issues/)
:warning: an [unsolved issue](https://jira.sonarsource.com/browse/SONARSLANG-450) may prevent SonarQube Go plugin from
importing your test reports.
## GitLab compatibility
:information_source: This template is actually tested and validated on GitLab Community Edition instance version 13.12.11