Skip to content

Pin exact versions for all npm dependencies#11932

Open
desrosj wants to merge 5 commits into
WordPress:trunkfrom
desrosj:pin-specific-versions-of-npm-packages
Open

Pin exact versions for all npm dependencies#11932
desrosj wants to merge 5 commits into
WordPress:trunkfrom
desrosj:pin-specific-versions-of-npm-packages

Conversation

@desrosj

@desrosj desrosj commented May 22, 2026

Copy link
Copy Markdown
Member

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.lock file

Removing 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.lock file to version control ensuring that composer install does not install untested and unverified versions of dependencies.

A config.platform.php version of 7.4 has 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.

@desrosj desrosj self-assigned this May 22, 2026
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The 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

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@desrosj desrosj force-pushed the pin-specific-versions-of-npm-packages branch from 7b62c73 to 5b4e1b6 Compare May 22, 2026 19:39
@desrosj desrosj force-pushed the pin-specific-versions-of-npm-packages branch from e28fbab to cb62c24 Compare June 23, 2026 01:05
@desrosj desrosj marked this pull request as ready for review June 23, 2026 01:25
@desrosj desrosj requested review from Copilot and westonruter June 23, 2026 01:26
@github-actions

github-actions Bot commented Jun 23, 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.

Core Committers: Use this line as a base for the props when committing in SVN:

Props desrosj, jorbin, mamaduka, gziolo, youknowriad, manzoorwanijk.

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.json accordingly.
  • Commit a new composer.lock and adjust composer.json config to support lockfile usage.
  • Update test/bootstrap tooling and CI workflow comments/messages to reference composer install instead of composer 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.

Comment thread tests/phpunit/includes/bootstrap.php Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Mamaduka

Copy link
Copy Markdown
Member

@manzoorwanijk has been working on something similar for the Gutenberg project; I'm sure they'll have more insights to share.

@gziolo

gziolo commented Jun 23, 2026

Copy link
Copy Markdown
Member

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.

@youknowriad

Copy link
Copy Markdown
Contributor

The goal behind this change is to help guard against supply chain attacks where a vulnerable package may be installed unintentionally and unknowingly.

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.

@gziolo

gziolo commented Jun 23, 2026

Copy link
Copy Markdown
Member

@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.

@manzoorwanijk

Copy link
Copy Markdown
Member

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 npm update.

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.

@youknowriad

Copy link
Copy Markdown
Contributor

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).

@aaronjorbin

Copy link
Copy Markdown
Member

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 absolutely agree. I think that can be a follow up, but I do see it as important.

@gziolo gziolo removed their request for review June 24, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants