Skip to content

story(dagger): move both modules to Dagger v1.0.0-beta.15 and the v1 config shape - #430

Merged
zaba505-auto-merge[bot] merged 2 commits into
mainfrom
issue-429
Oct 23, 2026
Merged

zaba505-auto-merge[bot] merged 2 commits into
mainfrom
issue-429

Conversation

@Zaba505

@Zaba505 Zaba505 commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Closes #429

Moves both Dagger modules from v0.21.8 to v1.0.0-beta.15 and to the v1 config shape in one change, following upstream's migration path: dagger workspace migrate -y, then dagger generate -y, then commit dagger.toml, each dagger-module.toml, the generated code and dagger.lock.

Judgment calls

  • Ci is no longer a +check. On beta.15, dagger call <a +check function> hands back a Check object and exits 0 whether the check passed or failed. I measured it: dagger call engine-lock over two modules that disagree printed the failure and exited 0, and dagger check engine-lock exited 1. Left as a +check, dagger call ci (CI's gate, the contributor's gate, and the backlog verify command) could never fail. As a plain function it returns its error and exits non-zero. I checked that both ways: it exited 1 on a mismatched tree and 0 on a clean one. Every part of ci is still a +check, so dagger check runs them all, and no longer runs them twice. story(daggerverse): drop the +check annotations on builder objects dagger check cannot reach z5labs/devex#444 dropped the annotation from its builders' Ci for the same reason. CONTRIBUTING now says to narrow down with dagger check <stage>, not dagger call <stage>.
  • Ci(ctx, callingWorkspace *dagger.Workspace). The new generated part reads the workspace rather than Source. The CLI fills the argument in, so dagger call ci still takes no arguments (checked).
  • A new dependency in .dagger/go.mod: github.com/BurntSushi/toml v1.6.0, for EngineLock's TOML parsing. The parsing lives in internal/enginelock so tests can reach it. dagger generate keeps the require (checked).

Acceptance criteria

The tree

  • Both modules declare engineVersion = "v1.0.0-beta.15" in a dagger-module.toml, and no dagger.json remains. The root dagger.toml installs cpybkc (source .) as the entrypoint, installs dagger-go-sdk, and gives . and daggerverse/cpybkc each a Go SDK scope. The companion is a local client of the root scope (clients = ["./daggerverse/cpybkc", …]), and the root dagger-module.toml keeps the companion dependency edge.
  • Both devex dependencies are pinned to fa34af9 (devex main, 2026-10-18), whose go and z5labs modules declare beta.15. The commit appears in each dependency's source and in the matching clients entry. API changes between c10a120 and fa34af9 in the two modules: devex#444 removed +check from go's Ci.Check and Ci.Run and from z5labs's GoChain.Ci. In the regenerated client they return error, not a deferred *dagger.Check. .dagger/ calls GoChain.Ci(ctx) and uses its error, so no source change was needed. z5labs now also depends on devex's oci module, which resolves transitively. Nothing else in either module's non-generated source changed (git diff c10a120 fa34af9 -- daggerverse/go daggerverse/z5labs).
  • The Go SDK and sdk-helpers resolve from pins in the committed dagger.lock: git-latest entries resolve github.com/dagger/go-sdk to refs/tags/v1.1.0 and sdk-helpers v1 to refs/tags/v1.0.6, and git-sha entries pin each to a commit.
  • dagger generate -y on the committed tree changes nothing. Every generated file, including .dagger/internal/dagger/companion.gen.go and daggerverse/cpybkc/dagger.gen.go from story(container): below 1.0.0 any release may break a covered thing, and the covered tables say what 1.0.0 will promise #414/story(cli): cpybkc init writes each copybook as a definitions file beside the layout, so a project regenerates with no copybook #425, is what beta.15 writes. Deleting the generated files and regenerating also reproduces the tree exactly.
  • No Dagger command run against the tree printed No workspace config found, inferring from dagger.json. I grepped every run log from this work.
  • dagger -m github.com/Zaba505/cpybkc/daggerverse/cpybkc@issue-429 functions lists the companion's eight functions.

Checks

  • EngineLock reads engineVersion from both dagger-module.toml files with a TOML parser (internal/enginelock, BurntSushi/toml). It fails on a bump made in one module but not the other, in both directions (unit tests, plus dagger check engine-lock exited 1 on a real one-sided bump), and its message and tests name dagger-module.toml.
  • ci fails when committed codegen is stale. Measured on beta.15: upstream's dagger-go-sdk stale check (dagger check --generated) catches all of these: a binding with a line appended, a go.mod with a require removed, a dagger-module.toml with a pin key restored that codegen drops, and a companion function added without regenerating the root's client. So ci runs it, through the new Generated check. It runs the SDK module's checks via Workspace.artifacts and finds the module by the SDK's ref rather than by a hard-coded name.
    • Stale-binding test: on every run, Generated also makes .dagger/internal/dagger/companion.gen.go stale in a copy of the workspace (never written back) and fails unless that copy fails. That is why a passing run reports checks: 2/2 done (1 failed). A real stale tree fails ci with the files regeneration would change and the fix. It happened during this work, when codegen turned out to own each module's .gitattributes:
      ! committed codegen is stale:
      !   generated files are not up to date
      ! regeneration changes:
      !   .dagger/.gitattributes
      !   daggerverse/cpybkc/.gitattributes
      ! run `dagger generate -y` and commit what it writes, dagger.lock included (CONTRIBUTING.md, "After changing the module")
      
  • dagger.lock is committed, and the reason sits beside the regeneration instructions in CONTRIBUTING's After changing the module. The ci job and both Dagger jobs in release.yaml end with an if: always() step that runs git diff --exit-code dagger.lock and names the fix in an ::error. Note that a ci run resolves golang image digests that dagger generate never pins, so those entries are committed here too.
  • dagger call ci passes on beta.15 locally (exit 0, the tree and dagger.lock unchanged afterwards). CI is below.

CI and release

  • ci.yaml and both Dagger install steps in release.yaml install the version declared in the root dagger-module.toml, read with Python's tomllib (standard library, on every hosted runner) rather than jq over dagger.json.
  • The release workflow's Dagger calls were exercised on beta.15 by a local dry run of the same calls from an ordinary clone of this branch:
    • all four dagger call … export artifact builds succeeded;
    • dagger call release --tag irpb/v0.0.0 … (dummy credentials) passed the credential gate and the release plan, and returned irpb/v0.0.0 is not a release of the image …; nothing published;
    • dagger call release-notes refused v0.0.0 because it does not point at HEAD, which is correct. With a local-only tag v99.0.0 on HEAD (never pushed, deleted afterwards) it spliced the image block. With an irpb/ tag it left the notes unchanged;
    • git diff --exit-code dagger.lock was clean afterwards.

Docs

  • CONTRIBUTING.md:
    • Getting the tools installs from dagger-module.toml via tomllib.
    • After changing the module uses dagger generate -y and commits dagger.lock, with the reason.
    • One engineVersion… is re-measured on beta.15. The edge now refuses only a companion a whole release ahead (module requires dagger v1.1.0, but you have v1.0.0-beta.15), because beta.15 ignores the prerelease: a companion at v1.0.0-beta.99, or at v1.0.0, loads.
    • The companion section's dagger develop line is updated.
    • DAGGER_LEAVE_OLD_ENGINE=1 is explained in a new Running another Dagger version beside this one.
    • Running one stage switches to dagger check and explains why.
  • The dagger develop/dagger.json wording is updated in .dagger/companion.go, daggerverse/cpybkc/main.go, .gitignore and renovate.json's go.mod rule. In .gitattributes, codegen writes /dagger.gen.go, /internal/dagger/** and /internal/telemetry/** itself (it appends any that are missing). Each module's file now keeps those and adds go.mod/go.sum, which codegen also rewrites.
  • README.md states the minimum Dagger CLI, v1.0.0-beta.15, for driving the companion module.
  • Measured: dagger call ci does not run inside a git worktree on beta.15. It fails in 4s at load contextual arg "gitDir" … stat …/.git: not a directory, and dagger check fails the same way. dagger generate does run in a worktree and is a no-op there. CONTRIBUTING records this, so the backlog cycle's "verify from an ordinary clone" step is confirmed.

How it was verified

From an ordinary clone of this branch (/var/tmp), on a beta.15 engine: dagger generate -y was a no-op, dagger call ci exited 0, dagger.lock and the tree were unchanged, go test ./internal/enginelock/ passed, and the release dry run above succeeded. Separately, dagger call ci exited 1 on a tree with a one-sided engine bump, and Generated failed on a stale companion source.

🤖 Generated with Claude Code

…config shape

Migrate the workspace with `dagger workspace migrate`: a root dagger.toml
installing the root module as the entrypoint and the Go SDK with one scope per
module (the companion a local client of the root), a dagger-module.toml per
module declaring engineVersion v1.0.0-beta.15, and a committed dagger.lock.
Both devex dependencies move to fa34af9, whose modules declare beta.15, and
every generated file is regenerated with `dagger generate -y` — including the
two #414 and #425 edited by hand.

`ci` gains Generated, which runs the Go SDK's own staleness check (measured
catching a stale binding, go.mod, dagger-module.toml and companion client) and
proves on every run that a deliberately stale binding turns it red. EngineLock
reads both dagger-module.toml files with a TOML parser. Ci is no longer a
+check: on v1 `dagger call` exits 0 on a failed check, which would have made
the gate unfailable.

CI and release install the CLI version the root dagger-module.toml declares,
read with tomllib, and every Dagger job fails if it left dagger.lock changed.

Closes #429

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

CONTRIBUTING.md contains contradictory guidance about dagger check exit status vs earlier documented behavior and should be corrected to avoid misleading contributors.

1 open issue
7 files not reviewed
  • .dagger/dagger.gen.go: Generated file
  • .dagger/internal/dagger/companion.gen.go: Generated file
  • .dagger/internal/dagger/cpybkc.gen.go: Generated file
  • .dagger/internal/dagger/go.gen.go: Generated file
  • .dagger/internal/dagger/z-5-labs.gen.go: Generated file
  • daggerverse/cpybkc/dagger.gen.go: Generated file
  • daggerverse/cpybkc/internal/dagger/cpybkc.gen.go: Generated file
What changed in this PR

This PR migrates the repository’s two Dagger modules (root pipeline and daggerverse/cpybkc) from Dagger v0.21.8 / dagger.json to Dagger v1 (dagger-module.toml + workspace dagger.toml) pinned at v1.0.0-beta.15, updating generated bindings, lockfile pinning, CI/release install steps, and contributor docs to match the new v1 workflow.

Changes:

  • Replace dagger.json configs with v1 dagger-module.toml + workspace dagger.toml, and commit the corresponding regenerated Go bindings.
  • Add/strengthen safeguards for drift: EngineVersion lock check via TOML parsing and a new “generated code is committed” check, plus CI/release enforcement that dagger.lock remains unchanged after runs.
  • Update docs and automation (README/CONTRIBUTING/workflows/renovate) to use dagger generate/dagger check and to install the CLI version by parsing dagger-module.toml.
File Description
renovate.json Updates Renovate rationale to reflect dagger generate + dagger-module.toml v1 shape.
README.md Documents minimum required Dagger CLI (v1.0.0-beta.15) for the companion module.
daggerverse/​cpybkc/​main.go Updates module commentary to reference dagger-module.toml + EngineLock.
daggerverse/​cpybkc/​internal/​dagger/​cpybkc.gen.go Adds v1-generated Go client bindings for the companion module.
daggerverse/​cpybkc/​dagger.json Removes legacy v0 module config.
daggerverse/​cpybkc/​dagger.gen.go Updates generated module schema/metadata emitted for v1.
daggerverse/​cpybkc/​dagger-module.toml Adds v1 module config for the companion (engine pinned to beta.15).
daggerverse/​cpybkc/​.gitattributes Marks additional codegen-managed files (go.mod/go.sum) as generated.
dagger.toml Adds v1 workspace config (modules + Go SDK scopes/clients).
dagger.lock Adds committed lockfile pinning SDK refs and image digests.
dagger.json Removes legacy root v0 module config.
dagger-module.toml Adds v1 root module config (engine pinned to beta.15 + deps updated to devex fa34af9).
CONTRIBUTING.md Updates contributor workflow to v1 (dagger generate, dagger check, lockfile policy, worktree caveat).
.gitignore Updates guidance about committed codegen + dagger.lock under v1.
.github/​workflows/​release.yaml Installs Dagger CLI by parsing dagger-module.toml; enforces clean dagger.lock post-run.
.github/​workflows/​ci.yaml Installs Dagger CLI by parsing dagger-module.toml; enforces clean dagger.lock post-run.
.dagger/​main.go Updates pipeline entrypoint to accept workspace arg; adds Generated check; removes +check from Ci.
.dagger/​internal/​enginelock/​enginelock.go New TOML-based engineVersion parsing + comparison helper for EngineLock.
.dagger/​internal/​enginelock/​enginelock_test.go Unit tests pin enginelock parsing/error semantics and mismatch behavior.
.dagger/​internal/​dagger/​z-5-labs.gen.go Regenerated devex z5labs bindings for updated dependency pin/version.
.dagger/​internal/​dagger/​go.gen.go Regenerated devex go bindings for updated dependency pin/version.
.dagger/​internal/​dagger/​companion.gen.go Regenerated companion bindings in root module client.
.dagger/​go.sum Adds BurntSushi/toml checksums for new EngineLock TOML parsing.
.dagger/​go.mod Adds BurntSushi/toml dependency for internal/enginelock.
.dagger/​generated.go Adds a check that committed codegen matches dagger generate output (uses SDK stale check + proof).
.dagger/​companion.go Updates EngineLock implementation to use TOML parsing (internal/enginelock) and v1 manifest name.
.dagger/​.gitattributes Marks additional codegen-managed files (go.mod/go.sum) as generated.

Review effort: Lite

Comment thread CONTRIBUTING.md Outdated
Comment on lines +156 to +158
The one-platform form is a `dagger call`, because `dagger check` passes a check
no arguments — so read its `CHECKS` summary rather than its exit status, which is
0 whether the contract held or not (see [Running one stage](#running-one-stage)).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair — "its" read as dagger check. Reworded in 67cf99e: the exit-0 behaviour is dagger call on a check, which the one-platform form has to use because dagger check cannot pass arguments; dagger check image-contract exits non-zero on a failure as usual.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Zaba505 Zaba505 added the auto-merge Hand this pull request to the auto merge workflow label Oct 23, 2026
@zaba505-auto-merge
zaba505-auto-merge Bot merged commit 1440bd3 into main Oct 23, 2026
4 checks passed
@zaba505-auto-merge
zaba505-auto-merge Bot deleted the issue-429 branch October 23, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge Hand this pull request to the auto merge workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

story(dagger): move both modules to Dagger v1.0.0-beta.15 and the v1 config shape

2 participants