Skip to main content

Go

The Go module gives a Go workspace one shared way to test, lint, and run go generate. It scans the workspace for go.mod files, treats each one as a Go module, and exposes workspace-level functions that run across all of them — a good fit for monorepos, service repos, and libraries with generated code, especially when several modules should share one Go version and the same CI checks.

Official module: dagger/go

Add it to your workspace

dagger install github.com/dagger/go

Run the checks

dagger check              # run every check in the workspace
dagger check go:test-all # run Go tests across every module
dagger check go:lint-all # run golangci-lint across every module

test-all and lint-all discover every go.mod in the workspace, treat each as a Go module, and run against all of them. Tests run through an OpenTelemetry-aware runner, so individual Go tests appear as spans in the Dagger TUI and Dagger Cloud. Lint runs a pinned golangci-lint and picks up each module's .golangci.* config.

Generate code

Run the generator when generated Go files are part of normal development — mocks, embedded assets, protobuf output, or anything produced by go generate:

dagger generate go:generate-all

generate-all runs only in modules that contain a //go:generate directive, and returns the result as a changeset to review before applying.

Configure it

List the current settings with dagger settings go, then change one with dagger settings go <key> <value>. They live in dagger.toml under [modules.go.settings]:

  • version (default 1.26): the Go toolchain version used to build the test and generate containers (golang:<version>-alpine). Set this so every module is tested and generated against the same Go version. Lint uses a pinned golangci-lint image and is unaffected.
  • includeExtraFiles (default empty): extra workspace-root path patterns mounted alongside each module's Go source. Go source, go.mod/go.sum/go.work, and testdata/ directories are already included automatically; use this for inputs those patterns miss, such as embedded non-Go assets, generator inputs, or fixtures kept outside testdata/.
  • lint, test, and generate (each defaults to ["**"]): module-root selector arrays for lint-all, test-all, and generate-all. A bare pattern includes modules, a !-prefixed pattern excludes them, and exclusions always win. "**" and "*" match every module; "path" and "path/**" match the module at path and any modules below it. With no positive pattern, every module is included unless excluded, so ["!**"] disables that workflow everywhere.
# Pin the Go version for the whole workspace
dagger settings go version 1.25

List-valued settings are edited directly in dagger.toml:

[modules.go.settings]
version = "1.25"
includeExtraFiles = ["Makefile", "tools/**"]
lint = ["!**"] # Disable linting for all modules
test = ["**", "!legacy-service"] # Test all modules except legacy-service and modules below it

Working with other modules

Reach for this module whenever the repo contains one or more Go modules, especially when they should share the same Go version and CI checks. To exclude a single module from a workflow, add a !-prefixed module path to the corresponding selector array rather than splitting the repo into separate check systems.