Build and run a Dagger pipeline in Go that containerizes an application, runs tests in isolation, and pushes to a registry only if tests pass, using Dagger's native caching
Initialize a Dagger Go module with dagger init --sdk=go --name=ci and scaffold a main.go with a Dagger function that accepts a *dagger.Client context and a source *dagger.Directory parameter
In the pipeline function, build a container from the source directory using client.Container().From(baseImage).WithDirectory("/app", source).WithWorkdir("/app").WithExec([]string{"go", "build", "./..."})
Run tests in a separate container derived from the build output using .WithExec([]string{"go", "test", "-race", "./..."}); call .Sync(ctx) to execute and return an error if tests fail, preventing the pipeline from continuing
Only if Sync returns nil, proceed to push the image to a registry using .Publish(ctx, registryRef) where registryRef includes the digest-addressable tag; capture and return the pushed digest as the function output
Use WithMountedCache on the Go module cache directory pointing to a client.CacheVolume("go-modules") so dependency downloads are reused across pipeline runs without manual cache key management
Invoke the Dagger pipeline locally with dagger call ci --source=. and in CI with dagger run go run ./ci.go, ensuring the same pipeline code executes identically in both environments
Known gotchas
Dagger caches container layers and function outputs by content hash; if the build context includes files that change on every run (such as a timestamp file or a git-dirty working tree), caching is effectively disabled and every run rebuilds from scratch
Dagger's WithExec does not stream output to the terminal by default; a long-running step such as a test suite produces no visible output until it completes or fails, making it appear hung; use Stdout(ctx) or Stderr(ctx) to surface output progressively
Publishing to a private registry requires passing registry credentials to Dagger via client.SetSecret and using WithRegistryAuth on the container; credentials stored only as environment variables on the host are not automatically available inside Dagger containers
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp