Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playground CLI #1289

Merged
merged 72 commits into from
Apr 29, 2024
Merged

Playground CLI #1289

merged 72 commits into from
Apr 29, 2024

Conversation

adamziel
Copy link
Collaborator

@adamziel adamziel commented Apr 21, 2024

WordPress Playground CLI

A CLI tool for running WordPress playground locally instead of in the browser.

Usage when testing this PR

# Just run a clean-slate WordPress server
$ bun packages/playground/cli/src/cli.ts server --wp=6.5
WordPress is running on http://127.0.0.1:9400

# Start PHP server and mount a WordPress develop build at /wordpress
$ bun ./packages/playground/cli/src/cli.ts server --mount=../../wordpress-develop/build:/wordpress
WordPress is running on http://127.0.0.1:9400

The end goal is to create a portable cross-OS server binary with Bun, see #1056 for more context.

Usage after merging this PR

$ npx @wp-playground/cli server --wp=6.5

Flexible and unoppinionated

Playground CLI is simple, configurable, and unoppinionated. You can set it up
to your unique WordPress setup. For example, this command would run the documentation
workflow at https://github.com/adamziel/playground-docs-workflow:

bun --config=/Users/adam/.bunfig.toml \
    ./packages/playground/cli/src/cli.ts \
    server \
    --mount=./wp-content/plugins/wp-docs-plugin:/wordpress/wp-content/plugins/wp-docs-plugin \
    --mount=./wp-content/html-pages:/wordpress/wp-content/html-pages \
    --mount=./wp-content/uploads:/wordpress/wp-content/uploads \
    --mount=./wp-content/themes/playground-docs:/wordpress/wp-content/themes/playground-docs \
    --blueprint=./wp-content/blueprint-wp-now.json \
    --wp=6.5

It is long, sure, but it is also very flexible. If you need a shorter version, you can alias
it or write a bash script. In the future, Blueprints might support relative path mappings,
at which point that command would get much shorter.

Usage

Playground CLI supports three commands:

  • server - start a fresh WordPress playground server.
  • build-snapshot – run a Blueprint and output a .zip file with the resulting WordPress instance.
  • run-blueprint – just run the Blueprint and exit

Here's the CLI usage:

Positionals:
  command  Command to run                   [string] [choices: "server", "run-blueprint", "build-snapshot"]

Options:
  --help                Show help                                      [boolean]
  --version             Show version number                            [boolean]
  --outfile             When building, write to this output file.
                                             [string] [default: "wordpress.zip"]
  --port                Port to listen on when serving. [number] [default: 9400]
  --php                 PHP version to use.
  [string] [choices: "8.3", "8.2", "8.1", "8.0", "7.4", "7.3", "7.2", "7.1", "7.
                                                            0"] [default: "8.0"]
  --wp                  WordPress version to use.   [string] [default: "latest"]
  --mount               Mount a directory to the PHP runtime.            [array]
  --login               Should log the user in        [boolean] [default: false]
  --blueprint           Blueprint to execute.                           [string]
  --skipWordPressSetup  Do not download, unzip, and install WordPress. Useful for
                        mounting a pre-configured WordPress directory at /wordpress
                        [boolean] [default: false]

Server

Playground is a WordPress server:

$ bun ./packages/playground/cli/src/cli.ts server
Setting up WordPress latest
Running a blueprint – 100%
WordPress is running on http://127.0.0.1:9400

Builder

Playground can build a Blueprint.json file into a wordpress.zip:

$ bun ./packages/playground/cli/src/cli.ts build \
     --blueprint=./blueprint.json \
     --outfile=wp.zip
Setting up WordPress latest
Running the blueprint – 100%
Zipping WordPress to wp.zip
WordPress saved to wp.zip

All the mounts you specify will still apply.

Philosophy

The data flow is as follows:

  • Start PHP
  • Mount any local directories
  • Put a fresh WordPress in the resulting virtual filesystem (unless you're mounting directly at /wordpress).
  • Start a local server, accept requests
  • Run the Blueprint

On each run, a fresh WordPress release is unzipped in the virtual filesystem. It is sourced
from a zip file cached at ~/.wordpress-playground/. If you mess up your site, just restart the
server and you'll get a fresh one, again unzipped. The CLI tool never modifies the zip file
so you can always be sure you're starting from a clean slate.

Future work

In the guture, Playground CLI may support:

  • Loading Blueprints from URLs.
  • Saving the running WordPress site and loading it later.
  • Caching all remote resources referenced in Blueprints. Currently, they are downloaded on each run.

Conceptually, this isn't too different from Docker containers. There are images (zip files),
containers (running instances), and commands (Blueprints). Playground could support the same
concepts such as:

  • Listing and managing available images and containers.
  • Saving a running container and restoring it later
  • Starting a container from a specific image (already supported via zip files)
  • Running a command in a container (the php command)
  • Building a new image from a Blueprint (the build command)
  • Step-by-step cache for Blueprints so that only the changed steps are re-run.

Interoperability

This CLI package is not just a useful tool. It drives interoperability between the in-browser
Playground, CLI packages, and the PHP Blueprints library. Once complete, it will reuse the
same internals as the website at https://playground.wordpress.org whether we're talking about
running PHP code, executing Blueprints, building snapshots, serving requests, or maintaining
multiple PHP instances

Known issues

  • The progress bar sometimes does not reach 100% and the sequencing of the events means a newline is displayed between Running a blueprint and 100%.

Possible improvements

  • Blueprints downloads are not cached but performed each time, e.g. gutenberg.zip will be download on each build.
  • The built binary is 180MB large as it bundles all the .wasm modules. We could only ship PHP 8.0 for starters and download the rest on demand.
  • Grid build for all the OSes and CPUs.

How do I run the binary? I'm getting an error!

@stoph Wrote this excellent guide:

Once downloaded find the file in your terminal. If you initially try to run it, you’ll get an error

$ ./playground-cli
zsh: permission denied: ./playground-cli

You’ll need to grant execute permissions to allow it to run

$ chmod +x playground-cli

You’ll then get a pop-up form MacOS warning about untrusted code.

unnamed

Find the file in your Finder. Right click and select “Open” This should not give you the option to Open from the dialog.

unnamed

Once that’s done, you can close the terminal it launched and should be able to run it without issue from the command line going forward.

$ ./playground-cli server

cc @dmsnell

@adamziel adamziel requested a review from a team as a code owner April 21, 2024 23:59
The request handler needs to decide whether to serve a static asset or
run the PHP interpreter. For static assets it should just reuse the primary
PHP even if there's 50 concurrent requests to serve. However, for
dynamic PHP requests, it needs to grab an available interpreter.
Therefore, it cannot just accept PHP as an argument as serving requests
requires access to ProcessManager.
@adamziel adamziel marked this pull request as ready for review April 29, 2024 19:40
@adamziel
Copy link
Collaborator Author

I'm not 100% confident in the Node PHP build changes but I can't get lerna publish to work fromy branch with a dist tag so I'll go ahead, merge, publish from a CI job, and revert if anything goes wrong.

@adamziel adamziel merged commit 7c229a6 into trunk Apr 29, 2024
5 checks passed
@adamziel adamziel deleted the node-server branch April 29, 2024 21:27
adamziel added a commit that referenced this pull request Apr 30, 2024
#1289 shipped a
PHP.wasm building logic that used an import statement instead of
composing a path of __dirname. It did that to support Bun bundling, as
Bun needs those static imports to include the .wasm files in the single
executable. Unfortunately, that change broke npm bundling and
publishing, resulting in a broken package that doesn't ship the correct
paths and builds a broken index.cjs file.
adamziel added a commit that referenced this pull request Apr 30, 2024
)

#1289 shipped a
PHP.wasm building logic that used an import statement instead of
composing a path of __dirname. It did that to support Bun bundling, as
Bun needs those static imports to include the .wasm files in the single
executable. Unfortunately, that change broke npm bundling and
publishing, resulting in a broken package that doesn't ship the correct
paths and builds a broken index.cjs file.
adamziel added a commit to adamziel/playground-docs-workflow that referenced this pull request May 1, 2024
…eneration (#59)

This PR ships a Blueprint that generates the static site using the Simply Static plugin and the `run-blueprint` feature WordPress/wordpress-playground#1289.

Usage:

```shell
bash build-static-site.sh
# the site is now rendered in the output directory
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants