Hosting Private Go Modules on GitLab
There are a few hoops to jump through to host private go modules on GitLab. Firstly, we have to include .git
in the module path, otherwise go get
has trouble finding a repository in a nested subgroup.
For example, say we have a repository hosted at gitlab.com/ray1729/dev/hello; to create a go module in this repository, we need to do:
go mod init gitlab.com/ray1729/dev/hello.git
In the consumer, we need to import it as:
import "gitlab.com/ray1729/dev/hello.git"
To consume a subpackage in the module, we simply do:
import "gitlab.com/ray1729/dev/hello.git/pkg/foo"
Secondly, we have to define the GOPRIVATE
environment variable to prevent go get
from trying to download the module from a public proxy:
export GOPRIVATE=gitlab.com/ray1729/*
Finally, we need to configure authentication. For local development, create a personal access token with read_repository
permission, and add the following to ~/.netrc
:
machine gitlab.com
login oauth2
password ${TOKEN}
We can now run go get
to fetch modules from our private repositories.
For GitLab CI/CD, every job has an automatic variable called $CI_JOB_TOKEN
that we can write to a .netrc
file in a before_script
. Here's a minimal working .gitlab-ci.yml
:
variables:
GOPRIVATE: gitlab.com/ray1729/*
go-build:
image: golang:1.15-buster
before_script:
- echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
script:
- go build ./...
Note: if you define a group-level GOPRIVATE
variable in GitLab there is no need to include the variable in the CI config.