Skip to content

ci: guard cmd/duckgres-controlplane against duckdb-go regressions#499

Merged
fuziontech merged 1 commit into
mainfrom
feature/ci-guard-controlplane-deps
May 1, 2026
Merged

ci: guard cmd/duckgres-controlplane against duckdb-go regressions#499
fuziontech merged 1 commit into
mainfrom
feature/ci-guard-controlplane-deps

Conversation

@fuziontech
Copy link
Copy Markdown
Member

Summary

Adds a controlplane-no-libduckdb job that builds cmd/duckgres-controlplane (both default tags and -tags kubernetes) and then runs:

go list -deps ./cmd/duckgres-controlplane | grep duckdb-go
go list -deps ./controlplane              | grep duckdb-go

If anything matches, the job fails the build.

This locks in the binary-split achievement from PRs #477-#498. Without this guard, someone could land a server/* extraction that grows a new duckdb-go transitive import and silently re-link libduckdb into the CP build — which would defeat the matrix-build per-DuckDB-version goal.

The error message points at the right diagnostic command and suggests the right fix (subpackage extraction / registration hook / interface boundary) rather than encouraging anyone to suppress the check.

Test plan

Verified locally:

  • go list -deps ./cmd/duckgres-controlplane | grep duckdb-go is empty
  • go list -deps ./controlplane | grep duckdb-go is empty
  • same with -tags kubernetes
  • YAML parses cleanly via python3 -c "import yaml; yaml.safe_load(open(...))"

The guard will run on this PR's CI as part of the new job.

🤖 Generated with Claude Code

Adds a controlplane-no-libduckdb job that builds cmd/duckgres-controlplane
(both default tags and -tags kubernetes) and then runs

  go list -deps ./cmd/duckgres-controlplane | grep duckdb-go
  go list -deps ./controlplane              | grep duckdb-go

If anything matches, the job fails the build.

This locks in the binary-split achievement from PRs #477-#498. Without
this guard, someone could land a server/* extraction that grows a new
duckdb-go transitive import and silently re-link libduckdb into the CP
build — which would defeat the matrix-build per-DuckDB-version goal.

The error message points at the right diagnostic command and suggests
the right fix (subpackage extraction / registration hook / interface
boundary) rather than encouraging anyone to suppress the check.

Verified locally:
  - go list -deps ./cmd/duckgres-controlplane | grep duckdb-go is empty
  - go list -deps ./controlplane              | grep duckdb-go is empty
  - same with -tags kubernetes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fuziontech fuziontech enabled auto-merge (squash) May 1, 2026 18:13
@fuziontech fuziontech merged commit 9713158 into main May 1, 2026
21 of 22 checks passed
@fuziontech fuziontech deleted the feature/ci-guard-controlplane-deps branch May 1, 2026 18:16
fuziontech added a commit that referenced this pull request May 1, 2026
…ibduckdb (#500)

Counterpart to cmd/duckgres-controlplane (PR #498). This binary:

  - Links libduckdb (verified: go list -deps shows duckdb-go-bindings,
    duckdb-go/v2 in the import graph).
  - Imports duckdbservice but not controlplane — no PG wire surface, no
    config-store / k8s pool wiring. It's the runtime that the control
    plane spawns into worker pods over Unix sockets / TCP.
  - Is the target of the planned per-DuckDB-version matrix build in CI.
    A worker pod ships exactly one DuckDB version, pinned via go.mod +
    the Dockerfile DUCKDB_EXTENSION_VERSION build arg.

Like cmd/duckgres-controlplane, this is a stub that errors out at
runtime — duckgres' YAML / CLI / env config resolution still lives in
the package main file at the repo root alongside the all-in-one binary.
The follow-up PR lifts that into a shared package both new binaries
can import. The point of this PR is locking in the binary's existence
and the import-graph contract.

Together with PR #498 (CP-only, no libduckdb) and PR #499 (CI guard),
the binary split is now structurally complete:

  cmd/duckgres-controlplane   no libduckdb (CP-only, all DuckDB versions
                              run on remote workers)
  cmd/duckgres-worker         links libduckdb (worker-only, pinned to
                              one DuckDB version per build)
  duckgres                    all-in-one (links libduckdb, all modes)

Verified:
  - go build ./cmd/duckgres-worker/... clean
  - go list -deps ./cmd/duckgres-worker | grep duckdb-go shows the
    expected DuckDB driver imports
  - go list -deps ./cmd/duckgres-controlplane | grep duckdb-go is still
    empty (the CP-only contract held)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fuziontech added a commit that referenced this pull request May 1, 2026
* feat: add Dockerfile.controlplane for the duckdb-free CP image

Builds cmd/duckgres-controlplane (PR #498). The image is the control-
plane Pod's runtime; all SQL execution is routed to remote
duckgres-worker images (Dockerfile.worker), so this image:

  - Does NOT link libduckdb (the controlplane-no-libduckdb CI guard
    from PR #499 enforces it)
  - Does NOT bundle the DuckDB extension downloads — without a DuckDB
    driver they'd be dead weight
  - Is meaningfully smaller than the all-in-one image

CGO is still enabled because the transpiler uses pg_query_go which
links libpg_query. That's a pure Postgres parser, nothing to do with
DuckDB.

Together with Dockerfile.worker (per-DuckDB-version, PR #501) and the
existing all-in-one Dockerfile (unchanged), the image set now mirrors
the binary set:

  duckgres                    (existing) — all-in-one, links libduckdb
  duckgres-worker             (new)      — worker-only, per-DuckDB-version
  duckgres-controlplane       (this PR)  — CP-only, no libduckdb

A CD workflow that publishes the controlplane image (single build per
sha, no DuckDB matrix needed since this binary is version-agnostic) is
the next PR.

Verified locally:
  - go build -o /tmp/duckgres-controlplane ./cmd/duckgres-controlplane
    builds clean (~40MB binary)

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

* ci: add CD pipeline for cmd/duckgres-controlplane image (#504)

Adds .github/workflows/container-image-controlplane-cd.yml — publishes
duckgres-controlplane:<sha> + duckgres-controlplane:latest as a multi-
arch manifest (arm64 + amd64) on every push to main.

Single build per sha — the CP is version-agnostic by design (one
image fits all worker fleets), so no DuckDB-version matrix here.
Contrast with container-image-worker-cd.yml (PR #502) which produces
one duckgres-worker image per (DuckDB version × arch).

Together with the existing all-in-one CD (container-image-cd.yml,
unchanged) and the worker matrix CD, the image pipeline now mirrors
the binary set:

  duckgres                container-image-cd.yml             (existing)
  duckgres-worker         container-image-worker-cd.yml      (PR #502)
  duckgres-controlplane   container-image-controlplane-cd.yml (this PR)

Stacked on PR #503 which adds Dockerfile.controlplane.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fuziontech added a commit that referenced this pull request May 5, 2026
…rar (#523)

Lifts the ~50 CLIInputs-backed CLI flag declarations out of root main.go
into configresolve.RegisterCLIInputsFlags so the all-in-one duckgres
binary and cmd/duckgres-controlplane share one flag table — adding a
new field to CLIInputs without registering a flag fails CI loudly via
the new TestRegisterCLIInputsFlagsCoversEveryCLIBackedField drift
guard, instead of silently doing nothing.

cmd/duckgres-controlplane is no longer a stub: it parses flags via
the shared registrar plus its own bespoke set (--config, --log-level,
--mode, --socket-dir, --version, --help), resolves config via
configresolve.ResolveEffective, ensures TLS certs (or hands off to
ACME), starts the metrics server, and calls
controlplane.RunControlPlane. Local smoke run confirms it binds the
PG-wire port + :9090, accepts TCP, and serves real Prometheus
metrics. The libduckdb-free invariant (CI guard #499) is preserved —
go list -deps reports no duckdb-go in the dep tree.

Worker stays bespoke (its 14 flags ARE the documented worker-pod
surface), and a --mode control-plane accept-and-validate flag mirrors
the worker's --mode duckdb-service for symmetry. cliboot.InitMetrics
is shared, and just test-unit now also runs ./configresolve/... so
the drift guard fires on every CI pass.

Co-authored-by: james <james@jams-spark.lan>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant