Skip to content

testrunner: use buildkit PassthroughOp for validation-only steps#1099

Draft
cpuguy83 wants to merge 2 commits into
project-dalec:mainfrom
cpuguy83:buildkit-passthrough-op
Draft

testrunner: use buildkit PassthroughOp for validation-only steps#1099
cpuguy83 wants to merge 2 commits into
project-dalec:mainfrom
cpuguy83:buildkit-passthrough-op

Conversation

@cpuguy83

Copy link
Copy Markdown
Collaborator

Stacked on #1097. This branch is based on #1097's test-buildkit-0.31.0-rc2,
so the diff below also includes that PR's go.mod/go.sum bump and CI
changes until #1097 lands on main. The passthrough work is the final
commit; review that one (testrunner: use buildkit PassthroughOp for validation-only steps).

What

Integrate buildkit's PassthroughOp (new in v0.31) to express "evaluate this
state for validation only" in the package test runner, replacing the
long-standing no-op true command hack.

  • WithFinalState uses llb.State.Requires when the daemon advertises
    pb.CapPassthroughOp, otherwise falls back to the existing
    trueCmd.WithOutput exec.
  • Capability detection mirrors SupportsDiffMerge: the router probes the
    client's LLBCaps once per process and records the result on a
    process-global atomic toggle.
  • DALEC_DISABLE_PASSTHROUGH=1 forces the legacy path.

Backwards compatibility

Daemons that don't advertise the capability keep using the fallback, so
behavior is unchanged for them.

Testing

  • New unit test (internal/testrunner/runner_test.go) locks in the
    passthrough-vs-exec wiring.
  • testLinuxPackageTestsFail now runs both with and without
    DALEC_DISABLE_PASSTHROUGH, exercising both the PassthroughOp and the
    fallback paths.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR integrates buildkit's new PassthroughOp (from v0.31.0) into the dalec test runner, replacing the previous no-op exec hack used to express "evaluate this state for validation only." The PR is stacked on #1097, which bumps the buildkit dependency to v0.31.0-rc2 and pins CI builders to this version.

Changes:

  • WithFinalState now uses llb.State.Requires when the daemon supports PassthroughOp, falling back to the existing no-op exec on older daemons. Capability detection follows the same sync.Once+atomic.Bool pattern used for SupportsDiffMerge.
  • A new DALEC_DISABLE_PASSTHROUGH build arg allows forcing the legacy fallback path, wired through load.go, frontend/gateway.go, and frontend/router.go.
  • New unit test validates both the passthrough and fallback paths; testLinuxPackageTestsFail integration test now exercises both code paths.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
helpers.go Adds passthroughOpSupported atomic.Bool with getter/setter, mirroring disableDiffMerge
frontend/gateway.go Adds SupportsPassthroughOp with sync.Once-guarded capability check and DALEC_DISABLE_PASSTHROUGH override
frontend/router.go Calls SupportsPassthroughOp at handler startup and records result via SetPassthroughOpSupported
internal/testrunner/runner.go Updates WithFinalState to branch on capability; adds finalStateRequiresID constant
internal/testrunner/runner_test.go New unit test verifying passthrough-vs-exec wiring in WithFinalState
load.go Registers DALEC_DISABLE_PASSTHROUGH as a known build arg
test/linux_target_test.go Wraps testLinuxPackageTestsFail to run both passthrough modes; refactors body into testLinuxPackageTestsFailMode
go.mod Bumps buildkit to v0.31.0-rc2, Go to 1.25.9, and transitive dependencies
go.sum Updated checksums for dependency bumps
.github/workflows/ci.yml Pins CI builders to moby/buildkit:v0.31.0-rc2; creates buildx container builders for integration and e2e jobs; improves log collection

@cpuguy83 cpuguy83 marked this pull request as draft June 16, 2026 01:54
cpuguy83 and others added 2 commits June 18, 2026 09:30
Pin the CI builders to moby/buildkit:v0.31.0 and bump the buildkit Go
module to match so both the integration (distro) matrix and the e2e suite
build against the released buildkitd.

Behavior changes:
- Add a top-level BUILDKIT_TEST_IMAGE env as the single source of truth for
  the buildkit image under test.
- The integration job now creates a buildx container builder pinned to the
  test image and uses it, instead of relying on the engine's embedded
  buildkit. The test harness (buildx dial-stdio) and the bake pre-builds all
  target this builder. Its failure log dump now also collects the
  buildx_buildkit_* container logs.
- The e2e job creates a pinned container builder for both diff/merge matrix
  legs (USE_BUILDX=1 for both) rather than only the diff/merge-enabled leg
  falling back to the default docker driver for the other.
- Bump github.com/moby/buildkit v0.30.0 -> v0.31.0 (with the transitive
  updates pulled in by go mod tidy).

Trade-offs:
- The integration job previously used the default docker driver, so bake
  pre-builds landed in the docker image store. With a container builder they
  warm the builder cache instead; tests consume the frontend as a buildkit
  frontend-input and reuse the same builder, so this is functionally
  equivalent but is the main thing to watch on the first run.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Package tests run validation steps purely for their side effect of
failing the build when a check does not hold; their filesystem output is
discarded. Previously the test runner forced this evaluation with a
documented hack: it ran a no-op `true` command whose root mount was the
state to validate, relying on the exec being evaluated to pull the
validation steps into the build graph.

buildkit v0.31 adds the PassthroughOp, exposed via llb.State.Requires,
which expresses exactly this intent: return one state's output while
requiring other states to be built. WithFinalState now uses it when the
daemon advertises pb.CapPassthroughOp.

Capability detection mirrors the existing SupportsDiffMerge path: the
router probes the client's LLBCaps once per process and records the
result on a process-global atomic toggle. A DALEC_DISABLE_PASSTHROUGH=1
build-arg forces the legacy path. Daemons that do not advertise the cap
keep using the trueCmd hack, so behavior is unchanged for them and
backwards compatibility is preserved.

The testrunner integration test (testLinuxPackageTestsFail) now runs
both with and without DALEC_DISABLE_PASSTHROUGH so the PassthroughOp and
the fallback wiring are both exercised.

Trade-offs: PassthroughOp is still experimental in buildkit, so it is
gated behind capability detection rather than required outright. The
detection flag is process-global (one buildkit daemon per frontend
process), consistent with how diff/merge support is already tracked.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
@cpuguy83 cpuguy83 force-pushed the buildkit-passthrough-op branch from 78d2890 to 0e8961e Compare June 18, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants