Skip to content
Latchkey

go work use: Multi-Module Workspaces in CI

go work use adds a module directory to a go.work file so the go command builds and tests several local modules together without replace directives.

Workspaces (Go 1.18+) let a monorepo of related modules resolve each other locally. In CI you often disable the workspace so the published go.mod is what gets tested.

What it does

go work init creates a go.work file; go work use <dir> adds a module to it; go work sync pushes the workspace build list back into the member go.mod files. When go.work is present, the go command uses the local module copies instead of downloaded versions.

Common usage

Terminal
go work init ./api ./worker
go work use ./newservice
go work sync
GOWORK=off go test ./...        # ignore the workspace

Flags

Command / envWhat it does
go work init <dirs>Create go.work listing the given modules
go work use <dir>Add a module directory to go.work
go work use -r <dir>Recursively add modules under a directory
go work syncSync the workspace build list into member go.mod
GOWORK=offEnv: ignore go.work for this command

In CI

Decide deliberately whether CI uses the workspace. To test each module as published, set GOWORK=off so CI does not paper over a missing dependency with a local copy. Do not commit go.work if it is developer-local; many teams gitignore it. The module cache (~/go/pkg/mod) still caches non-workspace dependencies.

Common errors in CI

"go: no modules were found in the current workspace; see 'go help work'" means go.work lists no valid modules. "directory ... is not a module" from go work use means the path lacks a go.mod. "missing dependencies in go.work, run 'go work sync'" appears when member modules and the workspace disagree. With GOWORK=off, a build that relied on a local module may now fail with "no required module provides package", revealing a real missing require.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →