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.

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. 😎

Comments

comments powered by Disqus