Skip to content

Reduce the need for npm by installing built files from the WordPress mirror - #246

Open
ramonfincken wants to merge 3 commits into
WordPress:masterfrom
ramonfincken:reduce-need-for-npm
Open

ramonfincken wants to merge 3 commits into
WordPress:masterfrom
ramonfincken:reduce-need-for-npm

Conversation

@ramonfincken

@ramonfincken ramonfincken commented Jun 7, 2025 •

Copy link
Copy Markdown

Problem

The test suite runs against src/ of the wordpress-develop checkout, and src/ only works after the build has written the generated scripts, styles and block assets into it. The only way prepare.php had to get them was npm install && npm run build:dev, so a host needs Node.js and npm, a node_modules tree and the Gutenberg artifact download from ghcr.io to run a PHP test suite (#244). The first version of this PR tried to shortcut that by patching core's Gruntfile and copying the nightly's files into build/; it kept npm install, lost the exact revision, and build/ is no longer where the tests look since #351.

Fix

A new opt-in WPT_ASSETS_SOURCE=mirror. prepare.php then:

  1. reads the Subversion revision of the clone from its last commit message (git-svn-id: .../trunk@NNNNN, present in a shallow clone too);
  2. finds the commit of the WordPress/WordPress mirror that was built from that revision: every mirror commit message carries Built from https://develop.svn.wordpress.org/trunk@NNNNN (branches map to x.y-branch), about a minute behind develop; the lookup reads the latest 100 commits through the public GitHub API, unauthenticated;
  3. downloads that tree as a tarball (about 60 MB) and copies into src/ only the files the checkout ignores (git check-ignore), so tracked files stay exactly as checked out;
  4. checks a few sentinel files (wp-includes/js/jquery/jquery.js, wp-includes/js/dist/blocks.js, wp-includes/css/dist/block-library/style.css, wp-admin/js/common.js).

Any miss (no mirror commit yet, download or copy failure, missing sentinel) logs the reason and runs the npm build as before. WPT_ASSETS_SOURCE=npm (the default) is unchanged. An unknown value stops prepare.php with a clear error.

What changes for hosts

Nothing unless they set WPT_ASSETS_SOURCE=mirror. With it, a successful run does not touch Node.js or npm: no node_modules, no Gutenberg download, and prepare.php finishes in well under a minute instead of several. When the mirror has no commit for the revision yet, or the download or validation fails, the npm build runs as before, so Node.js and npm stay installed. Documented in README.md and .env.default.

Verification

Local, macOS 27 (arm64), PHP 8.5.11, MySQL 26.7.0 (Homebrew), Node 26.10 / npm 11.19, the real runner (prepare.php then test.php), core trunk r64238 (same commit for every run below).

WPT_ASSETS_SOURCE=mirror WPT_ASSETS_SOURCE=npm (default)
prepare.php, fresh clone to "Prepared environment" 22 s and 37 s in two runs clone + npm install 21 s with a warm npm cache + build:dev 23 s
Node.js / npm used no yes
Extra disk 59 MB tarball, deleted after the copy node_modules 804 MB
Generated files under src/ 1605 1606 (tinymce.js is the extra one)
Full suite, single site 25944 tests, 4561463 assertions, 1 failure, 86 warnings, 74 skipped, 298 s 25944 tests, 4561463 assertions, 1 failure, 86 warnings, 74 skipped, 296 s

The one failure is Tests_Admin_wpPostsListTable::test_search_hierarchical_pages_first_page on both routes, a local environment issue unrelated to the built files; the warnings are PHP 8.5 deprecations inside core's tests, identical on both. The junit reports name the same failing test and nothing else.

The only file the npm build writes that the mirror does not carry is src/wp-includes/js/tinymce/tinymce.js (the mirror ships tinymce.min.js and wp-tinymce.js); nothing in tests/phpunit/tests references it. The mirror route copied nothing the build does not also write.

Also exercised: the revision parser on the checkout (trunk@64238), on a repository without a git-svn-id line and on a non-repository (null, null); the mirror lookup for a branch (branches/7.1@64164 -> the mirror commit built from it) and for a revision that does not exist (null); the fallback with a checkout whose revision the mirror never built, and with the GitHub API unreachable: both return false before touching src/, so prepare.php continues with the npm build.

Five full runs in all (four mirror, one npm) on that revision, every one with the same single failure. The first mirror run copied wp-admin and wp-includes only and came out four assertions short; adding the bundled themes' minified styles to the copy (two files) closed that gap. The last run used the exact code in this PR: 25944 tests, 4561463 assertions, 1 failure, 86 warnings, 74 skipped, 300 s. Logs, scripts and junit reports are in my notes and can be shared on request.

Concurrency: two prepare.php runs for the same revision, started together with separate prepare directories, both finished in 23 s with byte-identical src/ trees, each in its own temporary work directory (wpt-built-assets-<sha>-<pid>-<random>), nothing left behind. A forced download failure (a wget that exits 1) returns to the npm path and leaves no temporary directory either.

Notes

  • The mirror lags develop by about a minute. A run that starts within that window falls back to npm for that revision, with the reason in the log.
  • Branch checkouts (branches/x.y) map to the mirror's x.y-branch the same way.
  • The GitHub API call is unauthenticated: 60 requests per hour per IP, one per run.
  • Host tests on Linux welcome; this was proven on macOS with GNU-compatible tar, rsync and wget.

Use of AI

AI assistance: Yes
Tool(s): Claude Code and Codex
Used for: investigation, implementation, the proof runs and the PR wording. I reviewed the reasoning and the results and take responsibility for the contribution.

…ld as source of truth for CSS and JS files
@desrosj

desrosj commented Jun 11, 2025

Copy link
Copy Markdown
Member

Perhaps I'm missing something. But why can't the test runner just use the https://github.com/WordPress/WordPress repository instead of the nightly?

Using the nightly loses a level of fidelity because you can't control which commit is tested. But the WordPress SVN repository is updated by the build server after every commit to wordpress-develop and mirrored here to GitHub.

The only challenge there is a search would need to be performed to find the corresponding changeset.

@ramonfincken

Copy link
Copy Markdown
Author

The point is to copy the nightly JS/CSs files, not the PHP ones.

But hold on, i will try using another path.

@ramonfincken

Copy link
Copy Markdown
Author

Thanks for your talk at WordCamp by the way :)

@ekamran

ekamran commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Picking this up, thanks Ramon for the first attempt.

The original direction here still makes sense, but the implementation needs a different shape now. #246 still runs npm install, patches core's Gruntfile, downloads the nightly, and copies built assets into build/. With #351, the runner's test build path is moving to build:dev, so the files the tests need live under src/ instead.

The alternative desrosj suggested looks viable: the WordPress/WordPress built mirror carries the exact develop revision in each commit message (Built from https://develop.svn.wordpress.org/trunk@NNNNN). I verified the current trunk revision maps to the mirror about a minute later, and the mirror contains the built files that wordpress-develop ignores under src/, including wp-includes/js/dist, jQuery, block CSS/JS, wp-admin/js, and CSS dist files.

Plan: a new opt-in WPT_ASSETS_SOURCE=mirror path that finds the mirror commit for the checked-out develop revision, downloads that built tree, copies the ignored asset paths into src/, runs sentinel checks, and falls back to the normal npm build:dev path if the mirror commit or required files are not available. Default behavior stays npm.

I will push the new approach to this PR, with a same-revision comparison of the npm route and the mirror route.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @ramon@creativepulses.nl.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: ramon@creativepulses.nl.

Co-authored-by: ekamran <ekamran@git.wordpress.org>
Co-authored-by: desrosj <desrosj@git.wordpress.org>
Co-authored-by: ramonfincken <ramon-fincken@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

The test suite runs against src/ of the wordpress-develop checkout, which
needs the generated scripts, styles and block assets. Until now the only
way to get them was npm install and npm run build:dev, so every host needs
Node.js and npm for a PHP test run.

With WPT_ASSETS_SOURCE=mirror, prepare.php reads the checked-out revision
from the clone, finds the WordPress/WordPress commit built from that
revision (every mirror commit names it), downloads that tree and copies
the files the checkout ignores into src/. Tracked files stay as checked
out. When no mirror commit exists for the revision yet, or the expected
files are missing, the npm build runs as before. The default stays npm.

Supersedes the approach first tried in this PR, which patched core's
Gruntfile and copied the nightly build into build/.
@ekamran ekamran changed the title [TASK] first attempt to reduce NPM need bu using the Core nightly bui… Reduce the need for npm by installing built files from the WordPress mirror Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

4 participants