From 74736659b275dcb0f9e6fed05b2ea8e69e6cfcbb Mon Sep 17 00:00:00 2001 From: Bill Guowei Yang Date: Thu, 16 Jul 2026 12:57:28 -0400 Subject: [PATCH 1/2] build: update DuckLake to v1.0-posthog.6 --- .../workflows/container-image-worker-cd.yml | 2 +- .github/workflows/e2e-mw-dev.yml | 2 +- .github/workflows/scenario-dev.yml | 2 +- Dockerfile | 2 +- Dockerfile.worker | 2 +- tests/manifests/manifests_test.go | 65 +++++++++++++++++++ tests/mw-dev/e2e/harness.sh | 4 +- 7 files changed, 72 insertions(+), 7 deletions(-) diff --git a/.github/workflows/container-image-worker-cd.yml b/.github/workflows/container-image-worker-cd.yml index 6239dd21..e8ed819a 100644 --- a/.github/workflows/container-image-worker-cd.yml +++ b/.github/workflows/container-image-worker-cd.yml @@ -78,7 +78,7 @@ jobs: # as the credential-refresh scheduler keeps rotating the # ducklake_s3 secret. httpfs: "v1.5.3-cred-refresh-write-retry" - ducklake: "v1.0-posthog.5" + ducklake: "v1.0-posthog.6" # Stable repo hosts postgres_scanner for 1.5.3; nightly # does not. See scripts/ducklake_version_matrix.sh # commit history for the rationale on each row. diff --git a/.github/workflows/e2e-mw-dev.yml b/.github/workflows/e2e-mw-dev.yml index 92b42ca1..eb59596a 100644 --- a/.github/workflows/e2e-mw-dev.yml +++ b/.github/workflows/e2e-mw-dev.yml @@ -90,7 +90,7 @@ jobs: build-args: | DUCKDB_EXTENSION_VERSION=1.5.3 HTTPFS_EXTENSION_TAG=v1.5.3-cred-refresh-write-retry - DUCKLAKE_EXTENSION_TAG=v1.0-posthog.5 + DUCKLAKE_EXTENSION_TAG=v1.0-posthog.6 DUCKDB_EXTENSION_REPOSITORY=https://extensions.duckdb.org POSTGRES_SCANNER_REPOSITORY=https://extensions.duckdb.org secrets: diff --git a/.github/workflows/scenario-dev.yml b/.github/workflows/scenario-dev.yml index 64fed2bc..0b770b90 100644 --- a/.github/workflows/scenario-dev.yml +++ b/.github/workflows/scenario-dev.yml @@ -48,7 +48,7 @@ jobs: build-args: | DUCKDB_EXTENSION_VERSION=1.5.3 HTTPFS_EXTENSION_TAG=v1.5.3-cred-refresh-write-retry - DUCKLAKE_EXTENSION_TAG=v1.0-posthog.5 + DUCKLAKE_EXTENSION_TAG=v1.0-posthog.6 DUCKDB_EXTENSION_REPOSITORY=https://extensions.duckdb.org POSTGRES_SCANNER_REPOSITORY=https://extensions.duckdb.org secrets: diff --git a/Dockerfile b/Dockerfile index 0b66505d..4c690110 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN go mod download ARG TARGETARCH ARG DUCKDB_EXTENSION_VERSION=1.5.3 ARG HTTPFS_EXTENSION_TAG=v1.5.3-cred-refresh-write-retry -ARG DUCKLAKE_EXTENSION_TAG=v1.0-posthog.5 +ARG DUCKLAKE_EXTENSION_TAG=v1.0-posthog.6 ARG DUCKDB_EXTENSION_REPOSITORY=https://extensions.duckdb.org # Repository for postgres_scanner specifically. Defaults to the stable # extensions repo, overridable per-row in CI (e.g. legacy DuckDB versions diff --git a/Dockerfile.worker b/Dockerfile.worker index 55f6f7ab..ef9b890a 100644 --- a/Dockerfile.worker +++ b/Dockerfile.worker @@ -52,7 +52,7 @@ RUN go mod download # ran after the source COPY + build, so they re-fetched on every edit.) ARG DUCKDB_EXTENSION_VERSION=1.5.3 ARG HTTPFS_EXTENSION_TAG=v1.5.3-cred-refresh-write-retry -ARG DUCKLAKE_EXTENSION_TAG=v1.0-posthog.5 +ARG DUCKLAKE_EXTENSION_TAG=v1.0-posthog.6 ARG DUCKDB_EXTENSION_REPOSITORY=https://extensions.duckdb.org # Repository for postgres_scanner specifically. Defaults to the stable # extensions repo, overridable per-row in CI (e.g. legacy DuckDB versions diff --git a/tests/manifests/manifests_test.go b/tests/manifests/manifests_test.go index 4c7a4c54..f06c8e22 100644 --- a/tests/manifests/manifests_test.go +++ b/tests/manifests/manifests_test.go @@ -12,6 +12,8 @@ import ( "path/filepath" "strings" "testing" + + "gopkg.in/yaml.v3" ) func TestControlPlaneRBACIncludesLeaseAccess(t *testing.T) { @@ -134,6 +136,69 @@ func TestManifestTestsRunInUnitRecipe(t *testing.T) { } } +func TestCurrentDuckLakeReleasePins(t *testing.T) { + const ( + tag = "v1.0-posthog.6" + version = "49ec0dc8" + ) + + tests := []struct { + path []string + want []string + }{ + {path: []string{"Dockerfile"}, want: []string{"ARG DUCKLAKE_EXTENSION_TAG=" + tag}}, + {path: []string{"Dockerfile.worker"}, want: []string{"ARG DUCKLAKE_EXTENSION_TAG=" + tag}}, + {path: []string{".github", "workflows", "scenario-dev.yml"}, want: []string{"DUCKLAKE_EXTENSION_TAG=" + tag}}, + {path: []string{".github", "workflows", "e2e-mw-dev.yml"}, want: []string{"DUCKLAKE_EXTENSION_TAG=" + tag}}, + { + path: []string{"tests", "mw-dev", "e2e", "harness.sh"}, + want: []string{"DUCKLAKE_EXTENSION_TAG=" + tag, `EXPECT_DUCKLAKE_SHA="` + version + `"`}, + }, + } + + for _, tt := range tests { + content := readManifest(t, tt.path...) + for _, want := range tt.want { + if !strings.Contains(content, want) { + t.Errorf("expected %q in %s", want, filepath.Join(tt.path...)) + } + } + } + + var workflow struct { + Jobs map[string]struct { + Strategy struct { + Matrix struct { + DuckDB []struct { + DuckLake string `yaml:"ducklake"` + Default bool `yaml:"default"` + } `yaml:"duckdb"` + } `yaml:"matrix"` + } `yaml:"strategy"` + } `yaml:"jobs"` + } + workerWorkflow := readManifest(t, ".github", "workflows", "container-image-worker-cd.yml") + if err := yaml.Unmarshal([]byte(workerWorkflow), &workflow); err != nil { + t.Fatalf("parse worker image workflow: %v", err) + } + buildJob, ok := workflow.Jobs["build"] + if !ok { + t.Fatal("worker image workflow has no build job") + } + var defaults []string + for _, row := range buildJob.Strategy.Matrix.DuckDB { + if row.Default { + defaults = append(defaults, row.DuckLake) + } + } + if len(defaults) != 1 { + t.Fatalf("expected exactly one default DuckDB worker matrix row, got %d", len(defaults)) + } + if defaults[0] != tag { + t.Errorf("default DuckDB worker matrix row pins DuckLake %q, want %q", defaults[0], tag) + } +} + // readManifest reads a file relative to the project root (located by walking up // to the go.mod), matching how the manifests ship in the repo. func readManifest(t *testing.T, parts ...string) string { diff --git a/tests/mw-dev/e2e/harness.sh b/tests/mw-dev/e2e/harness.sh index b47018cf..0af49e04 100755 --- a/tests/mw-dev/e2e/harness.sh +++ b/tests/mw-dev/e2e/harness.sh @@ -111,9 +111,9 @@ READY_TIMEOUT="${READY_TIMEOUT:-1200}" # The bundled extensions MUST be the PostHog forks. These are the short commit # SHAs duckdb_extensions() reports for the tags the image pins -# (DUCKLAKE_EXTENSION_TAG=v1.0-posthog.5, HTTPFS_EXTENSION_TAG=v1.5.3-cred-refresh-write-retry). +# (DUCKLAKE_EXTENSION_TAG=v1.0-posthog.6, HTTPFS_EXTENSION_TAG=v1.5.3-cred-refresh-write-retry). # If the image accidentally ships upstream, the version differs and we fail. -EXPECT_DUCKLAKE_SHA="40174368" +EXPECT_DUCKLAKE_SHA="49ec0dc8" EXPECT_HTTPFS_SHA="0dac6fc" # duckling-example RDS — the shared external metadata store (same one the From 4de796ff6c83030523a9cc0a159dbe52da801077 Mon Sep 17 00:00:00 2001 From: Bill Guowei Yang Date: Thu, 16 Jul 2026 13:13:50 -0400 Subject: [PATCH 2/2] test: remove DuckLake release pin assertion --- tests/manifests/manifests_test.go | 65 ------------------------------- 1 file changed, 65 deletions(-) diff --git a/tests/manifests/manifests_test.go b/tests/manifests/manifests_test.go index f06c8e22..4c7a4c54 100644 --- a/tests/manifests/manifests_test.go +++ b/tests/manifests/manifests_test.go @@ -12,8 +12,6 @@ import ( "path/filepath" "strings" "testing" - - "gopkg.in/yaml.v3" ) func TestControlPlaneRBACIncludesLeaseAccess(t *testing.T) { @@ -136,69 +134,6 @@ func TestManifestTestsRunInUnitRecipe(t *testing.T) { } } -func TestCurrentDuckLakeReleasePins(t *testing.T) { - const ( - tag = "v1.0-posthog.6" - version = "49ec0dc8" - ) - - tests := []struct { - path []string - want []string - }{ - {path: []string{"Dockerfile"}, want: []string{"ARG DUCKLAKE_EXTENSION_TAG=" + tag}}, - {path: []string{"Dockerfile.worker"}, want: []string{"ARG DUCKLAKE_EXTENSION_TAG=" + tag}}, - {path: []string{".github", "workflows", "scenario-dev.yml"}, want: []string{"DUCKLAKE_EXTENSION_TAG=" + tag}}, - {path: []string{".github", "workflows", "e2e-mw-dev.yml"}, want: []string{"DUCKLAKE_EXTENSION_TAG=" + tag}}, - { - path: []string{"tests", "mw-dev", "e2e", "harness.sh"}, - want: []string{"DUCKLAKE_EXTENSION_TAG=" + tag, `EXPECT_DUCKLAKE_SHA="` + version + `"`}, - }, - } - - for _, tt := range tests { - content := readManifest(t, tt.path...) - for _, want := range tt.want { - if !strings.Contains(content, want) { - t.Errorf("expected %q in %s", want, filepath.Join(tt.path...)) - } - } - } - - var workflow struct { - Jobs map[string]struct { - Strategy struct { - Matrix struct { - DuckDB []struct { - DuckLake string `yaml:"ducklake"` - Default bool `yaml:"default"` - } `yaml:"duckdb"` - } `yaml:"matrix"` - } `yaml:"strategy"` - } `yaml:"jobs"` - } - workerWorkflow := readManifest(t, ".github", "workflows", "container-image-worker-cd.yml") - if err := yaml.Unmarshal([]byte(workerWorkflow), &workflow); err != nil { - t.Fatalf("parse worker image workflow: %v", err) - } - buildJob, ok := workflow.Jobs["build"] - if !ok { - t.Fatal("worker image workflow has no build job") - } - var defaults []string - for _, row := range buildJob.Strategy.Matrix.DuckDB { - if row.Default { - defaults = append(defaults, row.DuckLake) - } - } - if len(defaults) != 1 { - t.Fatalf("expected exactly one default DuckDB worker matrix row, got %d", len(defaults)) - } - if defaults[0] != tag { - t.Errorf("default DuckDB worker matrix row pins DuckLake %q, want %q", defaults[0], tag) - } -} - // readManifest reads a file relative to the project root (located by walking up // to the go.mod), matching how the manifests ship in the repo. func readManifest(t *testing.T, parts ...string) string {