Private Golang Packages
I’ve been working with Golang on both personal projects and within my role at Serif for about six months now, and we’ve recently decided that Golang is a good fit for some of the new microservices we have plans for. Up until this point we’ve not had a need to use private packages.
Although the package management system in Golang is very simple - it basically just references a Git repository. This is fine for open source projects, but for private projects it’s not ideal.
Using Private Packages
Let’s create a test package that’s private to our organisation. Assuming our private Gitlab instance is at gitlab.example.com
we can create a new project called test-package
and then create a new Go module:
$ mkdir test-package
$ cd test-package
$ go mod init gitlab.example.com/our-org/test-package
This test package is going to be really simple, it’s just going to echo a string. (Imagine shouting in a tunnel…)
package echo
import (
"fmt"
"strings"
)
func Echo(s string) string {
return fmt.Sprintf("%s... %s... %s...", strings.ToUpper(s), strings.ToTitle(s), strings.ToLower(s))
}
We’ll push this to a newly created GitLab repository and tag it as v1.0.0
- Let’s say the URL is gitlab.example.com/our-org/test-package.git
.
We now want to make use of this package in another project.
$ go get gitlab.example.com/our-org/test-package
We’ll see that this doesn’t work, we need to configure Go to use our private GitLab instance.
Configuring Go
We need to tell Go that the url for these packages is private, so let’s set the GOPRIVATE
environment variable:
go env -w GOPRIVATE=gitlab.example.com/our-org/*
By default, Go will try to use the https
protocol to access the GitLab instance. This won’t work for us, as we usually use SSH to access GitLab. We can either update our ~/.gitconfig
to use ssh
instead when making requests to gitlab.example.com
or we can setup authentication for https
requests. Let’s do it this way.
- Create a Personal Access Token in our GitLab instance with the READ API and READ REPOSITORY scope.
- Create a file called
~/.netrc
with the following contents:
machine gitlab.example.com
login <our-gitlab-username>
password <personal-access-token>
We can now try to install our private package again. This time we get a different error:
go get: gitlab.example.com/our-org/test-package.git: parsing go.mod:
module declares its path as:
gitlab.example.com/our-org/test-package
but was required as:
gitlab.example.com/our-org/test-package.git
Within the project we’re trying to install the package in, we need to update the go.mod
file to use the correct path. We can do this by adding the following line to the go.mod
file:
replace gitlab.example.com/our-org/test-package.git => gitlab.example.com/our-org/test-package v1.0.0
Rerunning go get
should now work. 😎