Skip to content

Commit

Permalink
WordPress Build: Use Playground CLI to produce minified WordPress bui…
Browse files Browse the repository at this point in the history
…ld (without the SQLite integration plugin) (#1426)

Uses Playground CLI to produce the minified WordPress builds:

```bash
$ bun \
    packages/playground/cli/src/cli.ts run-blueprint \
    --wp=https://wordpress.org/6.5.zip \
    --mount-before-install=./wordpress-site:/wordpress
```

Those new builds ships **without** the SQLite database integration
plugin but **with** the SQLite database file containing all the data and
tables created by a vanilla WordPress installation.

Advantages:

* Less code to maintain – Playground CLI replaces a custom bash script
relying on wget, unzip, sed, wp-cli etc.
* More testing for our internal tools – we're dogfooding Playground CLI
and the boot protocol in the critical code path.

## Testing instructions

* Confirm the CI checks passed – this is about as good of a testing as
we can get.
* Run `npm run dev` and confirm the local Playground loads without any
issues.

Run `bun packages/playground/cli/src/cli.ts server --login` and confirm
it loads an installed WordPress.

Related: #1398
  • Loading branch information
adamziel authored May 28, 2024
1 parent eef41af commit daf9c52
Show file tree
Hide file tree
Showing 30 changed files with 264 additions and 237 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/refresh-wordpress-major-and-beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}
clean: true
persist-credentials: false
- name: 'Install bun'
run: |
curl -fsSL https://bun.sh/install | bash
- uses: ./.github/actions/prepare-playground
- name: 'Recompile WordPress'
shell: bash
env:
FORCE_REBUILD: ${{ github.event.inputs.force_rebuild }}
run: npx nx bundle-wordpress:major-and-beta playground-wordpress-builds
run: PATH="${PATH}:${HOME}/.bun/bin" npx nx bundle-wordpress:major-and-beta playground-wordpress-builds
- name: Check for uncommitted changes
id: changes
run: |
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/refresh-wordpress-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ jobs:
clean: true
persist-credentials: false
- uses: ./.github/actions/prepare-playground
- name: 'Install bun'
run: |
curl -fsSL https://bun.sh/install | bash
- name: 'Recompile WordPress'
shell: bash
run: npx nx bundle-wordpress:nightly playground-wordpress-builds
run: PATH="${PATH}:${HOME}/.bun/bin" npx nx bundle-wordpress:nightly playground-wordpress-builds
- name: Config git user
run: |
git config --global user.name "deployment_bot"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import { PHP } from '@php-wasm/universal';
import { RecommendedPHPVersion } from '@wp-playground/common';
import { getWordPressModule } from '@wp-playground/wordpress-builds';
import { unzip } from './unzip';
import {
getSqliteDatabaseModule,
getWordPressModule,
} from '@wp-playground/wordpress-builds';
import { activatePlugin } from './activate-plugin';
import { phpVar } from '@php-wasm/util';
import { PHPRequestHandler } from '@php-wasm/universal';
import { loadNodeRuntime } from '@php-wasm/node';
import { bootWordPress } from '@wp-playground/wordpress';

describe('Blueprint step activatePlugin()', () => {
let php: PHP;
let handler: PHPRequestHandler;
beforeEach(async () => {
handler = new PHPRequestHandler({
phpFactory: async () =>
new PHP(await loadNodeRuntime(RecommendedPHPVersion)),
documentRoot: '/wordpress',
handler = await bootWordPress({
createPhpRuntime: async () =>
await loadNodeRuntime(RecommendedPHPVersion),
siteUrl: 'http://playground-domain/',

wordPressZip: await getWordPressModule(),
sqliteIntegrationPluginZip: await getSqliteDatabaseModule(),
});
php = await handler.getPrimaryPhp();
await unzip(php, {
zipFile: await getWordPressModule(),
extractToPath: '/wordpress',
});
});

it('should activate the plugin', async () => {
const docroot = php.documentRoot;
php.writeFile(
`/${docroot}/wp-content/plugins/test-plugin.php`,
`${docroot}/wp-content/plugins/test-plugin.php`,
`<?php /**\n * Plugin Name: Test Plugin */`
);
await activatePlugin(php, {
Expand All @@ -46,11 +48,12 @@ describe('Blueprint step activatePlugin()', () => {
it('should detect a silent failure in activating the plugin', async () => {
const docroot = php.documentRoot;
php.writeFile(
`/${docroot}/wp-content/plugins/test-plugin.php`,
`${docroot}/wp-content/plugins/test-plugin.php`,
`<?php /**\n * Plugin Name: Test Plugin */`
);
php.mkdir(`${docroot}/wp-content/mu-plugins`);
php.writeFile(
`/${docroot}/wp-content/mu-plugins/0-exit.php`,
`${docroot}/wp-content/mu-plugins/0-exit.php`,
`<?php exit(0); `
);
expect(
Expand Down
30 changes: 17 additions & 13 deletions packages/playground/blueprints/src/lib/steps/activate-theme.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { loadNodeRuntime } from '@php-wasm/node';
import { PHP } from '@php-wasm/universal';
import { RecommendedPHPVersion } from '@wp-playground/common';
import { getWordPressModule } from '@wp-playground/wordpress-builds';
import { unzip } from './unzip';
import {
getSqliteDatabaseModule,
getWordPressModule,
} from '@wp-playground/wordpress-builds';
import { activateTheme } from './activate-theme';
import { phpVar } from '@php-wasm/util';
import { PHPRequestHandler } from '@php-wasm/universal';
import { bootWordPress } from '@wp-playground/wordpress';

describe('Blueprint step activateTheme()', () => {
let php: PHP;
let handler: PHPRequestHandler;
beforeEach(async () => {
handler = new PHPRequestHandler({
phpFactory: async () =>
new PHP(await loadNodeRuntime(RecommendedPHPVersion)),
documentRoot: '/wordpress',
handler = await bootWordPress({
createPhpRuntime: async () =>
await loadNodeRuntime(RecommendedPHPVersion),
siteUrl: 'http://playground-domain/',

wordPressZip: await getWordPressModule(),
sqliteIntegrationPluginZip: await getSqliteDatabaseModule(),
});
php = await handler.getPrimaryPhp();
php.mkdir('/wordpress');
await unzip(php, {
zipFile: await getWordPressModule(),
extractToPath: '/wordpress',
});
});

it('should activate the theme', async () => {
Expand Down Expand Up @@ -55,14 +56,16 @@ describe('Blueprint step activateTheme()', () => {
docroot + '/activation-ran-as-a-priviliged-user.txt';

const themeDir = `${docroot}/wp-content/themes/test-theme`;
php.mkdir(`${themeDir}/test-theme`);
php.mkdir(themeDir);
php.writeFile(
`${themeDir}/style.css`,
`/**
* Theme Name: Test Theme
* Theme URI: https://example.com/test-theme
*/`
);

php.mkdir(`${docroot}/wp-content/mu-plugins`);
php.writeFile(
`${docroot}/wp-content/mu-plugins/0-on-theme-switch.php`,
`<?php
Expand Down Expand Up @@ -95,8 +98,9 @@ describe('Blueprint step activateTheme()', () => {
*/
`
);
php.mkdir(`${docroot}/wp-content/mu-plugins`);
php.writeFile(
`/${docroot}/wp-content/mu-plugins/0-exit.php`,
`${docroot}/wp-content/mu-plugins/0-exit.php`,
`<?php exit(0); `
);
expect(
Expand Down
30 changes: 15 additions & 15 deletions packages/playground/blueprints/src/lib/steps/cp.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,44 @@ describe('Blueprint step cp()', () => {
});

it('should copy a file', async () => {
php.writeFile(`/${docroot}/index.php`, `<?php echo 'Hello World';`);
php.writeFile(`${docroot}/index.php`, `<?php echo 'Hello World';`);
await cp(php, {
fromPath: `/${docroot}/index.php`,
toPath: `/${docroot}/index2.php`,
fromPath: `${docroot}/index.php`,
toPath: `${docroot}/index2.php`,
});

expect(php.fileExists(`/${docroot}/index.php`)).toBe(true);
expect(php.fileExists(`/${docroot}/index2.php`)).toBe(true);
expect(php.fileExists(`${docroot}/index.php`)).toBe(true);
expect(php.fileExists(`${docroot}/index2.php`)).toBe(true);
});

it('should fail when the source file does not exist', async () => {
await expect(
cp(php, {
fromPath: `/${docroot}/index.php`,
toPath: `/${docroot}/index2.php`,
fromPath: `${docroot}/index.php`,
toPath: `${docroot}/index2.php`,
})
).rejects.toThrow(/There is no such file or directory/);
});

it('should fail when the source file is a directory', async () => {
php.mkdir(`/${docroot}/dir`);
php.mkdir(`${docroot}/dir`);
await expect(
cp(php, {
fromPath: `/${docroot}/dir`,
toPath: `/${docroot}/index2.php`,
fromPath: `${docroot}/dir`,
toPath: `${docroot}/index2.php`,
})
).rejects.toThrow(/There is a directory under that path/);
});

it('should overwrite the target file', async () => {
php.writeFile(`/${docroot}/index.php`, `<?php echo 'Hello World';`);
php.writeFile(`/${docroot}/index2.php`, `<?php echo 'Goodbye World';`);
php.writeFile(`${docroot}/index.php`, `<?php echo 'Hello World';`);
php.writeFile(`${docroot}/index2.php`, `<?php echo 'Goodbye World';`);
await cp(php, {
fromPath: `/${docroot}/index.php`,
toPath: `/${docroot}/index2.php`,
fromPath: `${docroot}/index.php`,
toPath: `${docroot}/index2.php`,
});

expect(php.readFileAsText(`/${docroot}/index2.php`)).toBe(
expect(php.readFileAsText(`${docroot}/index2.php`)).toBe(
`<?php echo 'Hello World';`
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
import { PHP } from '@php-wasm/universal';
import { RecommendedPHPVersion } from '@wp-playground/common';
import { getWordPressModule } from '@wp-playground/wordpress-builds';
import { unzip } from './unzip';
import {
getSqliteDatabaseModule,
getWordPressModule,
} from '@wp-playground/wordpress-builds';
import { enableMultisite } from './enable-multisite';
import { PHPRequestHandler } from '@php-wasm/universal';
import { bootWordPress } from '@wp-playground/wordpress';
import { loadNodeRuntime } from '@php-wasm/node';
import { setupPlatformLevelMuPlugins } from '@wp-playground/wordpress';

const DOCROOT = '/test-dir';
describe('Blueprint step enableMultisite', () => {
async function bootWordPress(options: { absoluteUrl: string }) {
const requestHandler = new PHPRequestHandler({
phpFactory: async () =>
new PHP(await loadNodeRuntime(RecommendedPHPVersion)),
absoluteUrl: options.absoluteUrl,
async function doBootWordPress(options: { absoluteUrl: string }) {
const requestHandler = await bootWordPress({
createPhpRuntime: async () =>
await loadNodeRuntime(RecommendedPHPVersion),
siteUrl: options.absoluteUrl,
documentRoot: DOCROOT,

wordPressZip: await getWordPressModule(),
sqliteIntegrationPluginZip: await getSqliteDatabaseModule(),
});
const php = await requestHandler.getPrimaryPhp();
await unzip(php, {
zipFile: await getWordPressModule(),
extractToPath: DOCROOT,
});
// Ensure we're preloading platform-level mu-plugins
await setupPlatformLevelMuPlugins(php);

return { php, requestHandler };
}

it('should enable a multisite on a scoped URL', async () => {
const { php, requestHandler } = await bootWordPress({
const { php, requestHandler } = await doBootWordPress({
absoluteUrl: 'http://playground-domain/scope:987987/',
});
await enableMultisite(php, {});
Expand All @@ -39,7 +37,7 @@ describe('Blueprint step enableMultisite', () => {
}, 30_000);

it('should enable a multisite on a scopeless URL', async () => {
const { php, requestHandler } = await bootWordPress({
const { php, requestHandler } = await doBootWordPress({
absoluteUrl: 'http://playground-domain/',
});
await enableMultisite(php, {});
Expand Down
23 changes: 12 additions & 11 deletions packages/playground/blueprints/src/lib/steps/import-wxr.spec.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { PHP } from '@php-wasm/universal';
import { RecommendedPHPVersion } from '@wp-playground/common';
import { getWordPressModule } from '@wp-playground/wordpress-builds';
import {
getSqliteDatabaseModule,
getWordPressModule,
} from '@wp-playground/wordpress-builds';
import { importWxr } from './import-wxr';
import { readFile } from 'fs/promises';
import { unzip } from './unzip';
import { installPlugin } from './install-plugin';
import { PHPRequestHandler } from '@php-wasm/universal';
import { bootWordPress } from '@wp-playground/wordpress';
import { loadNodeRuntime } from '@php-wasm/node';

describe('Blueprint step importWxr', () => {
let php: PHP;
let handler: PHPRequestHandler;
beforeEach(async () => {
handler = new PHPRequestHandler({
phpFactory: async () =>
new PHP(await loadNodeRuntime(RecommendedPHPVersion)),
documentRoot: '/wordpress',
});
php = await handler.getPrimaryPhp();
handler = await bootWordPress({
createPhpRuntime: async () =>
await loadNodeRuntime(RecommendedPHPVersion),
siteUrl: 'http://playground-domain/',

await unzip(php, {
zipFile: await getWordPressModule(),
extractToPath: '/wordpress',
wordPressZip: await getWordPressModule(),
sqliteIntegrationPluginZip: await getSqliteDatabaseModule(),
});
php = await handler.getPrimaryPhp();

// Delete all posts
await php.run({
Expand Down
27 changes: 14 additions & 13 deletions packages/playground/blueprints/src/lib/steps/login.spec.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import { PHP } from '@php-wasm/universal';
import { RecommendedPHPVersion } from '@wp-playground/common';
import { getWordPressModule } from '@wp-playground/wordpress-builds';
import {
getSqliteDatabaseModule,
getWordPressModule,
} from '@wp-playground/wordpress-builds';
import { login } from './login';
import { unzip } from './unzip';
import { PHPRequestHandler } from '@php-wasm/universal';
import { bootWordPress } from '@wp-playground/wordpress';
import { loadNodeRuntime } from '@php-wasm/node';

describe('Blueprint step installPlugin', () => {
let php: PHP;
let requestHandler: PHPRequestHandler;
let handler: PHPRequestHandler;
beforeEach(async () => {
requestHandler = new PHPRequestHandler({
phpFactory: async () =>
new PHP(await loadNodeRuntime(RecommendedPHPVersion)),
documentRoot: '/wordpress',
});
php = await requestHandler.getPrimaryPhp();
handler = await bootWordPress({
createPhpRuntime: async () =>
await loadNodeRuntime(RecommendedPHPVersion),
siteUrl: 'http://playground-domain/',

await unzip(php, {
zipFile: await getWordPressModule(),
extractToPath: '/wordpress',
wordPressZip: await getWordPressModule(),
sqliteIntegrationPluginZip: await getSqliteDatabaseModule(),
});
php = await handler.getPrimaryPhp();
});

it('should log the user in', async () => {
await login(php, {});
const response = await requestHandler.request({
const response = await handler.request({
url: '/wp-admin',
});
expect(response.text).toContain('Dashboard');
Expand Down
Loading

0 comments on commit daf9c52

Please sign in to comment.