DEV Community

Cover image for Go private packages
Yurii Zinets
Yurii Zinets

Posted on • Updated on

Go private packages

git submodules

What's the matter?

Imagine a situation when you're following best practices, splitting your code on different parts, and ... facing an issue to collect them.
Unfortunately, go does not support private packages well.

So, how?

I'll describe the situation I faced. Private go mod packages, located in the GitLab subgroup (let's say just for example)

First, go not actually supports GitLab subgroups. To bypass that issue, we need to set GOPRIVATE env variable and add .git in the end:

$ GOPRIVATE="" go get 
Enter fullscreen mode Exit fullscreen mode

Second barrier is access to that repo. SSH key must be added to the platform, I didn't found a way to fetch with https.


  • Native experience (go get, which handles go.mod changes itself)


  • SSH key must be set
  • go.mod package name must fully correspond that naming (with .git in the end)

Problem is solved ... or not?

The first problem was faced in just after half an hour. It's a CI/CD, or just building step.
As we understood from previous "summary", SSH key must be added. We are using Docker to build our project, and passing SSH key to the Dockerfile build actually is a security problem.

Alternative way

I found a solution in git submodules and replace feature for the go.mod.
Just add needed repo as a project submodule with git submodule add and add naming replacement in the go.mod.
For example:

Adding submodule

$ git submodule add ../repo1
Enter fullscreen mode Exit fullscreen mode

Pulling newly added repo

$ git submodule update --init
Enter fullscreen mode Exit fullscreen mode

Adding go.mod replacement

replace => ./repo1
Enter fullscreen mode Exit fullscreen mode

And that's all! Handling package as a submodule is much easier than go package.

P.S. Don't forget to add submodules pulling in your CI! In case of GitLab it's GIT_SUBMODULE_STRATEGY: recursive variable.

Thank you for reading!

Top comments (0)