Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/cli/src/commands/recipe-build.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFile, writeFile } from "node:fs/promises"
import { buildGenericAbilityRuntimeRunRecipe, buildRuntimePackageRunRecipe, buildWordPressBenchRecipe, buildWordPressPhpunitRecipe, compileRecipeTemplate, type GenericAbilityRuntimeRunOptions, type RecipeTemplateInput, type RuntimePackageRunRecipeOptions, type WorkspaceRecipe, type WorkspaceRecipeExtraPlugin, type WorkspaceRecipeMount, type WorkspaceRecipeRuntimeService, type WorkspaceRecipeStep } from "@automattic/wp-codebox-core"
import { buildGenericAbilityRuntimeRunRecipe, buildRuntimePackageRunRecipe, buildWordPressBenchRecipe, buildWordPressPhpunitRecipe, compileRecipeTemplate, type GenericAbilityRuntimeRunOptions, type RecipeTemplateInput, type RuntimePackageRunRecipeOptions, type WorkspaceRecipe, type WorkspaceRecipeExtraPlugin, type WorkspaceRecipeMount, type WorkspaceRecipePHPWasmExtensionManifest, type WorkspaceRecipeRuntimeBackendPackage, type WorkspaceRecipeRuntimeService, type WorkspaceRecipeStep } from "@automattic/wp-codebox-core"

interface RecipeBuildOptions {
recipeType: "phpunit" | "bench" | "template" | "generic-ability-runtime-run" | "runtime-package-run"
Expand All @@ -10,6 +10,9 @@ interface RecipeBuildOptions {
interface WordPressPhpunitBuilderOptions {
blueprint?: unknown
wordpressVersion?: string
phpVersion?: string
extensions?: WorkspaceRecipePHPWasmExtensionManifest[]
backendPackage?: WorkspaceRecipeRuntimeBackendPackage
mounts?: WorkspaceRecipeMount[]
services?: WorkspaceRecipeRuntimeService[]
extra_plugins?: WorkspaceRecipeExtraPlugin[]
Expand Down Expand Up @@ -76,6 +79,9 @@ function buildRecipe(recipeType: RecipeBuildOptions["recipeType"], options: Word
return buildWordPressPhpunitRecipe({
blueprint: phpunitOptions.blueprint,
wordpressVersion: stringOrUndefined(phpunitOptions.wordpressVersion),
phpVersion: stringOrUndefined(phpunitOptions.phpVersion),
extensions: Array.isArray(phpunitOptions.extensions) ? phpunitOptions.extensions : [],
backendPackage: phpunitOptions.backendPackage,
mounts: Array.isArray(phpunitOptions.mounts) ? phpunitOptions.mounts : [],
services: Array.isArray(phpunitOptions.services) ? phpunitOptions.services : [],
extra_plugins: Array.isArray(phpunitOptions.extra_plugins) ? phpunitOptions.extra_plugins : [],
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-core/src/recipe-builders.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { WorkspaceRecipe, WorkspaceRecipeExtraPlugin, WorkspaceRecipeMount, WorkspaceRecipeRuntimeService, WorkspaceRecipeStep } from "./runtime-contracts.js"
import type { WorkspaceRecipe, WorkspaceRecipeExtraPlugin, WorkspaceRecipeMount, WorkspaceRecipePHPWasmExtensionManifest, WorkspaceRecipeRuntimeBackendPackage, WorkspaceRecipeRuntimeService, WorkspaceRecipeStep } from "./runtime-contracts.js"
import { commandArg, commandJsonArg, commandStringListArg } from "./command-codecs.js"
export { buildRuntimePackageRunRecipe, CODEBOX_RUN_RUNTIME_PACKAGE_ABILITY, RUNTIME_PACKAGE_ARTIFACT_DECLARATION_SCHEMA, RUNTIME_PACKAGE_EXECUTION_INPUT_SCHEMA, RUNTIME_PACKAGE_EXECUTION_RESULT_SCHEMA, RUNTIME_PACKAGE_OUTPUT_PROJECTION_SCHEMA, runtimePackageExecutionInput, type RuntimePackageArtifactDeclaration, type RuntimePackageExecutionInput, type RuntimePackageOutputProjection, type RuntimePackageRunRecipeOptions } from "./runtime-package-execution.js"
export { RUNTIME_PACKAGE_DIAGNOSTIC_SCHEMA, RUNTIME_PACKAGE_RESULT_SCHEMA, RUNTIME_PACKAGE_TASK_SCHEMA, normalizeRuntimePackageResult, normalizeRuntimePackageTask, validateRuntimePackageTask, type RuntimePackageDiagnostic, type RuntimePackageResult, type RuntimePackageTask } from "./runtime-package-contracts.js"
Expand All @@ -13,7 +13,10 @@ export interface NormalizeRecipeMountsOptions {

export interface WordPressPhpunitRecipeOptions {
wordpressVersion?: string
phpVersion?: string
blueprint?: unknown
extensions?: WorkspaceRecipePHPWasmExtensionManifest[]
backendPackage?: WorkspaceRecipeRuntimeBackendPackage
mounts?: WorkspaceRecipeMount[]
services?: WorkspaceRecipeRuntimeService[]
extra_plugins?: WorkspaceRecipeExtraPlugin[]
Expand Down Expand Up @@ -73,7 +76,10 @@ export function buildWordPressPhpunitRecipe(options: WordPressPhpunitRecipeOptio
schema: "wp-codebox/workspace-recipe/v1",
runtime: {
wp: options.wordpressVersion ?? DEFAULT_WORDPRESS_VERSION,
...(options.phpVersion ? { phpVersion: options.phpVersion } : {}),
blueprint: options.blueprint ?? { steps: [] },
...(options.extensions?.length ? { extensions: options.extensions } : {}),
...(options.backendPackage ? { backendPackage: options.backendPackage } : {}),
},
inputs: {
extra_plugins: normalizeExtraPlugins(options.extra_plugins),
Expand Down
24 changes: 16 additions & 8 deletions packages/runtime-playground/src/phpunit-command-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,18 @@ $bootstrap_mode = ${JSON.stringify(options.bootstrapMode || "managed")};
$project_bootstrap = ${JSON.stringify(options.projectBootstrap)};
$multisite = ${JSON.stringify(options.multisite)};

function pg_build_phpunit_argv($raw): array {
$phpunit_argv = array('phpunit');
if (is_array($raw)) {
foreach ($raw as $arg) {
if (is_scalar($arg)) {
$phpunit_argv[] = (string) $arg;
}
}
}
return $phpunit_argv;
}

@file_put_contents($result_file, '');

function pg_log($msg) {
Expand Down Expand Up @@ -1045,6 +1057,10 @@ try {
}

pg_apply_env($bench_env);
$phpunit_argv = pg_build_phpunit_argv($phpunit_args_raw);
$argv = $phpunit_argv;
$_SERVER['argv'] = $phpunit_argv;
$_SERVER['argc'] = count($phpunit_argv);

if (!is_array($wp_config_defines)) {
$wp_config_defines = array();
Expand Down Expand Up @@ -1291,14 +1307,6 @@ function wp_codebox_phpunit_print_test_list($test) {
pg_stage_begin('run_tests');
pg_log('RUNNING ' . count($test_files) . ' TEST FILES');
try {
$phpunit_argv = array('phpunit');
if (is_array($phpunit_args_raw)) {
foreach ($phpunit_args_raw as $arg) {
if (is_scalar($arg)) {
$phpunit_argv[] = (string) $arg;
}
}
}
$phpunit_args = wp_codebox_phpunit_args($phpunit_argv);
if (!empty($phpunit_args['listTests'])) {
wp_codebox_phpunit_print_test_list($suite);
Expand Down
2 changes: 2 additions & 0 deletions packages/runtime-playground/src/playground-cli-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface PlaygroundCliModule {
wordpressInstallMode?: "install-from-existing-files" | "install-from-existing-files-if-needed" | "do-not-attempt-installing"
"site-url"?: string
phpIniEntries?: Record<string, string>
phpExtension?: string[]
}): Promise<PlaygroundCliServer>
}

Expand Down Expand Up @@ -137,6 +138,7 @@ export async function startPlaygroundCliServer(spec: RuntimeCreateSpec, mounts:
} : {}),
wp: localAssetServer?.url ?? wordpressStartupAsset?.wp,
php: spec.environment.phpVersion,
...(spec.environment.extensions?.length ? { phpExtension: spec.environment.extensions.map((extension) => extension.manifest) } : {}),
phpIniEntries: pluginRuntimePhpIniEntries(spec),
"site-url": spec.preview?.siteUrl,
blueprint: playgroundCliBlueprint(spec),
Expand Down
4 changes: 4 additions & 0 deletions packages/runtime-playground/src/wordpress-command-runners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,10 @@ export async function runPhpunitCommand({
await persistPluginPhpunitResult(server, resultFile, artifactRoot)
await persistVfsDiagnosticFileToHost(server, resultFile, `/wordpress/wp-content/plugins/${pluginSlug}/.pg-test-result.txt`, mounts)
assertPlaygroundResponseOk("wordpress.phpunit", response)
const structured = await readPluginPhpunitDiagnostic(server, resultFile)
if (structured) {
throw new Error(`wordpress.phpunit could not run: ${structured}`)
}

return response.text
}
Expand Down
2 changes: 2 additions & 0 deletions tests/phpunit-project-autoload.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@ const projectModeCode = phpunitRunCode({
const bootIndex = projectModeCode.indexOf("$config_path = pg_run_boot_stage")
const projectBootstrapIndex = projectModeCode.indexOf("pg_run_project_bootstrap_stage", bootIndex)
const projectAutoloadIndex = projectModeCode.indexOf("pg_run_project_autoload_stage", projectBootstrapIndex)
const phpunitArgvIndex = projectModeCode.indexOf("$_SERVER['argv'] = $phpunit_argv;")
assert.ok(bootIndex > 0)
assert.ok(phpunitArgvIndex > 0 && phpunitArgvIndex < projectBootstrapIndex, "project bootstrap must receive forwarded PHPUnit arguments")
assert.ok(projectBootstrapIndex > bootIndex)
assert.ok(projectAutoloadIndex > projectBootstrapIndex)
assert.ok(projectModeCode.includes("'autoload_required' => $bootstrap_mode !== 'project' || $harness_autoload_file !== ''"))
Expand Down
2 changes: 2 additions & 0 deletions tests/playground-cli-runner-bootstrap-ini.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ try {
phpVersion: "8.4",
wordpressInstallMode: "do-not-attempt-installing",
assets: { wordpressDirectory },
extensions: [{ manifest: "/tmp/sodium/manifest.json" }],
blueprint: {},
},
policy: {
Expand Down Expand Up @@ -68,6 +69,7 @@ try {
assert.equal(calls[0].workers, 6)
assert.equal(calls[0].wordpressInstallMode, "do-not-attempt-installing")
assert.deepEqual(calls[0].phpIniEntries, { memory_limit: "512M" })
assert.deepEqual(calls[0].phpExtension, ["/tmp/sodium/manifest.json"])
const sharedMount = calls[0]["mount-before-install"]?.[0]?.hostPath
assert.equal(typeof sharedMount, "string")
const sharedPhpIni = await readFile(join(sharedMount as string, "php.ini"), "utf8")
Expand Down
6 changes: 6 additions & 0 deletions tests/runtime-services.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ try {
const recipePath = join(builderDirectory, "recipe.json")
await writeFile(optionsPath, JSON.stringify({
pluginSlug: "example",
phpVersion: "8.3",
extensions: [{ manifest: "./sodium/manifest.json" }],
backendPackage: { kind: "playground", source: "./playground-cli", package: "@wp-playground/cli" },
testRoot: "/home/example/bin/tests/core",
phpunitXml: "/home/example/bin/tests/core/phpunit.xml",
}))
assert.equal(await runRecipeBuildCommand(["phpunit", "--options", optionsPath, "--output", recipePath]), 0)
const builtRecipe = JSON.parse(await readFile(recipePath, "utf8")) as WorkspaceRecipe
assert.ok(builtRecipe.workflow.steps[0].args?.includes("test-root=/home/example/bin/tests/core"))
assert.ok(builtRecipe.workflow.steps[0].args?.includes("phpunit-xml=/home/example/bin/tests/core/phpunit.xml"))
assert.equal(builtRecipe.runtime?.phpVersion, "8.3")
assert.deepEqual(builtRecipe.runtime?.extensions, [{ manifest: "./sodium/manifest.json" }])
assert.deepEqual(builtRecipe.runtime?.backendPackage, { kind: "playground", source: "./playground-cli", package: "@wp-playground/cli" })

await writeFile(optionsPath, JSON.stringify({ pluginSlug: "example" }))
assert.equal(await runRecipeBuildCommand(["phpunit", "--options", optionsPath, "--output", recipePath]), 0)
Expand Down
Loading