feat: Dagger module spike — ske-operator CI - #44
Draft
shano wants to merge 3 commits into
Draft
Conversation
Adds ci/dagger/ — a Go Dagger module replicating test-ske-operator.yaml with three structural improvements over the GHA version: - unit: golang:1.26 container with cached go modules, build artefacts, and envtest binaries; warm runs ~30s vs ~3min cold - e2e: pre-pulls cert-manager images before cluster creation and loads them into Kind, eliminating the cold-pull timing window - e2e: explicitly waits for all cert-manager deployments Available before deploying ske-operator (fixes recurring CrashLoopBackOff root cause) - e2e: Kind cluster in DIND service, insulating tests from runner variance Run 'dagger develop' from ci/dagger/ to generate dagger.gen.go and pin the SDK version before building or calling.
Restructure the module to make Dagger's value prop concrete: - SkeOperatorBuild returns *Container (typed artifact, content-addressed) - SkeOperatorE2e accepts *Container via AsTarball() + docker load — no registry push needed to pass the image between pipeline stages - SkeOperatorAll builds once then runs unit + e2e concurrently in Go goroutines, sharing go-mod and go-build cache volumes between both Comments explain what the GHA equivalent would require at each step where Dagger's typed pipeline diverges from the shell-script approach.
main.go was using bare Container/Directory/Secret which are not re-exported into the main package. Prefix with dagger. and re-run dagger develop to regenerate dagger.gen.go dispatch code with correct type assertions. go build ./... now passes clean.
shano
marked this pull request as draft
July 29, 2026 08:57
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.
What this is
Spike from Research Friday: port `test-ske-operator.yaml` to a Dagger Go module in the `ci` repo, structured to make Dagger's value prop concrete rather than just being a shell script in Go syntax.
Setup
```bash
cd dagger/
dagger develop # generates dagger.gen.go, pins SDK version
```
`dag`, `*Directory`, `*Secret`, `*Container` come from the generated file — the module won't compile until `dagger develop` runs.
The four functions
Why this structure (not just WithExec chains)
Typed artifacts — no registry round-trip
In GHA, passing a built Docker image from one job to the next requires pushing to a registry. Here, `SkeOperatorBuild` returns a `*Container`. `SkeOperatorE2e` calls `image.AsTarball()` and mounts the OCI tar directly into the DIND daemon via `docker load`. The image flows as a typed Go value. A release function would do the same: accept the same `*Container` and push it to GHCR — no rebuild.
Structural caching
`WithMountedCache` volumes are content-addressed by input hash. If `go.mod` didn't change, modules aren't re-downloaded. Both `SkeOperatorUnit` and `SkeOperatorE2e` share the same `ske-operator-go-mod` and `ske-operator-go-build` volumes — whichever runs first warms the cache for the other. In GHA this is a bolted-on `actions/cache` that you manage manually.
Parallelism is idiomatic Go
`SkeOperatorAll` calls `SkeOperatorBuild` once then fans out to unit and e2e via goroutines. No `needs:` arrays, no artifact upload/download between jobs.
e2e improvements over GHA
Where this goes next
Once validated, the `ske-operator` job in `test-ske.yaml` becomes:
```yaml
run: |
dagger -m ./dagger call ske-operator-all
--source=./enterprise-kratix/ske-operator
--github-token=env:GITHUB_TOKEN
--ske-license-token=env:SKE_LICENSE_TOKEN
```
The release pipeline would extend the same module: `SkeOperatorRelease(image *Container, version string)` — accepting the cached `*Container` from `SkeOperatorBuild` and pushing it to GHCR without rebuilding.
Known unknowns