Docs menu

Package managers

How Go modules work on Primcloud: go.mod / go.sum, vendoring, private modules, GOPROXY, and lockfile behavior.

On this page

Go has one dependency system: modules. Every dependency your app pulls in is declared in go.mod, its hash is recorded in go.sum, and the module graph is either downloaded from a module proxy at build time or read from a vendor/ directory you commit.

Primcloud requires modules. The older dependency managers (dep, godep, govendor, glide) aren't recognized; the build expects a go.mod at the root and Go module semantics throughout.

Supported package manager#

Go modules. The build sets GO111MODULE=on and runs every command in module-aware mode. There's nothing to install, enable, or configure to make modules work.

Install behavior#

The build reads two files:

  • go.mod: declares required modules and their minimum versions.
  • go.sum: records cryptographic hashes for every module version resolved into the build. Commit it; the Go toolchain verifies every downloaded module against these hashes and fails the build on a mismatch.

Two paths, depending on what's in the repo:

With vendor/modules.txt. Module downloads are skipped entirely and the copy of every dependency in vendor/ is used. This is the fastest and most reproducible option: the build never touches the network for module data. Generate it locally with:

Terminal
go mod vendor

Then commit the whole vendor/ tree.

Without vendor/modules.txt. The module graph is downloaded as a side effect of go list ./... and stored in a persistent cache at $GOMODCACHE. Downloads go through the default Go module proxy (https://proxy.golang.org) unless you override GOPROXY.

These module-related environment variables are set at build time:

Variable Value Effect
GOMODCACHE Path to the cached module layer Downloaded modules land here and persist across builds.
GO111MODULE on Forces module-mode compilation.

Private modules and registries#

If your go.mod requires a module hosted outside the public proxy (a private GitHub repo, a corporate module server, a self-hosted Athens instance), tell the Go toolchain where to fetch it and how to authenticate.

Route private paths around the proxy. Set GOPRIVATE (or GONOPROXY / GONOSUMCHECK) in the Secrets panel to a comma-separated list of module path prefixes:

  • GOPRIVATE=github.com/mycompany/*,git.example.com: matching modules bypass the public proxy and the public checksum database.

Provide credentials. For modules fetched over HTTPS, the Go toolchain reads credentials from a ~/.netrc-style config. On Primcloud, the practical pattern is a token embedded in GOPROXY (for a private module proxy) or a git URL rewrite.

A working approach for private GitHub modules:

  • Create a GitHub personal access token with repo scope.
  • Set GOPRIVATE=github.com/mycompany/* in the Secrets panel.
  • Configure git to use the token: a .netrc written during the build, or a git URL rewrite committed to your repo's build config.

For private module proxies (Artifactory, GitLab, Athens), set GOPROXY to the proxy URL with credentials embedded:

Secrets you set are visible during the build. They're stored encrypted and never printed in build logs.

Lockfiles#

go.sum is Go's lockfile, with a twist compared to other ecosystems.

Every module in the build graph appears in go.sum with a hash. The toolchain records hashes for both the module's source archive (h1:...) and its go.mod file (/go.mod h1:...), and verifies both on download.

A hash mismatch fails the build. If a module version's contents differ from what go.sum records, the build stops with a checksum mismatch error before compilation begins.

go.sum doesn't pin versions. Unlike npm's package-lock.json or Yarn's yarn.lock, go.sum doesn't force a specific version graph. It verifies the versions you resolved to. The actual resolution comes from go.mod and Go's minimum version selection.

To lock down the exact set of module versions in a build, either:

  • Commit vendor/: the vendored tree is the definitive source of truth, and vendor/modules.txt records the exact versions.
  • Pin exact versions in go.mod via require directives with specific patch versions.

Primcloud doesn't enforce a "locked mode": a build succeeds as long as go.sum matches what was downloaded and the module graph resolves. Committing both go.mod and go.sum is required; committing vendor/ is optional but worth it for teams that want hermetic builds.