Skip to content

Commit d3581d1

Browse files
authored
Run browser distribution startup probes (#1238)
1 parent 524d376 commit d3581d1

5 files changed

Lines changed: 34 additions & 9 deletions

File tree

packages/cli/src/commands/recipe-run-types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ export interface RecipeRunDistributionStartupProbe {
256256
stdout?: string
257257
stderr?: string
258258
reason?: string
259+
missingCommand?: string
260+
url?: string
261+
expectStatus?: number
262+
availableCommands?: string[]
259263
metadata?: Record<string, unknown>
260264
}
261265

packages/cli/src/commands/recipe-run-workflow-evidence.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,18 @@ export async function runRecipeProbes(recipe: WorkspaceRecipe, recipeDirectory:
180180
export async function runDistributionStartupProbes(recipe: WorkspaceRecipe, runtime: Runtime, executions: RecipeExecutionResult[]): Promise<RecipeRunDistributionStartupProbe[]> {
181181
const results: RecipeRunDistributionStartupProbe[] = []
182182
for (const [index, probe] of (recipe.distribution?.startupProbes ?? []).entries()) {
183-
if (probe.type === "http" || probe.type === "browser") {
183+
if (probe.type === "http") {
184184
results.push(stripUndefined({
185185
schema: "wp-codebox/distribution-startup-probe-result/v1" as const,
186186
index,
187187
name: probe.name,
188188
type: probe.type,
189189
status: "skipped" as const,
190-
reason: "Distribution startup probe type is planned but not executable by this runtime primitive.",
190+
reason: "Distribution startup http probes require a generic HTTP runtime command, but this runtime only exposes REST and browser primitives.",
191+
missingCommand: "wordpress.http-request",
192+
url: probe.url,
193+
expectStatus: probe.expectStatus,
194+
availableCommands: ["wordpress.rest-request", "wordpress.browser-probe"],
191195
metadata: probe.metadata,
192196
}))
193197
continue
@@ -228,9 +232,7 @@ async function executeRecipeProbe(runtime: Runtime, probe: WorkspaceRecipeProbe,
228232
}
229233

230234
async function executeDistributionStartupProbe(runtime: Runtime, probe: WorkspaceRecipeDistributionStartupProbe, index: number): Promise<RecipeExecutionResult> {
231-
const spec = probe.type === "wp-cli"
232-
? { command: "wordpress.wp-cli", args: [`command=${probe.command ?? ""}`] }
233-
: { command: "wordpress.run-php", args: [`code=${probe.code ?? ""}`] }
235+
const spec = distributionStartupProbeExecutionSpec(probe)
234236
try {
235237
const execution = await runtime.execute(spec)
236238
return withRecipeExecutionPhase(execution, "setup", index, `distribution.startupProbe:${probe.name}`)
@@ -240,6 +242,16 @@ async function executeDistributionStartupProbe(runtime: Runtime, probe: Workspac
240242
}
241243
}
242244

245+
function distributionStartupProbeExecutionSpec(probe: WorkspaceRecipeDistributionStartupProbe): { command: string; args: string[] } {
246+
if (probe.type === "wp-cli") {
247+
return { command: "wordpress.wp-cli", args: [`command=${probe.command ?? ""}`] }
248+
}
249+
if (probe.type === "php") {
250+
return { command: "wordpress.run-php", args: [`code=${probe.code ?? ""}`] }
251+
}
252+
return { command: "wordpress.browser-probe", args: [`url=${probe.url ?? ""}`] }
253+
}
254+
243255
function parseProbeJson(stdout: string): unknown | undefined {
244256
const trimmed = stdout.trim()
245257
if (!trimmed) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ function phaseDistributionStartupProbeData(recipe: WorkspaceRecipe): Record<stri
839839
index,
840840
name: probe.name,
841841
type: probe.type,
842-
executable: probe.type === "wp-cli" || probe.type === "php",
842+
executable: probe.type === "wp-cli" || probe.type === "php" || probe.type === "browser",
843843
})),
844844
}
845845
}

packages/cli/src/recipe-validation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ export function recipePolicy(recipe: WorkspaceRecipe): RuntimePolicy {
765765
const distributionStartupProbeCommands = (recipe.distribution?.startupProbes ?? []).flatMap((probe) => {
766766
if (probe.type === "wp-cli") return ["wordpress.wp-cli"]
767767
if (probe.type === "php") return ["wordpress.run-php"]
768+
if (probe.type === "browser") return ["wordpress.browser-probe"]
768769
return []
769770
})
770771
const commands = [

tests/distribution-startup-probes.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const recipe: WorkspaceRecipe = {
1313
startupProbes: [
1414
{ name: "database", type: "wp-cli", command: "option get siteurl", metadata: { role: "readiness" } },
1515
{ name: "bootstrap", type: "php", code: "echo 'ready';" },
16-
{ name: "homepage", type: "http", url: "/" },
16+
{ name: "homepage", type: "browser", url: "/" },
17+
{ name: "api", type: "http", url: "/wp-json/", expectStatus: 200 },
1718
],
1819
},
1920
workflow: { steps: [{ command: "wordpress.run-php", args: ["code=echo 'workload';"] }] },
@@ -22,6 +23,7 @@ const recipe: WorkspaceRecipe = {
2223
const policy = recipePolicy(recipe)
2324
assert.ok(policy.commands.includes("wordpress.wp-cli"), "wp-cli startup probes are policy-visible")
2425
assert.ok(policy.commands.includes("wordpress.run-php"), "php startup probes are policy-visible")
26+
assert.ok(policy.commands.includes("wordpress.browser-probe"), "browser startup probes are policy-visible")
2527

2628
const executed: Array<{ command: string; args: string[] }> = []
2729
const runtime = {
@@ -46,14 +48,20 @@ const results = await runDistributionStartupProbes(recipe, runtime, executions)
4648
assert.deepEqual(executed, [
4749
{ command: "wordpress.wp-cli", args: ["command=option get siteurl"] },
4850
{ command: "wordpress.run-php", args: ["code=echo 'ready';"] },
51+
{ command: "wordpress.browser-probe", args: ["url=/"] },
4952
])
50-
assert.equal(executions.length, 2)
53+
assert.equal(executions.length, 3)
5154
assert.deepEqual(results.map((result) => [result.name, result.type, result.status]), [
5255
["database", "wp-cli", "passed"],
5356
["bootstrap", "php", "passed"],
54-
["homepage", "http", "skipped"],
57+
["homepage", "browser", "passed"],
58+
["api", "http", "skipped"],
5559
])
5660
assert.equal(results[0]?.metadata?.role, "readiness")
61+
assert.equal(results[3]?.missingCommand, "wordpress.http-request")
62+
assert.equal(results[3]?.url, "/wp-json/")
63+
assert.equal(results[3]?.expectStatus, 200)
64+
assert.deepEqual(results[3]?.availableCommands, ["wordpress.rest-request", "wordpress.browser-probe"])
5765
assert.equal(distributionStartupProbeFailure(results), undefined)
5866

5967
const summary = normalizeRecipeRunSummary({

0 commit comments

Comments
 (0)