story(issue-71): add z5labs daggerverse module with GoApp + GoLib CI pipelines#80
Merged
Conversation
…pipelines GoApp runs the standardized check stages once (fmt/vet/lint/test -race via Go.Ci.Check), builds a multi-arch scratch image, and conditionally publishes to a registry based on a publishOn regex evaluated against the source repo's HEAD refs. GoLib runs the same checks; no artifact, no publish in v1. Publish uses skopeo in a service-bound sidecar instead of Container.Publish because Publish runs in BuildKit's engine context and does not see Dagger session service bindings, which makes it incompatible with a locally-hosted registry:2 service used in tests. The skopeo pipeline reads the multi-platform OCI tarball from Container.AsTarball and copies all variants under the computed image tag (stripped tag name for tag refs, <shortSha>-<isoCommitTime> for branch refs — commit-time, not build-time, so re-runs are idempotent). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new daggerverse/z5labs Dagger module that provides opinionated CI/release pipelines for Go applications (GoApp) and Go libraries (GoLib), plus a dedicated acceptance test suite (daggerverse/z5labs/tests) that is wired into the repo’s root CI test orchestrator.
Changes:
- Introduces
z5labsmodule withGoApp.Ci(shared checks + multi-arch build + conditional publish viaskopeo) andGoLib.Ci(checks-only). - Adds an acceptance test module with fixtures and 13 Dagger-invokable tests validating publish decision logic, ref normalization, and builder outputs.
- Registers
z5labs-testsin the rootdagger.jsonand runs it fromci/main.go.
Reviewed changes
Copilot reviewed 26 out of 28 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| daggerverse/z5labs/main.go | Defines the Z5labs module entrypoints (GoApp, GoLib) and embeds default lint config. |
| daggerverse/z5labs/helpers.go | Implements shared check pipeline and helpers for lint config materialization and go.mod parsing. |
| daggerverse/z5labs/goapp.go | Implements GoApp CI pipeline, multi-arch build, git ref matching, and publish via skopeo. |
| daggerverse/z5labs/builder.go | Adds Builder for host-platform container/binary production. |
| daggerverse/z5labs/golib.go | Implements GoLib checks-only CI pipeline. |
| daggerverse/z5labs/configs/golangci.yml | Provides the default golangci-lint configuration embedded by the module. |
| daggerverse/z5labs/dagger.json | Declares the z5labs module and its dependency on daggerverse/go. |
| daggerverse/z5labs/go.mod | Go module definition for dagger/z-5-labs. |
| daggerverse/z5labs/go.sum | Dependency lockfile for the z5labs module. |
| daggerverse/z5labs/.gitignore | Ignores generated bindings and env files for the module. |
| daggerverse/z5labs/.gitattributes | Marks generated files as linguist-generated for the module. |
| daggerverse/z5labs/tests/main.go | Adds the z5labs acceptance test suite and registry/git fixture helpers. |
| daggerverse/z5labs/tests/dagger.json | Declares the tests module and dependencies (z5labs, random, go). |
| daggerverse/z5labs/tests/go.mod | Go module definition for the tests module. |
| daggerverse/z5labs/tests/go.sum | Dependency lockfile for the tests module. |
| daggerverse/z5labs/tests/.gitignore | Ignores generated bindings and env files for the tests module. |
| daggerverse/z5labs/tests/.gitattributes | Marks generated files as linguist-generated for the tests module. |
| daggerverse/z5labs/tests/fixtures/hello/go.mod | Adds Go app fixture module metadata. |
| daggerverse/z5labs/tests/fixtures/hello/main.go | Adds simple hello-world app fixture used by tests. |
| daggerverse/z5labs/tests/fixtures/hello/main_test.go | Adds passing unit test for the hello-world fixture. |
| daggerverse/z5labs/tests/fixtures/hello-lib/go.mod | Adds Go library fixture module metadata. |
| daggerverse/z5labs/tests/fixtures/hello-lib/lib.go | Adds simple library fixture used by tests. |
| daggerverse/z5labs/tests/fixtures/hello-lib/lib_test.go | Adds passing unit test for the library fixture. |
| daggerverse/z5labs/tests/fixtures/failing-lib/go.mod | Adds failing library fixture module metadata. |
| daggerverse/z5labs/tests/fixtures/failing-lib/lib.go | Adds failing library fixture implementation. |
| daggerverse/z5labs/tests/fixtures/failing-lib/lib_test.go | Adds intentionally failing unit test for negative-path coverage. |
| dagger.json | Registers z5labs-tests as a root dependency. |
| ci/main.go | Wires z5labs test suite into the root Ci.Test orchestrator. |
Comments suppressed due to low confidence (1)
daggerverse/z5labs/tests/main.go:332
- This uses
curlimages/curl:latest, which is a moving target and can introduce flaky failures when the image changes. Prefer pinning to a specific version tag or digest (similar to how other test suites pin curl).
out, err := dag.Container().From("curlimages/curl:latest").
WithServiceBinding(host, svc).
- GoApp.Ci: cache=never (publish is side-effecting; session caching can silently skip pushes on re-runs). - Git working-tree check: accept .git as directory or file (worktrees, submodules); wrap the underlying error instead of dropping it. - Fix stale "via crane" comment to match the skopeo implementation. - skopeo --dest-tls-verify defaults to true; only disabled when a registryService is wired in (test-only HTTP registry). - Pin quay.io/skopeo/stable to v1.22.2 (was :latest) for reproducibility. - parsePlatform accepts GOOS/GOARCH/variant (e.g. linux/arm/v7). - Pin curlimages/curl to 8.10.1 in tests (was :latest), matching other test modules in this repo.
- tests/main.go: derive registry secret name from an independent random sha256 instead of pwdHex[:16]. Secret names appear in trace UIs and logs; the previous name leaked password material. - helpers.go: parseModuleDirective returns (string, error) and propagates scanner.Err() so I/O / long-line failures don't masquerade as a missing module directive.
- goapp.go: pass skopeo destination image as positional $1 instead of interpolating into the sh -c script. Eliminates shell-injection / quoting risk from caller-supplied registry, binary, and ref values. - goapp.go: sanitizeDockerTag now maps any character outside Docker's tag charset [A-Za-z0-9_.-] to '-' (was only ':' and '+'), replaces a leading '.'/'-' with '_', and truncates to 128 chars. Common tag schemes like "release/v1.2.3" now produce valid image tags instead of failing the publish. - tests/main.go: feed the registry password to htpasswd via WithSecretVariable + env expansion so it does not appear in container args (which show up in traces/logs). A separate NONCE env var preserves the per-call cache key — Dagger excludes secret values from cache keys, so without it a stale htpasswd file from an earlier password could be returned.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
daggerverse/z5labswithGoApp(multi-arch build + conditional publish) andGoLib(checks-only) archetypes. Depends ondaggerverse/goand reusesGo.Ci.Checkfor the standardized check stages.daggerverse/z5labs/tests/(covering happy path, fail-fast on missing.git, publish-decision matrix, ref normalization, multi-arch publish, tag-vs-branch precedence, and library failures) and wiresz5labs-testsinto the rootCi.Testorchestrator.skopeoin a service-bound sidecar instead ofContainer.Publishbecause the latter runs in BuildKit's engine context and does not see Dagger session service bindings — making it incompatible with locally-hostedregistry:2services used in tests. The skopeo pipeline copies all OCI variants (--all) fromContainer.AsTarballand writes them under tag names derived from the commit time so re-runs are idempotent.Resolves #71.
Test plan
dagger -m daggerverse/z5labs functionslistsgo-appandgo-lib;go-appexposesciandbuilder;builderexposescontainerandbinary;go-libexposesci.dagger -m daggerverse/z5labs/tests call <kebab-name>.dagger -m daggerverse/z5labs/tests call allpasses (56s, parallel=1).daggerverse/z5labs/dagger.jsondeclaresdaggerverse/goas a dependency.dagger developre-run in bothdaggerverse/z5labs/anddaggerverse/z5labs/tests/after signature changes.dagger call testin the root passes end-to-end (single-suite z5labs path verified; full root run not yet exercised in CI).🤖 Generated with Claude Code