Skip to content

Commit 350dfca

Browse files
authored
Consolidate WordPress runtime inputs (#1865)
1 parent 36930da commit 350dfca

13 files changed

Lines changed: 61 additions & 35 deletions

packages/cli/src/commands/wordpress-runtime.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ function runtimeBackedFuzzSuitePolicy(suite: FuzzSuiteContract): RuntimePolicy {
183183

184184
function fuzzSuiteRequiresRecipeRuntime(input: Record<string, unknown>): boolean {
185185
const requirements = fuzzSuiteRuntimeRequirements(input)
186-
return arrayOption(requirements?.extra_plugins).length > 0 || arrayOption(requirements?.component_contracts).length > 0
186+
return arrayOption(requirements?.extra_plugins).length > 0 || arrayOption(requirements?.component_contracts).length > 0 || Boolean(runtimeRequirementWordPressDirectory(requirements))
187187
}
188188

189189
function runtimeBackedFuzzSuiteCommands(suite: FuzzSuiteContract): string[] {
@@ -310,6 +310,9 @@ function applyFuzzSuiteRuntimeRequirements(recipe: WorkspaceRecipe, requirements
310310
}
311311
recipe.runtime = {
312312
...runtime,
313+
assets: runtimeRequirementWordPressDirectory(requirements)
314+
? { ...(runtime.assets ?? {}), wordpressDirectory: runtimeRequirementWordPressDirectory(requirements) }
315+
: runtime.assets,
313316
stack: arrayOption(requirements.runtime_mounts).length > 0 ? { ...(runtime.stack ?? {}), mounts: arrayOption(requirements.runtime_mounts) as WorkspaceRecipeMount[] } : runtime.stack,
314317
}
315318
recipe.metadata = {
@@ -318,6 +321,10 @@ function applyFuzzSuiteRuntimeRequirements(recipe: WorkspaceRecipe, requirements
318321
}
319322
}
320323

324+
function runtimeRequirementWordPressDirectory(requirements: Record<string, unknown> | undefined): string | undefined {
325+
return requirements ? stringValue(requirements.wordpress_directory) : undefined
326+
}
327+
321328
function fuzzSuiteRuntimeRequirements(suiteInput: Record<string, unknown>): Record<string, unknown> | undefined {
322329
return objectOption(objectOption(suiteInput.metadata)?.runtime_requirements)
323330
}
@@ -428,6 +435,7 @@ function workloadRecipeOptions(input: Record<string, unknown>, runtimeRequiremen
428435
const steps = workloadRecipeSteps(input, runtimeRequirements)
429436
return {
430437
wordpressVersion: stringValue(input.wordpressVersion ?? input.wordpress_version ?? input.wp),
438+
wordpressDirectory: stringValue(input.wordpress_directory),
431439
blueprint: input.blueprint,
432440
preview: objectOption(input.preview) as WordPressWorkloadRunRecipeOptions["preview"],
433441
mounts: arrayOption(input.mounts) as WordPressWorkloadRunRecipeOptions["mounts"],

packages/cli/src/recipe-dry-run.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { basename, dirname, resolve } from "node:path"
2-
import { fixtureImportDeterministicIdPlan, normalizeRuntimeBackendKind, validateRuntimePolicy, type FixtureImportDeterministicIdPlan, type MountSpec, type RuntimePolicy, type RuntimeWordPressInstallMode, type SandboxWorkspaceMode, type WorkspaceRecipe, type WorkspaceRecipeDeclaredArtifact, type WorkspaceRecipeDistribution, type WorkspaceRecipeDistributionStartupProbe, type WorkspaceRecipeFixtureDatabase, type WorkspaceRecipePluginRuntime, type WorkspaceRecipePluginRuntimeHealthProbe, type WorkspaceRecipeSiteSeed, type WorkspaceRecipeSiteSeedBootstrap, type WorkspaceRecipeWorkspace } from "@automattic/wp-codebox-core"
2+
import { fixtureImportDeterministicIdPlan, normalizeRuntimeBackendKind, validateRuntimePolicy, type FixtureImportDeterministicIdPlan, type MountSpec, type RuntimeAssetSpec, type RuntimePolicy, type RuntimeWordPressInstallMode, type SandboxWorkspaceMode, type WorkspaceRecipe, type WorkspaceRecipeDeclaredArtifact, type WorkspaceRecipeDistribution, type WorkspaceRecipeDistributionStartupProbe, type WorkspaceRecipeFixtureDatabase, type WorkspaceRecipePluginRuntime, type WorkspaceRecipePluginRuntimeHealthProbe, type WorkspaceRecipeSiteSeed, type WorkspaceRecipeSiteSeedBootstrap, type WorkspaceRecipeWorkspace } from "@automattic/wp-codebox-core"
33
import { SANDBOX_WORKSPACE_ROOT, stripUndefined } from "@automattic/wp-codebox-core/internals"
44
import { serializeError } from "./output.js"
55
import { RecipeArtifactsMountConflictError, recipeArtifactsMountConflict } from "./commands/recipe-run-artifacts-mount-guard.js"
@@ -55,6 +55,7 @@ export interface RecipePlan {
5555
wp: string
5656
phpVersion?: string
5757
wordpressInstallMode?: RuntimeWordPressInstallMode
58+
assets?: RuntimeAssetSpec
5859
blueprint: unknown
5960
extensions?: Array<{ manifest: string }>
6061
}
@@ -441,6 +442,7 @@ export async function planWorkspaceRecipe(recipe: WorkspaceRecipe, recipeDirecto
441442
wp: recipe.runtime?.wp ?? context.defaultWordPressVersion,
442443
...(recipe.runtime?.phpVersion ? { phpVersion: recipe.runtime.phpVersion } : {}),
443444
...(recipe.runtime?.wordpressInstallMode ? { wordpressInstallMode: recipe.runtime.wordpressInstallMode } : {}),
445+
...(recipe.runtime?.assets ? { assets: recipe.runtime.assets } : {}),
444446
...(recipe.runtime?.extensions ? { extensions: recipe.runtime.extensions } : {}),
445447
blueprint: recipeBlueprintWithBootActivePlugins(recipe.runtime?.blueprint, extraPlugins),
446448
},

packages/cli/src/recipe-validation.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ function validateRecipeRuntimeAssets(assets: RuntimeAssetSpec | undefined, recip
337337
if (assets.wordpressZip !== undefined && typeof assets.wordpressZip !== "string") {
338338
throw new Error(`Recipe runtime assets wordpressZip must be a string: ${recipePath}`)
339339
}
340+
341+
if (assets.wordpressDirectory !== undefined && typeof assets.wordpressDirectory !== "string") {
342+
throw new Error(`Recipe runtime assets wordpressDirectory must be a string: ${recipePath}`)
343+
}
340344
}
341345

342346
function validateRecipeRuntimeExtensions(extensions: NonNullable<WorkspaceRecipe["runtime"]>["extensions"] | undefined, recipePath: string): void {

packages/runtime-core/src/agent-task-recipe.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export interface AgentTaskRunInput {
3939
workspaces?: NonNullable<WorkspaceRecipe["inputs"]>["workspaces"]
4040
dependency_overlays?: NonNullable<WorkspaceRecipe["inputs"]>["dependency_overlays"]
4141
extra_plugins?: WorkspaceRecipeExtraPlugin[]
42-
extraPlugins?: WorkspaceRecipeExtraPlugin[]
4342
runtime_stack_mounts?: WorkspaceRecipeMount[]
4443
runtime_overlays?: Array<Record<string, unknown>>
4544
agent_bundles?: Array<Record<string, unknown>>
@@ -677,9 +676,7 @@ function agentTaskExtraPlugins(input: AgentTaskRunInput): WorkspaceRecipeExtraPl
677676
...normalizeAgentTaskExtraPlugins(runtimeProfileRecord(input).plugins),
678677
...normalizeAgentTaskExtraPlugins(runtimeProfileRecord(input).mu_plugins),
679678
...normalizeAgentTaskExtraPlugins(input.extra_plugins),
680-
...normalizeAgentTaskExtraPlugins(input.extraPlugins),
681679
...normalizeAgentTaskExtraPlugins(runtimeRequirements?.extra_plugins),
682-
...normalizeAgentTaskExtraPlugins(runtimeRequirements?.extraPlugins),
683680
]
684681
}
685682

packages/runtime-core/src/command-registry.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -627,20 +627,6 @@ export const commandRegistry = [
627627
recipe: true,
628628
handler: { kind: "playground", method: "runRestRouteInventory" },
629629
},
630-
{
631-
id: "wordpress.inventory-rest-routes",
632-
description: "Inventory registered WordPress REST routes for fuzzing seed discovery using rest_get_server()->get_routes().",
633-
acceptedArgs: [],
634-
outputShape: "wp-codebox/wordpress-rest-route-inventory/v1 JSON with route, namespace, methods, bounded endpoint permission descriptors, bounded arg/schema descriptors, status, and diagnostics.",
635-
outputSchema: objectEnvelopeSchema(WORDPRESS_REST_ROUTE_INVENTORY_SCHEMA, {
636-
routes: { type: "array" },
637-
namespaces: { type: "array" },
638-
diagnostics: { type: "array" },
639-
}),
640-
policyRequirement: "Runtime policy commands must include wordpress.inventory-rest-routes.",
641-
recipe: true,
642-
handler: { kind: "playground", method: "runRestRouteInventory" },
643-
},
644630
{
645631
id: "wordpress.admin-page-inventory",
646632
description: "Inventory already-loaded WordPress admin menu pages for fuzzing target discovery without crawling the browser UI.",

packages/runtime-core/src/wordpress-runtime-discovery-contracts.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export const WORDPRESS_EXECUTION_ACTION_RESULT_SCHEMA = "wp-codebox/wordpress-ex
99

1010
export type WordPressRuntimeInventoryCommand =
1111
| "wordpress.rest-route-inventory"
12-
| "wordpress.inventory-rest-routes"
1312
| "wordpress.admin-page-inventory"
1413
| "wordpress.admin-action-inventory"
1514
| "wordpress.inventory-database"
@@ -48,7 +47,7 @@ export interface WordPressRestRouteDiscovery {
4847

4948
export interface WordPressRestRouteInventory {
5049
schema: typeof WORDPRESS_REST_ROUTE_INVENTORY_SCHEMA
51-
command: "wordpress.rest-route-inventory" | "wordpress.inventory-rest-routes"
50+
command: "wordpress.rest-route-inventory"
5251
status: "ok" | "unsupported"
5352
routes: WordPressRestRouteDescriptor[]
5453
namespaces: string[]

packages/runtime-core/src/wordpress-workload-primitives.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export interface WordPressAbilityStepOptions {
2020

2121
export interface WordPressWorkloadRunRecipeOptions {
2222
wordpressVersion?: string
23+
/** Local WordPress core source mounted at /wordpress before Playground starts. */
24+
wordpressDirectory?: string
2325
blueprint?: unknown
2426
preview?: RuntimePreviewSpec
2527
mounts?: WorkspaceRecipeMount[]
@@ -80,6 +82,7 @@ export function wordpressWorkloadRunRecipe(options: WordPressWorkloadRunRecipeOp
8082
runtime: stripUndefined({
8183
backend: "wordpress-playground",
8284
wp: options.wordpressVersion ?? DEFAULT_WORDPRESS_VERSION,
85+
assets: options.wordpressDirectory ? { wordpressDirectory: options.wordpressDirectory } : undefined,
8386
blueprint: options.blueprint ?? { steps: [] },
8487
preview: options.preview,
8588
stack: Array.isArray(options.runtimeStackMounts) && options.runtimeStackMounts.length > 0 ? { mounts: options.runtimeStackMounts } : undefined,

packages/wordpress-plugin/src/class-wp-codebox-fuzz-suite-runner.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ private static function execute_fuzz_suite_step( array $step, array $case, array
442442
return match ( $command ) {
443443
'wordpress.ensure-plugin-active' => self::execute_fuzz_suite_plugin_activation( $args, $observation, $case_id ),
444444
'wordpress.ensure-external-http-guardrail' => self::execute_fuzz_suite_external_http_guardrail( $args, $observation ),
445-
'wordpress.inventory-rest-routes', 'wordpress.rest-route-inventory' => self::execute_fuzz_suite_rest_route_inventory( $args, $observation, $case_id ),
445+
'wordpress.rest-route-inventory' => self::execute_fuzz_suite_rest_route_inventory( $args, $observation, $case_id ),
446446
'wordpress.inventory-database' => self::execute_fuzz_suite_database_inventory( $args, $observation, $case_id ),
447447
'wordpress.admin-page-inventory' => self::execute_fuzz_suite_admin_page_inventory( $args, $observation ),
448448
'wordpress.fuzz-admin-pages' => self::execute_fuzz_suite_admin_page_fuzz( $args, $observation ),
@@ -517,7 +517,7 @@ private static function execute_fuzz_suite_rest_route_inventory( array $args, ar
517517
$observation['namespaces'] = array_values( array_unique( $namespaces ) );
518518
$observation['payload'] = array(
519519
'schema' => 'wp-codebox/wordpress-rest-route-inventory/v1',
520-
'command' => 'wordpress.inventory-rest-routes',
520+
'command' => 'wordpress.rest-route-inventory',
521521
'routes' => $items,
522522
'namespaces' => $observation['namespaces'],
523523
);

scripts/php-fuzz-suite-runner-smoke.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ class WP_Codebox_Fuzz_Suite_Runner_Smoke {
397397
'id' => 'rest-route-inventory',
398398
'phases' => array(
399399
'action' => array(
400-
array( 'command' => 'wordpress.inventory-rest-routes', 'args' => array( 'namespaces=sample/v1', 'artifact=route_inventory' ) ),
400+
array( 'command' => 'wordpress.rest-route-inventory', 'args' => array( 'namespaces=sample/v1', 'artifact=route_inventory' ) ),
401401
),
402402
),
403403
),

tests/agent-task-contracts.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,7 @@ try {
630630
activate: false,
631631
pluginFile: "agent-runtime-tool-bridge/agent-runtime-tool-bridge.php",
632632
metadata: { source: "agent-task-input" },
633-
}],
634-
extraPlugins: [{
633+
}, {
635634
source: providerSource,
636635
slug: "test-provider",
637636
loadAs: "plugin",

0 commit comments

Comments
 (0)