From 9ddb17a7271afa972b3d306be3e89e993b6b6645 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Thu, 10 Sep 2026 09:42:14 -0400 Subject: [PATCH 1/2] fix: allow explicit native MDI source --- packages/runtime-core/src/recipe-builders.ts | 36 +++++++++++++++++--- tests/runtime-services.test.ts | 31 +++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/src/recipe-builders.ts b/packages/runtime-core/src/recipe-builders.ts index d81449e7..e27d50a9 100644 --- a/packages/runtime-core/src/recipe-builders.ts +++ b/packages/runtime-core/src/recipe-builders.ts @@ -78,9 +78,16 @@ export function buildWordPressPhpunitRecipe(options: WordPressPhpunitRecipeOptio const pluginTarget = `/wordpress/wp-content/plugins/${pluginSlug}` const autoloadFile = options.autoloadFile ?? (options.bootstrapMode === "project" ? "" : "/wp-codebox-vendor/autoload.php") const services = phpunitRuntimeServices(options.databaseType, options.services) - const extraPlugins = options.databaseType === "mdi-native" - ? [...normalizeExtraPlugins(options.extra_plugins), mdiNativePlugin()] - : normalizeExtraPlugins(options.extra_plugins) + const extraPlugins = normalizeExtraPlugins(options.extra_plugins) + if (options.databaseType === "mdi-native") { + const nativePlugin = nativeMdiPlugin(extraPlugins) + const nativeIndex = extraPlugins.findIndex((plugin) => plugin.slug === "markdown-database-integration") + if (nativeIndex === -1) { + extraPlugins.push(nativePlugin) + } else { + extraPlugins[nativeIndex] = nativePlugin + } + } return { schema: "wp-codebox/workspace-recipe/v1", @@ -155,7 +162,25 @@ function phpunitDependencyPlugins(mounts: readonly string[], plugins: readonly W }) } -function mdiNativePlugin(): WorkspaceRecipeExtraPlugin { +function nativeMdiPlugin(plugins: readonly WorkspaceRecipeExtraPlugin[]): WorkspaceRecipeExtraPlugin { + const candidates = plugins.filter((plugin) => plugin.slug === "markdown-database-integration") + if (candidates.length > 1) { + throw new Error("mdi-native accepts at most one markdown-database-integration extra plugin source") + } + const candidate = candidates[0] + if (candidate) { + return { + ...candidate, + slug: "markdown-database-integration", + pluginFile: "markdown-database-integration/markdown-database-integration.php", + activate: false, + metadata: { + ...candidate.metadata, + phase: "pre-install", + databaseDropIn: true, + }, + } + } return { source: "wp-codebox:mdi-native", sha256: "b01d119e994c5c498373edcd2e3a62fcaec72bc8ad360f6c9a209341e1c5cc88", @@ -298,6 +323,9 @@ function normalizeExtraPlugins(plugins: readonly WorkspaceRecipeExtraPlugin[] = if (plugin.composer !== undefined) { normalized.composer = plugin.composer } + if (plugin.metadata !== undefined) { + normalized.metadata = plugin.metadata + } return normalized }) diff --git a/tests/runtime-services.test.ts b/tests/runtime-services.test.ts index 57a75e60..54033ba3 100644 --- a/tests/runtime-services.test.ts +++ b/tests/runtime-services.test.ts @@ -103,6 +103,37 @@ try { } finally { await cleanupRecipePreparedSources([], preparedMdiPlugins) } +const candidateMdiSource = "/tmp/markdown-database-integration" +const candidateMdiRecipe = buildWordPressPhpunitRecipe({ + pluginSlug: "example", + databaseType: "mdi-native", + extra_plugins: [{ + source: candidateMdiSource, + slug: "markdown-database-integration", + sha256: "0123456789abcdef", + activate: true, + metadata: { revision: "548042c47efac724d13d25744765dbc65a851b20" }, + }], +}) +assert.deepEqual(candidateMdiRecipe.inputs?.extra_plugins, [{ + source: candidateMdiSource, + slug: "markdown-database-integration", + sha256: "0123456789abcdef", + pluginFile: "markdown-database-integration/markdown-database-integration.php", + activate: false, + metadata: { revision: "548042c47efac724d13d25744765dbc65a851b20", phase: "pre-install", databaseDropIn: true }, +}]) +assert.throws( + () => buildWordPressPhpunitRecipe({ + pluginSlug: "example", + databaseType: "mdi-native", + extra_plugins: [ + { source: "/tmp/one", slug: "markdown-database-integration" }, + { source: "/tmp/two", slug: "markdown-database-integration" }, + ], + }), + /at most one markdown-database-integration extra plugin source/, +) assert.equal(buildWordPressPhpunitRecipe({ pluginSlug: "example", wordpressInstallMode: "do-not-attempt-installing" }).runtime?.wordpressInstallMode, "do-not-attempt-installing") const builderDirectory = await mkdtemp(join(tmpdir(), "wp-codebox-phpunit-builder-")) try { From eaf8159453c74b830f3e0a2d6b87657d9f6dcbd0 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Thu, 10 Sep 2026 10:03:20 -0400 Subject: [PATCH 2/2] fix: constrain native MDI candidate mount --- packages/runtime-core/src/recipe-builders.ts | 3 +++ tests/runtime-services.test.ts | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/packages/runtime-core/src/recipe-builders.ts b/packages/runtime-core/src/recipe-builders.ts index e27d50a9..cbcdc33f 100644 --- a/packages/runtime-core/src/recipe-builders.ts +++ b/packages/runtime-core/src/recipe-builders.ts @@ -169,6 +169,9 @@ function nativeMdiPlugin(plugins: readonly WorkspaceRecipeExtraPlugin[]): Worksp } const candidate = candidates[0] if (candidate) { + if (candidate.loadAs !== undefined && candidate.loadAs !== "plugin") { + throw new Error("mdi-native markdown-database-integration source must use loadAs=plugin") + } return { ...candidate, slug: "markdown-database-integration", diff --git a/tests/runtime-services.test.ts b/tests/runtime-services.test.ts index 54033ba3..d2df538e 100644 --- a/tests/runtime-services.test.ts +++ b/tests/runtime-services.test.ts @@ -134,6 +134,14 @@ assert.throws( }), /at most one markdown-database-integration extra plugin source/, ) +assert.throws( + () => buildWordPressPhpunitRecipe({ + pluginSlug: "example", + databaseType: "mdi-native", + extra_plugins: [{ source: "/tmp/mdi", slug: "markdown-database-integration", loadAs: "mu-plugin" }], + }), + /must use loadAs=plugin/, +) assert.equal(buildWordPressPhpunitRecipe({ pluginSlug: "example", wordpressInstallMode: "do-not-attempt-installing" }).runtime?.wordpressInstallMode, "do-not-attempt-installing") const builderDirectory = await mkdtemp(join(tmpdir(), "wp-codebox-phpunit-builder-")) try {