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

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"packages/runtime-playground/package.json",
"packages/cli/dist",
"packages/cli/package.json",
"scripts/apply-development-patches.mjs",
"README.md",
"LICENSE"
],
Expand All @@ -88,7 +89,7 @@
"cloudflare:dry-run:d1": "npm exec -- wrangler deploy --dry-run --config packages/runtime-cloudflare/wrangler.d1.jsonc",
"cloudflare:local-gate": "node scripts/cloudflare-local-gate.mjs",
"cloudflare:local-gate:d1": "node scripts/cloudflare-local-gate.mjs --coordinator=d1",
"postinstall": "patch-package",
"postinstall": "node scripts/apply-development-patches.mjs",
"generate:cloudflare-wordpress-runtime-corpus": "tsx scripts/generate-cloudflare-wordpress-runtime-corpus.ts",
"provision:cloudflare-wordpress-runtime-corpus": "node scripts/provision-cloudflare-wordpress-runtime-corpus.mjs",
"prepare": "npm run build",
Expand Down
11 changes: 11 additions & 0 deletions scripts/apply-development-patches.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { execFileSync } from "node:child_process"
import { existsSync } from "node:fs"
import { resolve } from "node:path"

const patchPackageBin = resolve(import.meta.dirname, "..", "node_modules", "patch-package", "index.js")

if (existsSync(patchPackageBin)) {
execFileSync(process.execPath, [patchPackageBin], { stdio: "inherit" })
} else {
process.stdout.write("Skipping development patches in the production package.\n")
}
19 changes: 18 additions & 1 deletion scripts/package-release-artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ try {
cwd: packageRoot,
maxBuffer: 1024 * 1024 * 20,
})
await materializeWorkspacePackages(packageRoot)
await bundleNodeRuntime(packageRoot, platformName, archName)

const binDir = join(packageRoot, "bin")
Expand All @@ -51,7 +52,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
NODE_BIN="\${WP_CODEBOX_NODE_BIN:-}"
if [ -z "\${NODE_BIN}" ]; then
if [ -x "\${SCRIPT_DIR}/../vendor/node/bin/node" ]; then
if [ -x "\${SCRIPT_DIR}/../vendor/node/bin/node" ] && "\${SCRIPT_DIR}/../vendor/node/bin/node" --version >/dev/null 2>&1; then
NODE_BIN="\${SCRIPT_DIR}/../vendor/node/bin/node"
elif command -v node >/dev/null 2>&1; then
NODE_BIN="$(command -v node)"
Expand Down Expand Up @@ -101,6 +102,22 @@ async function copyIfPresent(relativePath: string): Promise<void> {
}
}

async function materializeWorkspacePackages(root: string): Promise<void> {
const automatticModules = join(root, "node_modules", "@automattic")
await mkdir(automatticModules, { recursive: true })

const packages = new Map([
["runtime-core", "wp-codebox-core"],
["runtime-playground", "wp-codebox-playground"],
["cli", "wp-codebox-cli"],
])
for (const [sourceName, packageName] of packages) {
const target = join(automatticModules, packageName)
await rm(target, recursiveRmOptions)
await cp(join(root, "packages", sourceName), target, { recursive: true, dereference: true })
}
}

async function bundleNodeRuntime(root: string, platformName: string, archName: string): Promise<void> {
const nodePackageName = nodeRuntimePackageName(platformName, archName)
const runtimeRoot = join(root, "vendor", "node")
Expand Down
83 changes: 81 additions & 2 deletions tests/release-package-coverage.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import assert from "node:assert/strict"
import { execFile } from "node:child_process"
import { readFile } from "node:fs/promises"
import { resolve } from "node:path"
import { cp, lstat, mkdir, mkdtemp, readFile, rm } from "node:fs/promises"
import { tmpdir } from "node:os"
import { join, resolve } from "node:path"
import { promisify } from "node:util"

const execFileAsync = promisify(execFile)
Expand All @@ -19,6 +20,11 @@ assert.deepEqual(homeboy.release?.package_coverage, [{

const { stdout } = await execFileAsync("npm", ["run", "release:package"], {
cwd: repositoryRoot,
env: {
...process.env,
WP_CODEBOX_RELEASE_PLATFORM: "linux",
WP_CODEBOX_RELEASE_ARCH: "x64",
},
maxBuffer: 1024 * 1024 * 20,
})
const artifacts = JSON.parse(stdout.trim().split("\n").at(-1) ?? "[]")
Expand Down Expand Up @@ -59,4 +65,77 @@ const { stdout: tarEntries } = await execFileAsync("tar", ["-tzf", cliArtifact.p
})
assert.ok(tarEntries.split("\n").some((path) => path === "wp-codebox-cli/"), "CLI tarball root changed")

const extractionRoot = await mkdtemp(join(tmpdir(), "wp-codebox-release-coverage-"))
try {
const pluginExtraction = join(extractionRoot, "plugin")
const cliExtraction = join(extractionRoot, "cli")
await mkdir(pluginExtraction, { recursive: true })
await mkdir(cliExtraction, { recursive: true })
await execFileAsync("unzip", ["-q", resolve(repositoryRoot, pluginArtifact), "-d", pluginExtraction])
await execFileAsync("tar", ["-xzf", resolve(repositoryRoot, cliArtifact.path), "-C", cliExtraction])

const pluginCliRoot = join(pluginExtraction, "wp-codebox", "vendor", "wp-codebox-cli")
const tarCliRoot = join(cliExtraction, "wp-codebox-cli")
for (const root of [pluginCliRoot, tarCliRoot]) {
for (const packageName of ["wp-codebox-cli", "wp-codebox-core", "wp-codebox-playground"]) {
const packagePath = join(root, "node_modules", "@automattic", packageName)
const packageStat = await lstat(packagePath)
assert.equal(packageStat.isDirectory(), true, `${packagePath} must be a materialized directory`)
assert.equal(packageStat.isSymbolicLink(), false, `${packagePath} must not depend on archive symlinks`)
await lstat(join(packagePath, "package.json"))
}

const cliEntrypoint = join(root, "packages", "cli", "dist", "index.js")
const { stdout: version } = await execFileAsync(process.execPath, [cliEntrypoint, "--version"])
assert.match(version, /^\d+\.\d+\.\d+\s*$/)
await execFileAsync(process.execPath, [cliEntrypoint, "commands"])

const wrapper = join(root, "bin", "wp-codebox")
const { stdout: wrapperVersion } = await execFileAsync(wrapper, ["--version"], {
env: { ...process.env, WP_CODEBOX_NODE_BIN: "" },
})
assert.equal(wrapperVersion, version, "wrapper must fall back to host Node when bundled Node is incompatible")
}
} finally {
await rm(extractionRoot, { recursive: true, force: true })
}

const rootPackage = JSON.parse(await readFile(resolve(repositoryRoot, "package.json"), "utf8"))
assert.equal(rootPackage.scripts.postinstall, "node scripts/apply-development-patches.mjs")
assert.ok(rootPackage.files.includes("scripts/apply-development-patches.mjs"))

const lifecycleRoot = await mkdtemp(join(tmpdir(), "wp-codebox-production-lifecycle-"))
try {
const lifecycleScript = resolve(repositoryRoot, "scripts", "apply-development-patches.mjs")
const packedLifecycleScript = join(lifecycleRoot, "scripts", "apply-development-patches.mjs")
await mkdir(join(lifecycleRoot, "scripts"), { recursive: true })
await cp(lifecycleScript, packedLifecycleScript)
const { stdout: lifecycleOutput } = await execFileAsync(process.execPath, [packedLifecycleScript], { cwd: lifecycleRoot })
assert.equal(lifecycleOutput, "Skipping development patches in the production package.\n")
} finally {
await rm(lifecycleRoot, { recursive: true, force: true })
}

const consumerRoot = await mkdtemp(join(tmpdir(), "wp-codebox-consumer-install-"))
try {
const packRoot = join(consumerRoot, "pack")
const installRoot = join(consumerRoot, "install")
await mkdir(packRoot, { recursive: true })
const { stdout: packOutput } = await execFileAsync("npm", ["pack", "--ignore-scripts", "--json", "--pack-destination", packRoot], {
cwd: repositoryRoot,
maxBuffer: 1024 * 1024 * 20,
})
const [packed] = JSON.parse(packOutput) as Array<{ filename: string }>
await execFileAsync("npm", ["install", "--global", "--prefix", installRoot, join(packRoot, packed.filename), "--omit=dev", "--no-audit", "--no-fund"], {
cwd: consumerRoot,
maxBuffer: 1024 * 1024 * 20,
})
const installedCli = join(installRoot, "bin", "wp-codebox")
const { stdout: installedVersion } = await execFileAsync(installedCli, ["--version"])
assert.match(installedVersion, /^\d+\.\d+\.\d+\s*$/)
await execFileAsync(installedCli, ["commands"])
} finally {
await rm(consumerRoot, { recursive: true, force: true })
}

console.log("release package coverage passed")
Loading