It’s been a busy year so far for the Build/Test Tool component! Here are some notable changes to be aware of, and an update on the transition to using GitHub Actions for all automated testing.
NodeJS 14.x LTS support
NodeJS 14.x has been the active LTS version since April of 2020. While dependencies were updated to ensure support and related build scripts have worked on 14.x for some time now, the
package.json file in Core Core is the set of software required to run WordPress. The Core Development Team builds WordPress. now officially recommends using NodeJS
14.15.0 and NPM
The versions specified in the
engines field of the
package.json file have also been updated to specify a range of versions (
>=14.15.0) instead of explicit versions (
14.15.0). This should make it more clear to contributors that they can use any version newer than the one specified.
For more information on these changes, check out #51749 and #52455 on Trac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress..
Consistent tooling across all branches
The WordPress project’s current support policy is that only the most recent major version should be considered supported. At the time of this post, this means that 5.7 is the only maintained branch A directory in Subversion. WordPress uses branches to store the latest development code for each major release (3.9, 4.0, etc.). Branches are then updated with code for any minor releases of that branch. Sometimes, a major version of WordPress and its minor versions are collectively referred to as a "branch", such as "the 4.0 branch".. However, security fixes are backported as a courtesy in an effort to promote a more secure web (currently) all the way back to the 3.7 branch.
Because of changes in TravisCI’s services, the 3.7-5.5 branches did not have working automated testing configured since the first week of December. To fix this, the GitHub GitHub is a website that offers online implementation of git repositories that can can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ Actions workflow files added to
trunk needed to be backported. This could be accomplished for the 4.6-5.5 branches fairly easily after [49527-49533].
However, because build/test tool functionality has not been maintained in old branches, there were a few blockers and consistency issues that needed to be resolved before the necessary workflows could be backported further.
Outdated NodeJS versions
Because old branches are not maintained and only receive security updates as a courtesy, the version of NodeJS used in each branch largely reflected the active version of NodeJS when the branch was created. For example, the 3.7 branch used
v0.10.48, 4.2 used
v0.12.18, 4.3 used
This was recently made easier through the use of
nvm (Node Version Manager) and
.nvmrc files (see #51682), but the dependencies needed to run the local Docker environment (more on that below) do not support these older versions of NodeJS.
After [50187-50224], all older branches currently receiving security updates have been updated to support the most recent version of NodeJS LTS (currently 14.x) and all
devDependencies specified in the
package.json files have been updated to their latest versions.
The 3.7-4.9 branches also contained an
npm-shrinkwrap.json file. This is a type of lock file that predates the newer
package-lock.json file. Since all newer branches utilize a
package-lock.json file to specify the exact desired versions of dependencies, all
npm-shrinkwrap.json files have been replaced with
package-lock.json ones in old branches for consistency.
For more information on these changes, see #52341 on Trac.
Another side effect of only backporting security fixes to unmaintained branches is inconsistent tooling. Because tools that make contributing easier are updated and added in each release, switching to an older branch to create a patch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. becomes much more difficult. The tools contributors are accustomed to using are not there or work differently, and then they have to spend time figuring out how things were done in the past before they can contribute.
All branches now contain the same basic scripts needed to work on WordPress locally. This includes:
npm run build
npm run watch
npm run grunt
grunt-patch-wordpress package has been updated to the latest version in all branches. It has also been added to the 3.7 and 3.8 branches where it was missing.
More information on these changes can also be found in #52341 on Trac.
Local Docker environment
Since WordPress 5.3, a local Docker environment configuration has been included in
wordpress-develop to provide an easy way for contributors to configure their own development environment and serve as a more consistent testing environment (mainly for Core’s PHPUnit tests). This environment has also been used for all automated testing in branches 5.3 and newer since being introduced.
However, because of the blockers detailed above, this environment could not be backported to the 3.7-4.5 branches.
After those blockers were resolved, the local Docker environment was then merged into older branches in [50243-50251] ensuring all branches receiving security updates can use the Docker environment.
Note: PHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher 5.2 is not currently included in the testing workflows for older branches that supported this version. Adding this for true parity with the old TravisCI testing configuration is blocked by the local Docker environment’s PHP 5.2 PHPUnit image not containing the correct version of PHPUnit.
For more information on this, see #48301 (and the previous #47767) on Trac.
Transitioning to GitHub Actions for automated testing
If you’re unfamiliar with the ongoing transition moving all automated testing from TravisCI/Appveyor to GitHub Actions, the initiative introduction and follow-up posts will help bring you up to speed. This transition has been continuing, and is nearing completion.
As of , automated testing has been restored for all branches still receiving security updates as a courtesy. This includes (where supported) PHPUnit testing, NPM testing, JSHint/PHPCS PHP Code Sniffer, a popular tool for analyzing code quality. The WordPress Coding Standards rely on PHPCS. linting, QUnit testing, and PHPCompatibility scanning.
In addition to restoring automated testing to branches receiving security updates, there have been a number of performance improvements to the workflows. Most notably, this has resulted in a roughly 70% total decrease in overall runtime for the PHPUnit test workflow.
Here are some additional changes related to GitHub Actions.
Note: All of the changes and improvements listed below have been backported through the 3.7 branch unless otherwise noted.
Limiting when workflows run
Because there are over 750 forks of the wordpress-develop mirror, it’s important to limit when workflows run appropriately. For private repositories, owners are given an allotment of free workflow minutes and are then charged for every minute used over that number. If no limitations are added, each workflow would run on every push event for every fork, including any additional public or private mirrors that are maintained. This would not only waste resources (running for every push to a fork is not necessary as most people open a pull request anyway), but could also unintentionally exhaust a user’s or organization’s private workflow minutes.
To help with this, all workflows have been updated to run only under the following conditions:
- Every push event to
wordpress-develop for the primary branch, branches
>= 3.7, and all tags matching the pattern
x.y.z that is
- Every pull request to
wordpress-develop with the primary branch or branches
>= 3.7 as the base.
- Every pull request to a fork or private mirror repository with the primary branch or branches
>= 3.7 as the base.
package.json, etc.) are changed.
These conditions will help limit the number of workflow runs that occur throughout the contributor base without limiting the ability to test and verify changes.
For more information on these changes, see #52643 and #52667 on Trac.
Regular testing of old branches
In TravisCI, there was a feature to configure regular testing of a repository’s branches at given intervals. This was used to run the test suite for:
- The currently maintained branch daily when there has not been a successful build in the last 24 hours.
- The previous branch weekly when there has not been a successful build in the last 24 hours.
- All other branches receiving security updates monthly when there has not been a successful build in the last 24 hours.
There is a
schedule event for triggering workflows in GitHub Actions, but it only runs in the primary branch of a repository, so it cannot be used at the workflow level to ensure regular testing of branches.
Instead, a new workflow has been introduced that will run on a schedule and initiate all of the necessary workflows for old branches using the REST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. to trigger a
workflow_dispatch event. This workflow will test the two most recent branches twice per month, and all other branches monthly.
For more information on this, see #52653 on Trac.
Code coverage reporting
Generating a code coverage report for the code base has been supported for some time (see ). But, reports have never been generated and aggregated on a regular basis. To correct this, a new workflow has been introduced to run a test coverage report daily (see ).
The reports generated are now submitted to Codecov and can be viewed here.
This will hopefully give contributors interested in test coverage the ability to find areas of the code base with little to no testing, and provide some insight into how code coverage increases or decreases over time.
Note: The code coverage will only be reported for the primary branch.
For more information, see #52034 on Trac.
Additional improvements to GitHub Actions workflows
- The NPM testing workflow has been generalized to not only verify the build tools work on Windows, but Linux and MacOS as well. Steps have also been added to test additional scripts, such as
npm run build:dev and
npm run grunt clean (see #52658).
fail-fast option has been disabled for the NPM (see ) and PHPUnit (see #52612) testing workflows.
fail-fast is great for being alerted of a failure faster, but does not give the full picture of what conditions cause the failure.
- The method of installing dependencies by use of
npx install-changed has been replaced with using
npm ci after comparisons found the latter was more performant (see #52660).
restore-keys options for the
actions/cache action have been removed in order to prevent the cache from snowballing due to lax cache key matching. This resulted in a 40% decrease in the NPM dependency cache size (see #52660).
restapi-jsclient test group is no longer run separately. This group was never excluded in the
phpunit.xml.dist file, so it already runs as part of the main test suite (see #52608).
- The single site and multisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site tests have been split into separate jobs that run in parallel. This has reduced the overall runtime for the PHPUnit workflow by over approximately 30% from the previous run (see #52548).
- Because the test suite takes significantly longer to run on PHP <= 5.6, the PHPUnit workflow has been updated to run test groups that are considered slow (
external-http) in separate, parallel jobs. This reduced the overall time for the workflow by 34% from the previous run (see #52645).
Known transition steps remaining (updated)
The following items remain to achieve parity with the previous testing configurations on TravisCI.
- Add and configure Slack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. notifications. In addition to sending the results of the whole build of a core commit into #core, we may also want to consider a firehose channel for PRs. This may require all workflows to be combined into a single workflow if needed middleware cannot be found.
- Move to GitHub badges for build status indicators – note that these are per-workflow, which is different from the single badge for the entire Travis build for a given commit. However, GitHub does report an overall status for a commit/PR, so we may be able to use that information as well. It seems that the expectation in the greater developer community is that projects report status with a singular badge. Like the Slack notifications, this may require the workflows to be combined in the absence of middleware.
Backport A port is when code from one branch (or trunk) is merged into another branch or trunk. Some changes in WordPress point releases are the result of backporting code from trunk to the release branch. the workflow files to unsupported older branches receiving security updates. Finish backporting the local Docker environment to branches 3.7-4.5. This is blocked by:
- wpdev-docker-images#46, which aims to fix the PHP 5.2 PHPUnit image to include the requred version of PHPUnit (3.6).
WP branches <= 4.5 are running a version of NodeJS that is too old for the needed NPM packages required to run the local Docker environment. Report test results to the Host Test Results page. Completed, but the MySQL MySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. version being tested is not currently being reported (see phpunit-test-runner#135).
Running tests from
Since the build process was overhauled in WordPress 5.1 (see #43309), automated testing has been running from the
build directory. Running from
build introduces several problems that makes contributing difficult:
- Running a build is slow. It copies all the files and builds, validates, and minifies all the CSS and JS. None of this should be necessary for PHP testing.
- Developing with
grunt watch can give issues on some development environments that run in VirtualBox (like VVV), where changes aren’t being picked up. Having to rebuild manually after each change is a hassle.
- A developer iterating on a patch in the source file has no way of knowing that their file is not actually being tested when running the tests, unless they run the build each time or start and run the file watcher. This is an easy step to forget.
- PHP errors display a stack trace from
- Breakpoint debugging isn’t fun as it also uses the stack trace from
build instead of
The build process was adjusted to allow building and cleaning
src again in #44492, but the default directory for automated testing remained
build because of some unit test Code written to test a small piece of code or functionality within a larger application. Everything from themes to WordPress core have a series of unit tests. Also see regression. failures.
The remaining items blocking the PHPUnit test suite from running against the
src directory have been fixed in  and the default branch for testing has been switched back to
src. The PHPUnit testing workflow has also been updated to run the Core test suite from the
src directory. This change resulted in an approximately 28% decrease in the workflow’s overall run time from the previous run.
Note: This change has only been merged back to the 5.2-5.7 branches, as this was where it seemed reasonable to draw the line for this change when weighing effort vs. benefits.
For more information on this change, see #51734 on Trac. Related tickets: #43055, #44492, #45863.
Additional changes of note
Here are some other, additional build/test tool changes to make note of:
- The Docker-based local environment now installs the WordPress Importer plugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party into the
tests/phpunit/data/plugins directory as part of the
npm run env:install script. This eliminates the extra step required when running the unit test suite locally (see #49720).
- MariaDB support has been added to the local Docker environment. To substitute MySQL for MariaDB, change the values of the
mariadb and a valid MariaDB version in the
.env file, in your local CLI Command Line Interface. Terminal (Bash) in Mac, Command Prompt in Windows, or WP-CLI for WordPress. configuration file (such as
bashrc), or by setting the variable’s value in your session (see #51744).
- The deprecated
node-sass package has been substituted with the recommended replacement, DartSass (
svn:ignore properties have been synchronized with the
.gitignore file. These SVN Subversion, the popular version control system (VCS) by the Apache project, used by WordPress to manage changes to its codebase. properties had fallen out of date, and several exclusions defined for contributors using Git Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git is easy to learn and has a tiny footprint with lightning fast performance. Most modern plugin and theme development is being done with this version control system. https://git-scm.com/. were not defined for those using SVN (see #49784).
Unmaintained branches and build/test tools going forwards
Even though these changes were merged all they through the 3.7, WordPress’ official stance continues to be that only the most recent release (5.7 at the time of this post) should be considered supported. The 3.7-5.6 branches will continue to only receive security fixes going forward (though there have recently been discussions about reducing the number of versions receiving security updates).
The changes above were merged into older branches because they were necessary to restore automated testing, or to maintain consistency in testing configurations across branches.
As changes are made to build/test tool areas of the code base going forward, component maintainers will use their judgement in determining which changes should be backported to these older branches. Changes can be grouped and backported as necessary. To start, reviewing these quarterly or after each major release A release, identified by the first two numbers (3.6), which is the focus of a full release cycle and feature development. WordPress uses decimaling count for major release versions, so 2.8, 2.9, 3.0, and 3.1 are sequential and comparable in scope. can be used as the frequency.
Immense props go out to @johnbillion. Almost all of the performance related changes detailed above were his ideas and contributions. Props to @jorbin, @davidbaumwald, and @sergeybiryukov for peer review.