Pin exact versions for all npm dependencies#11932
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
7b62c73 to
5b4e1b6
Compare
e28fbab to
cb62c24
Compare
|
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 Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Pull request overview
This PR tightens dependency determinism in the WordPress develop repo by pinning previously ranged npm/Composer dependencies and reintroducing a committed composer.lock, along with updating related tooling/messages to reference composer install.
Changes:
- Replace version ranges with exact versions for several npm and Composer dev dependencies and update
package-lock.jsonaccordingly. - Commit a new
composer.lockand adjustcomposer.jsonconfig to support lockfile usage. - Update test/bootstrap tooling and CI workflow comments/messages to reference
composer installinstead ofcomposer update.
Reviewed changes
Copilot reviewed 11 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/phpunit/includes/bootstrap.php | Updates guidance/error output to use composer install for installing Polyfills/deps. |
| package.json | Pins previously ranged devDependency versions to exact values. |
| package-lock.json | Updates lockfile to reflect newly pinned npm devDependency versions. |
| Gruntfile.js | Updates certificate bundle upgrade preflight messaging to reference composer install. |
| composer.lock | Adds committed lockfile to pin Composer dependency graph. |
| composer.json | Pins Composer dev dependency versions and updates Composer config for lockfile/platform behavior. |
| .gitignore | Stops ignoring composer.lock so it can be committed. |
| .github/workflows/reusable-test-local-docker-environment-v1.yml | Updates workflow comment to remove outdated lockfile rationale. |
| .github/workflows/reusable-test-core-build-process.yml | Updates workflow comment to remove outdated lockfile rationale. |
| .github/workflows/reusable-phpunit-tests-v3.yml | Updates workflow comment to remove outdated lockfile rationale. |
| .github/workflows/reusable-phpstan-static-analysis-v1.yml | Updates workflow comment to remove outdated lockfile rationale. |
| .github/workflows/reusable-php-compatibility.yml | Updates workflow comment to remove outdated lockfile rationale. |
| .github/workflows/reusable-coding-standards-php.yml | Updates workflow comment to remove outdated lockfile rationale. |
| .github/workflows/reusable-check-built-files.yml | Updates workflow comment to remove outdated lockfile rationale. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@manzoorwanijk has been working on something similar for the Gutenberg project; I'm sure they'll have more insights to share. |
|
Good call. It would also make sense to introduce a CI check that ensures tooling doesn't accidentally bump the package version to ranges again. From my experience with Gutenberg, it's very likely to happen very soon. |
I thought the lock file already ensured that we don't install untested packages, regardless of whether the version is fixed or defined as a range in package.json. Only when updating packages or installing new ones explicitly, the lock file is updated with new versions. Also my understanding is that even if the version of a package is fixed in package.json, the transitive versions of its dependencies are not, which means installing/updating other packages may have the side effect of changing the versions of the first package's dependencies. In other words, I believe fixing package.json versions has very little effect and the real protection is the lock file. Now, it's possible that my understanding is wrong and please correct me if it is. |
|
@youknowriad, there was no lock file for the Composer dependencies. In npm, ranges allow a dependency to move. Dedup during a tree rebuild is what may actually move it, and only when overlapping ranges can be reconciled. The lockfile holds everything stable until a rebuild happens. Pinning anchors one direct dep against those bumps, but doesn't reach transitives — overrides do that. |
|
As @youknowriad correctly pointed out, in npm, the lockfile is the source of truth for installed packages. The version of a dependency shifts to the latest version that satisfies the range only if it's not already in the lockfile or if someone runs This kind of pinned version is fine for end-user applications (which do not publish packages to npm), and this repo is one. The reason is that published packages (e.g., in Gutenberg) should support version ranges rather than pinned versions to ensure that consumer applications receive security updates when needed. |
|
Yeah composer lock addition seems like a good thing. Pinning versions of package.json though seems unnecessary to me (nor good or bad, it just doesn't change anything for the project really). |
I absolutely agree. I think that can be a follow up, but I do see it as important. |
This attempts to pin versions of npm and Composer dependencies to ensure every update to a dependency (both direct and transitive) is intentional.
The goal behind this change is to help guard against supply chain attacks where a vulnerable package may be installed unintentionally and unknowingly.
Reintroduce
composer.lockfileRemoving version ranges in favor of explicitly pinning specific versions is straightforward and does not result in any meaningful change today provided a lock file is present. However, lock file generation for Composer has been disabled in this repository since WP 6.7 (see Core-61530/r59082).
This PR proposes re-enabling lock file generation and committing the
composer.lockfile to version control ensuring thatcomposer installdoes not install untested and unverified versions of dependencies.A
config.platform.phpversion of7.4has been configured to ensure that the dependencies installed are compatible in all instances where WordPress may be tested.Trac ticket: Core-64968.
Use of AI Tools
AI assistance: No
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.