Skip to content

Detect actual, loaded WP version - #1503

Merged
brandonpayton merged 18 commits into
trunkfrom
derive-wp-version-from-browser-storage
Jun 21, 2024
Merged

Detect actual, loaded WP version#1503
brandonpayton merged 18 commits into
trunkfrom
derive-wp-version-from-browser-storage

Conversation

@brandonpayton

@brandonpayton brandonpayton commented Jun 11, 2024

Copy link
Copy Markdown
Member

Motivation for the change, related issues

When loading from browser storage, Playground can incorrectly assume the loaded WP version is the default version when it is actually something else. This can cause issues where remote assets are requested from the wrong version of WP.

In addition, this work is needed to support a follow-up PR where we retrieve the wordpress-remote-asset-paths listing from the website when it is not already present within browser storage.

Implementation details

This PR adds two functions, one for detecting the version using wp-includes/version.php, and another for determining whether the detected version is one of the WP versions supported through the Playground web app.

These functions are used when initializing worker threads to detect the version of WP that was booted.

If detection fails, the WordPress version is left set to the default version.

Testing Instructions (or ideally a Blueprint)

  • CI, including new unit tests
@brandonpayton
brandonpayton requested a review from a team June 11, 2024 02:03
@brandonpayton brandonpayton self-assigned this Jun 11, 2024
});

if (result.errors.length > 0) {
// TODO: Find a way to warn

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the logger for this


if (!loadedVersion) {
// TODO: Is there something better than throwing at this stage?
return undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just return the default version?

@adamziel adamziel Jun 11, 2024

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is empty, something is very wrong – like a broken or missing WordPress installation. I'd rather show a big error.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I will make this throw. That seems preferable for clarity, especially if we are planning to remove the uncertainty around requesting remote assets from older point releases. In that case, we are no longer running OK by coincidence but because we're actually doing the right thing.

@adamziel

adamziel commented Jun 11, 2024

Copy link
Copy Markdown
Collaborator

@brandonpayton If we're loading a minified build from the browser storage, all bets are off. We might be loading WP 6.4.1 while playground.wordpress.net already has assets from 6.4.3. The files list may differ, and mixing assets from the two might lead to a broken state.

In addition, this work is needed to support a follow-up PR where we retrieve the wordpress-remote-asset-paths listing from the website when it is not already present within browser storage.

Let's always put it in the browser storage and expect to find it there. If it's missing from a minified build, that's an error. That would only happen if it gets deleted after we boot the minified bundle and before we finish downloading the zip file with the rest of the assets.

Also, let's find a way to always load all the assets from 6.4.1. This will always work, but what do we do if those assets are missing from the browser storage? I have a few ideas:

  1. Host all the historical assets bundles, including wordpress-remote-asset-paths, on playground.wordpress.net. It will increase the storage requirements by ~500MB a year. That sounds manageable for now and perhaps we'll have a better solution in 3 years.
  2. Stream the assets from an official release bundle. We have a partial ZIP downloader in @php-wasm/stream-compression. Downside: It's more complex, we need to deal with CORS, it relies on ranges request support which we don't have in proxy.php. I'd leave that for an unspecified future.
): Promise<string | undefined> {
const result = await php.run({
code: `<?php
if (is_file('${wordpressRoot}/wp-includes/version.php')) {

@adamziel adamziel Jun 11, 2024

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

php.documentRoot should do the trick here. The entire codebase assumes WordPress lives there – if it doesn't, we have a larger problem.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

php.documentRoot should do the trick here. The entire codebase assumes WordPress lives there – if it doesn't, we have a larger problem.

Thanks, I ended up using requestHandler.documentRoot because php.documentRoot is marked as deprecated.

`,
});

if (result.errors.length > 0) {

@adamziel adamziel Jun 11, 2024

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR php.run() throws on failure. result.errors is just stderr

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR php.run() throws on failure. result.errors is just stderr

Thanks! Will skip considering result.errors then.

// from browser storage is the default version when it is actually something else.
// Incorrectly assuming WP version can break things like remote asset retrieval
// for minified WP builds.
const loadedWordPressVersion = await getLoadedWordPressVersion(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this relevant for non-minified builds? Assets-wise, probably not, but it seems like it would enable displaying "6.6-nightly" in the UI, correct?

@brandonpayton brandonpayton Jun 11, 2024

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this relevant for non-minified builds? Assets-wise, probably not, but it seems like it would enable displaying "6.6-nightly" in the UI, correct?

Yes, I wasn't planning to do it as part of this PR but was thinking we could show the detected version in the UI.

@brandonpayton

Copy link
Copy Markdown
Member Author

In addition, this work is needed to support a follow-up PR where we retrieve the wordpress-remote-asset-paths listing from the website when it is not already present within browser storage.

Let's always put it in the browser storage and expect to find it there. If it's missing from a minified build, that's an error. That would only happen if it gets deleted after we boot the minified bundle and before we finish downloading the zip file with the rest of the assets.

@adamziel the main case I am thinking of is today's browser storage contents before we started shipping the remote asset listing. If people used browser storage before then, they would not have the listing, and requests for remote assets break. It's why I reverted the second request routing attempt. We're no longer deleting that file, so it should exist for all new browser storage. But for people who are loading from older browser storage, it is broken.

What do you think we should do here? Retrieve the listing file, just let it be broken, or something else?

@brandonpayton

Copy link
Copy Markdown
Member Author

What do you think we should do here? Retrieve the listing file, just let it be broken, or something else?

@adamziel nevermind, I see you are discussing that path here :)

Also, let's find a way to always load all the assets from 6.4.1. This will always work, but what do we do if those assets are missing from the browser storage? I have a few ideas:

@brandonpayton

Copy link
Copy Markdown
Member Author

Also, let's find a way to always load all the assets from 6.4.1. This will always work, but what do we do if those assets are missing from the browser storage?

I think we should do this work in the following steps, as separate PRs:

  1. This PR detects the current major/minor version
  2. Another PR downloads the remote asset listing for the detected WP version. Playground may still break if the stored version of WP is a different point release than the latest, but it is not worse than our current behavior which is to assume WP loaded from browser storage is "latest".
  3. Merge the request routing updates which depend on the remote asset listing. This gives us better request routing and shouldn't be worse than our current behavior of assuming WP from browser storage is "latest".
  4. Support providing/backfilling remote assets for all supported WP point releases, including corresponding remote asset listings.
  5. Update Playground to request WordPress assets from specific point releases

@WordPress/playground-maintainers what do you think?

note: We also need to consider what to do about "nightly" as a special case.

@brandonpayton

Copy link
Copy Markdown
Member Author

With the new unit tests, we encountered this failure in CI:

   ❯ src/test/version-detect.spec.ts > Test WP version detection > detects WP nightly
     → expected 'beta' to equal 'nightly'

Is it possible this is due to some test parallelization and shared FS? Otherwise, I'm not sure why this would be failing. The WP nightly zip here does not have a wp_version that includes the string "beta".

@brandonpayton

Copy link
Copy Markdown
Member Author

Is it possible this is due to some test parallelization and shared FS? Otherwise, I'm not sure why this would be failing. The WP nightly zip here does not have a wp_version that includes the string "beta".

The latest WP nightly build on trunk does include "beta" in its version string, which explains why the test is failing. We can't assume the nightly version contains "alpha".

@brandonpayton

brandonpayton commented Jun 11, 2024

Copy link
Copy Markdown
Member Author

Since the "nightly" version is transient and unstable day-to-day, it is now explicitly skipped in the version detection unit tests.

As an aside:
I wonder if it makes sense to download a full WP nightly zip when using browser storage. That way, all needed assets for working with the specific nightly version will be stored together, and that version should have everything it needs regardless of how stale it becomes over time.

@brandonpayton
brandonpayton force-pushed the derive-wp-version-from-browser-storage branch from 0a796e6 to fe3c268 Compare June 11, 2024 19:16
@brandonpayton

brandonpayton commented Jun 11, 2024

Copy link
Copy Markdown
Member Author

Since the "nightly" version is transient and unstable day-to-day, it is now explicitly skipped in the version detection unit tests.

It looks like we can still detect the nightly version.

The nightly version with "beta" in the string has a numeric suffix and looks like:
6.6-beta1-58376

The actual beta version looks like:
6.6-beta2

I've tightened nightly version detection and re-enabled testing for it.

Users might bring their own builds,
and we want to allow any declared version
as long as it is non-empty.
@brandonpayton

Copy link
Copy Markdown
Member Author

This is ready for another review. Please see this comment for a proposed path forward.

@brandonpayton

Copy link
Copy Markdown
Member Author

@adamziel @bgrgicak do you have any concerns about landing this? If not, I will merge and use this to pull the wordpress-remote-asset-paths dynamically as needed. Then we should have everything we need to land the request routing changes, even with stale browser storage.

@brandonpayton

brandonpayton commented Jun 18, 2024

Copy link
Copy Markdown
Member Author

Please see this comment for the overall plan:
#1503 (comment)

@adamziel

Copy link
Copy Markdown
Collaborator

I’ll re-review tomorrow

const loadedWordPressVersion = await getLoadedWordPressVersion(
requestHandler
);
if (isSupportedWordPressVersion(loadedWordPressVersion)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this check we won't always expose apiEndpoint.wordPressVersion which seems confusing. It makes it seem like we're not running any WordPress version if the version string doesn't match the pattern. What's an upside?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this actually overrides the previous value of wordPressVersion. Still, can't we always override?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this actually overrides the previous value of wordPressVersion. Still, can't we always override?

@adamziel This is the version used to download static assets. I think we should make it so that we just don't attempt static asset downloads for unsupported versions but plan to do that in a follow up PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my mind and updated this PR to tolerate an undefined staticAssetsDirectory when loading an unsupported WP version. It didn't seem right to land this in an in-between state.

In addition, instead of clobbering the requested WordPress version with the detected version, I made them different properties:

  • requestedWordPressVersion
  • loadedWordPressVersion

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call!

@adamziel adamziel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left a question about the version number check, but other than that this PR looks good to me!

@brandonpayton
brandonpayton merged commit d6a90af into trunk Jun 21, 2024
@brandonpayton
brandonpayton deleted the derive-wp-version-from-browser-storage branch June 21, 2024 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Boot Flow [Package][@wp-playground] WordPress [Type] Bug An existing feature does not function as intended

3 participants