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
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
"packages/runtime-playground/package.json",
"packages/cli/dist",
"packages/cli/package.json",
"scripts/normalize-playground-sqlite-package.mjs",
"README.md",
"LICENSE"
],
"scripts": {
"build": "node ./node_modules/typescript/bin/tsc -b packages/runtime-core packages/runtime-playground packages/cli",
"prepare": "npm run build",
"postinstall": "node scripts/normalize-playground-sqlite-package.mjs",
"package:wordpress-plugin": "tsx scripts/build-wordpress-plugin-zip.ts",
"package-distribution-smoke": "tsx scripts/package-distribution-smoke.ts",
"release:package": "tsx scripts/package-release-artifact.ts",
Expand Down Expand Up @@ -79,6 +81,7 @@
"recipe-workspace-seed-excludes-smoke": "tsx scripts/recipe-workspace-seed-excludes-smoke.ts",
"recipe-runtime-evidence-smoke": "tsx scripts/recipe-runtime-evidence-smoke.ts",
"playground-archive-cache-validation-smoke": "tsx scripts/playground-archive-cache-validation-smoke.ts",
"playground-sqlite-alias-smoke": "tsx scripts/playground-sqlite-alias-smoke.ts",
"recipe-playground-boot-failure-smoke": "tsx scripts/recipe-playground-boot-failure-smoke.ts",
"runtime-stack-mount-smoke": "tsx scripts/runtime-stack-mount-smoke.ts",
"runtime-overlay-php-ai-client-smoke": "tsx scripts/runtime-overlay-php-ai-client-smoke.ts",
Expand Down Expand Up @@ -108,6 +111,7 @@
"@chubes4/wp-codebox-core": "file:packages/runtime-core",
"@chubes4/wp-codebox-playground": "file:packages/runtime-playground",
"@wp-playground/cli": "^3.1.35",
"@wp-playground/wordpress-builds": "^0.9.4",
"abort-controller": "^3.0.0",
"accepts": "^1.3.8",
"aggregate-error": "^3.1.0",
Expand Down
1 change: 1 addition & 0 deletions packages/runtime-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"dependencies": {
"@chubes4/wp-codebox-core": "file:../runtime-core",
"@wp-playground/cli": "^3.1.35",
"@wp-playground/wordpress-builds": "^0.9.4",
"playwright": "^1.60.0"
}
}
68 changes: 68 additions & 0 deletions scripts/normalize-playground-sqlite-package.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { copyFile, mkdir, access } from "node:fs/promises"
import { createRequire } from "node:module"
import { dirname, join } from "node:path"
import { pathToFileURL } from "node:url"

const rootPackageUrl = pathToFileURL(join(process.cwd(), "package.json"))
const requireFromRoot = createRequire(rootPackageUrl)

const result = await normalizePlaygroundSqlitePackage(requireFromRoot)

if (process.env.WP_CODEBOX_PLAYGROUND_SQLITE_ALIAS_DEBUG === "1") {
console.log(JSON.stringify(result))
}

export async function normalizePlaygroundSqlitePackage(requireFrom = requireFromRoot) {
const wordpressBuildsRoot = await resolvePackageRoot(requireFrom, "@wp-playground/wordpress-builds")
if (!wordpressBuildsRoot) {
return { status: "skipped", reason: "@wp-playground/wordpress-builds is not installed" }
}

const sqliteDirectory = join(wordpressBuildsRoot, "src", "sqlite-database-integration")
const target = join(sqliteDirectory, "sqlite-database-integration-trunk.zip")
if (await exists(target)) {
return { status: "present", path: target }
}

const cliRoot = await resolvePackageRoot(requireFrom, "@wp-playground/cli")
const source = await firstExisting([
join(sqliteDirectory, "sqlite-database-integration.zip"),
cliRoot ? join(cliRoot, "sqlite-database-integration.zip") : undefined,
])

if (!source) {
return { status: "skipped", reason: "Playground SQLite package source was not found" }
}

await mkdir(sqliteDirectory, { recursive: true })
await copyFile(source, target)

return { status: "created", source, path: target }
}

async function resolvePackageRoot(requireFrom, packageName) {
try {
return dirname(requireFrom.resolve(`${packageName}/package.json`))
} catch {
return undefined
}
}

async function firstExisting(paths) {
for (const path of paths) {
if (path && await exists(path)) {
return path
}
}

return undefined
}

async function exists(path) {
try {
await access(path)
return true
} catch {
return false
}
}
22 changes: 21 additions & 1 deletion scripts/package-distribution-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,30 @@ const { stdout: packStdout } = await execFileAsync(
const [pack] = JSON.parse(packStdout) as Array<{ files: Array<{ path: string }>; entryCount: number }>
const packedFiles = new Set(pack.files.map((file) => file.path))

const { stdout: rootPackStdout } = await execFileAsync(
"npm",
["pack", "--dry-run", "--json"],
{ cwd: repoRoot, maxBuffer: 1024 * 1024 * 10 },
)
const [rootPack] = JSON.parse(rootPackStdout) as Array<{ files: Array<{ path: string }> }>
const rootPackedFiles = new Set(rootPack.files.map((file) => file.path))

assert.ok(packedFiles.has("package.json"), "CLI package should include package.json")
assert.ok(packedFiles.has("README.md"), "CLI package should include README.md")
assert.ok(packedFiles.has("dist/index.js"), "CLI package should include compiled binary entrypoint")
assert.ok(packedFiles.has("dist/index.d.ts"), "CLI package should include generated types")
assert.equal(packedFiles.has("src/index.ts"), false, "CLI package should not ship TypeScript source")
assert.ok(pack.entryCount >= 4, "CLI package should contain expected publish files")
assert.ok(
rootPackedFiles.has("scripts/normalize-playground-sqlite-package.mjs"),
"Root package should ship the Playground SQLite package normalizer for clean installs",
)

await execFileAsync("npm", ["run", "package:wordpress-plugin"], { cwd: repoRoot, maxBuffer: 1024 * 1024 * 10 })
const pluginZip = resolve(repoRoot, "packages", "wordpress-plugin", "dist", "wp-codebox.zip")
await access(pluginZip)

const { stdout: zipStdout } = await execFileAsync("unzip", ["-Z1", pluginZip], { cwd: repoRoot })
const { stdout: zipStdout } = await execFileAsync("unzip", ["-Z1", pluginZip], { cwd: repoRoot, maxBuffer: 1024 * 1024 * 20 })
const zipEntries = new Set(zipStdout.trim().split("\n").filter(Boolean))

assert.ok(zipEntries.has("wp-codebox/wp-codebox.php"), "Plugin zip should include the main plugin file")
Expand All @@ -55,6 +67,14 @@ assert.ok(
"Plugin zip should include packaged Node runtime for the plugin CLI path",
)
assert.ok(zipEntries.has("wp-codebox/vendor/wp-codebox-cli/packages/cli/dist/index.js"), "Plugin zip should include compiled CLI runtime")
assert.ok(
zipEntries.has("wp-codebox/vendor/wp-codebox-cli/node_modules/@wp-playground/wordpress-builds/src/sqlite-database-integration/sqlite-database-integration-trunk.zip"),
"Plugin zip should include Playground's normalized trunk SQLite package alias",
)
assert.ok(
zipEntries.has("wp-codebox/vendor/wp-codebox-cli/scripts/normalize-playground-sqlite-package.mjs"),
"Plugin zip should include the Playground SQLite package normalizer for packaged installs",
)
assert.equal(zipEntries.has("wp-codebox/package.json"), false, "Plugin zip should not include package metadata")
assert.equal(zipEntries.has("wp-codebox/dist/wp-codebox.zip"), false, "Plugin zip should not include generated artifacts")

Expand Down
6 changes: 6 additions & 0 deletions scripts/package-release-artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ try {

await copyIfPresent("README.md")
await copyIfPresent("LICENSE")
await mkdir(join(packageRoot, "scripts"), { recursive: true })
await cp(resolve(repoRoot, "scripts", "normalize-playground-sqlite-package.mjs"), join(packageRoot, "scripts", "normalize-playground-sqlite-package.mjs"))
await cp(resolve(repoRoot, "package.json"), join(packageRoot, "package.json"))
await cp(resolve(repoRoot, "package-lock.json"), join(packageRoot, "package-lock.json"))

Expand All @@ -38,6 +40,10 @@ try {
cwd: packageRoot,
maxBuffer: 1024 * 1024 * 20,
})
await execFileAsync("node", ["scripts/normalize-playground-sqlite-package.mjs"], {
cwd: packageRoot,
maxBuffer: 1024 * 1024 * 10,
})
await bundleNodeRuntime(packageRoot, platformName, archName)

const binDir = join(packageRoot, "bin")
Expand Down
29 changes: 29 additions & 0 deletions scripts/playground-sqlite-alias-smoke.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import assert from "node:assert/strict"
import { createRequire } from "node:module"
import { access, unlink } from "node:fs/promises"
import { dirname, join, resolve } from "node:path"
import { normalizePlaygroundSqlitePackage } from "./normalize-playground-sqlite-package.mjs"

const repoRoot = resolve(import.meta.dirname, "..")
const requireFromRepo = createRequire(join(repoRoot, "package.json"))
const wordpressBuildsRoot = dirname(requireFromRepo.resolve("@wp-playground/wordpress-builds/package.json"))
const sqliteDirectory = join(wordpressBuildsRoot, "src", "sqlite-database-integration")
const source = join(sqliteDirectory, "sqlite-database-integration.zip")
const target = join(sqliteDirectory, "sqlite-database-integration-trunk.zip")

await access(source)
await unlink(target).catch((error: NodeJS.ErrnoException) => {
if (error.code !== "ENOENT") {
throw error
}
})

const result = await normalizePlaygroundSqlitePackage(requireFromRepo)

assert.equal(result.status, "created", "Codebox should create Playground's trunk SQLite package alias")
await access(target)

const existing = await normalizePlaygroundSqlitePackage(requireFromRepo)
assert.equal(existing.status, "present", "Codebox should treat an existing Playground SQLite alias as reusable")

console.log("Playground SQLite alias smoke passed")