Dagger
Search

ci

the example root (dagger.json lives at examples/kafka-consumer/, source "ci")
so `dagger call` works from anywhere in the example, and it codifies the
example's run configuration alongside its checks:

- RunAgainst().Local() stands up the whole stack locally (Redpanda + bundled
Schema Registry over TLS, plus an OpenTelemetry collector) and runs the
example consumer against it — a Dagger-native replacement for make+compose.

It also exercises the runnable example under examples/kafka-consumer/ end to end:

- GoAppCi builds it through the z5labs GoApp archetype (fmt/vet/lint/test
-race + multi-arch build). This is the only +check — it runs in CI.
- MtlsAvroConsume / TlsAvroConsume stand up a TLS (or mTLS) Kafka cluster, a
TLS/mTLS Schema Registry, and an OpenTelemetry collector wired to Tempo/
Mimir/Loki, produce framed Avro records, run the example consumer against
the stack, and assert it both decoded the records and exported telemetry.

The integration tests are BLOCKED by a known kafka-module bug — #147:
SchemaRegistry.BindTo's advertised alias is not resolvable from a WithExec
process (the service handle detaches when it rides on the cross-module
SchemaRegistry object). MtlsAvroConsume fails at exactly `KafkaSchemaRegistry.
bindTo`, so it is deliberately NOT a +check (it would be red-by-#147, not
red-by-#150). It is kept runnable via `dagger call mtls-avro-consume` as a
faithful reproduction of the end-to-end user experience that triggers #147,
and should be promoted back to +check once #147 lands. See the example's
README for details.

The example source is loaded as a contextual argument (+defaultPath), so the
+check function runs under `dagger check` with no CLI arguments.

Installation

dagger install github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e

Entrypoint

Return Type
Ci
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
func (m *MyModule) Example() *dagger.Ci  {
	return dag.
			Ci()
}
@function
def example() -> dagger.Ci:
	return (
		dag.ci()
	)
@func()
example(): Ci {
	return dag
		.ci()
}

Types

Ci 🔗

all() 🔗

All runs the suite sequentially, for local dagger call all. CI runs only GoAppCi (the sole +check); the integration round-trip is blocked by #147.

Return Type
Void !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -No description provided
kafkaImageTagString !"4.2.0"No description provided
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 all --kafka-image-tag string
func (m *MyModule) Example(ctx context.Context, kafkaImageTag string)   {
	return dag.
			Ci().
			All(ctxkafkaImageTag)
}
@function
async def example(kafkaimagetag: str) -> None:
	return await (
		dag.ci()
		.all(kafkaimagetag)
	)
@func()
async example(kafkaImageTag: string): Promise<void> {
	return dag
		.ci()
		.all(kafkaImageTag)
}

goAppCi() 🔗

GoAppCi builds the example through the z5labs GoApp archetype: fmt, vet, golangci-lint, go test -race, and a multi-arch build. GoApp.Ci requires a git working tree, so the loaded source is wrapped with gitFixture first.

Return Type
Void !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -No description provided
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 go-app-ci
func (m *MyModule) Example(ctx context.Context)   {
	return dag.
			Ci().
			Goappci(ctx)
}
@function
async def example() -> None:
	return await (
		dag.ci()
		.goappci()
	)
@func()
async example(): Promise<void> {
	return dag
		.ci()
		.goAppCi()
}

mtlsAvroConsume() 🔗

MtlsAvroConsume is the recommended-posture integration test: the whole stack runs with mutual TLS on both the broker and the Schema Registry hops.

NOT a +check: it reproduces #147 (SchemaRegistry.BindTo alias unresolvable from WithExec) and fails at KafkaSchemaRegistry.bindTo. Run it on demand with dagger call mtls-avro-consume; promote back to +check once #147 lands.

Return Type
Void !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -No description provided
kafkaImageTagString !"4.2.0"No description provided
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 mtls-avro-consume --kafka-image-tag string
func (m *MyModule) Example(ctx context.Context, kafkaImageTag string)   {
	return dag.
			Ci().
			Mtlsavroconsume(ctxkafkaImageTag)
}
@function
async def example(kafkaimagetag: str) -> None:
	return await (
		dag.ci()
		.mtlsavroconsume(kafkaimagetag)
	)
@func()
async example(kafkaImageTag: string): Promise<void> {
	return dag
		.ci()
		.mtlsAvroConsume(kafkaImageTag)
}

runAgainst() 🔗

RunAgainst starts the run-configuration chain. The example source is loaded as a contextual argument so dagger call run-against local needs no arguments.

Return Type
RunAgainst !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -No description provided
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 run-against
func (m *MyModule) Example() *dagger.CiRunAgainst  {
	return dag.
			Ci().
			Runagainst()
}
@function
def example() -> dagger.CiRunAgainst:
	return (
		dag.ci()
		.runagainst()
	)
@func()
example(): CiRunAgainst {
	return dag
		.ci()
		.runAgainst()
}

tlsAvroConsume() 🔗

TlsAvroConsume is the server-TLS (trust-only) variant, runnable on demand. Like MtlsAvroConsume it currently reproduces #147 and is not a

Return Type
Void !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -No description provided
kafkaImageTagString !"4.2.0"No description provided
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 tls-avro-consume --kafka-image-tag string
func (m *MyModule) Example(ctx context.Context, kafkaImageTag string)   {
	return dag.
			Ci().
			Tlsavroconsume(ctxkafkaImageTag)
}
@function
async def example(kafkaimagetag: str) -> None:
	return await (
		dag.ci()
		.tlsavroconsume(kafkaimagetag)
	)
@func()
async example(kafkaImageTag: string): Promise<void> {
	return dag
		.ci()
		.tlsAvroConsume(kafkaImageTag)
}

RunAgainst 🔗

RunAgainst is the example’s run-configuration chain. It codifies “where do I run the consumer” the way an IDE run configuration would, but in Dagger so it is reproducible and shareable across a team. Local() stands the whole stack up on the local engine (a docker-compose replacement); a future NonProd() will point the same consumer container at an already-deployed non-prod environment instead of spinning services up.

source() 🔗

Source is the example source tree — the app that gets built and run.

Return Type
Directory !
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 run-against \
 source
func (m *MyModule) Example() *dagger.Directory  {
	return dag.
			Ci().
			Runagainst().
			Source()
}
@function
def example() -> dagger.Directory:
	return (
		dag.ci()
		.runagainst()
		.source()
	)
@func()
example(): Directory {
	return dag
		.ci()
		.runAgainst()
		.source()
}

local() 🔗

Local stands up a complete local stack — a single-node Redpanda broker with its bundled Schema Registry (server-TLS), plus an OpenTelemetry collector fronting Tempo/Mimir/Loki — produces framed Avro records onto a topic, then builds and runs the example consumer against it, returning the consumer’s stdout. It is meant to be a Dagger-native replacement for a docker-compose “up”: one command brings up every dependency and the app, wired together, runnable from anywhere in the example.

This models exactly how a developer would run the example locally, and is the canonical reproduction to reference when planning the fix for kafka-module bug #147. Redpanda + bundled Schema Registry was chosen because it sidesteps #147 for the SR REST hop in isolation (the SR is reached at broker-host:8081 via BindBrokers, not the cross-module SchemaRegistry.BindTo alias). It does NOT sidestep #147 for the full produce→consume flow, however: seeding the topic with a module-side producer starts the lone Redpanda service and then releases it, so by the time the external consumer container binds the broker the service has detached — the consumer’s WithExec fails at hosts-file setup with “lookup redpanda-1-… no such host”, the same detached-ModuleObject wall #147 is about. So Local currently FAILS by design; it is not a +check, and it will run green once #147 lands. See the example README for the full write-up.

Redpanda supports server-TLS but not mTLS, so the local wire + registry hops are server-TLS (trust-only). Local does not assert on telemetry — it just returns the consumer’s stdout — but the observability backends run so a developer (or a future dashboard) can point a UI at them.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
redpandaTagString !"v26.1.7"No description provided
Example
dagger -m github.com/z5labs/devex/examples/kafka-consumer@93616a322270189d6f9aa8985071fa6dd1f9282e call \
 run-against \
 local --redpanda-tag string
func (m *MyModule) Example(ctx context.Context, redpandaTag string) string  {
	return dag.
			Ci().
			Runagainst().
			Local(ctx, redpandaTag)
}
@function
async def example(redpandatag: str) -> str:
	return await (
		dag.ci()
		.runagainst()
		.local(redpandatag)
	)
@func()
async example(redpandaTag: string): Promise<string> {
	return dag
		.ci()
		.runAgainst()
		.local(redpandaTag)
}