Build: Fail plugin ZIP build when untracked files would be included - #2567
Conversation
When zipping a plugin, stray files left in the plugin source directory get copied into the build output and silently bundled into the archive. This makes it easy to ship files that were never meant to be part of a release. Before creating the archive, check the plugin source directory for files that Git considers untracked (and are not ignored via .gitignore), narrowed to those that actually made it into the build output — i.e. files not excluded by the copy step's ignore patterns. If any are found, fail the build with a message listing them. Generated build artifacts are unaffected because they are either committed or gitignored. The check can be bypassed with `--env force=true` for cases where including untracked files is intentional. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
The `build-plugins:zip` script wraps `build:plugin:*` via `npm-run-all`, which
did not pass extra command-line arguments through to the matched scripts. As a
result there was no way to reach the whole-suite zip build with the new
`--env force=true` override.
Add npm-run-all's `{@}` argument placeholder (and the required trailing `--`)
so arguments after `--` are forwarded to each plugin build. This makes
`npm run build-plugins:zip -- --env force=true` bypass the untracked-files
check across all plugins, while `npm run build-plugins:zip` continues to work
unchanged when no arguments are given.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## fix/preserve-zip-mtime-when-unchanged #2567 +/- ##
========================================================================
Coverage ? 70.38%
========================================================================
Files ? 91
Lines ? 7850
Branches ? 0
========================================================================
Hits ? 5525
Misses ? 2325
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|

Summary
Make the plugin ZIP build fail when untracked files would be included in the archive, since stray files left in a plugin source directory otherwise get silently bundled into a release. The check can be overridden with
--env force=true.Note
This is stacked on top of #2566 and targets that branch to keep the diff focused. GitHub will automatically retarget it to
trunkonce #2566 merges.Personal note: This addresses another pain point I've had with creating ZIPs for testing. Often I find out extra files were accidentally included, and that just makes things messy. This prevents that from happening.
Relevant technical choices
When zipping a plugin, files left in the plugin source directory get copied into the build output and bundled into the archive. It's easy to accidentally ship files that were never meant to be part of a release.
createPluginZip()now checks the plugin source directory before creating the archive:git ls-files --others --exclude-standardonplugins/<slug>to list files that Git considers untracked and not gitignored.build/<slug>/…), so files excluded by the copy step'signorepatterns (e.g.tests/,docs/,*.cache) don't trigger a false positive.Generated build artifacts (minified assets,
web-vitals.js,*.asset.php, etc.) are unaffected because they're either committed to the repo or gitignored — neither shows up as untracked.The check is bypassable with
--env force=truefor the rare case where including untracked files is intentional.Overriding the check
The
forceflag is a webpack--envvalue, so it must be passed after--— otherwise npm consumes the flag and never forwards it to the build:The
--after the script name is required by npm to forward arguments to the script;npm run build-plugins:zip --env force=true(without--) will not work.The
build-plugins:zipscript also had to be updated to forward these arguments throughnpm-run-allto eachbuild:plugin:*build (via the{@}argument placeholder). Without that change there was no way to pass--env force=trueto the whole-suite build.npm run build-plugins:zipwith no arguments continues to work unchanged.Verified manually:
--env force=true→ succeeds and includes the file.tests/) → build succeeds (not included, not flagged).npm run build-plugins:zip -- --env force=true→ forwardsforceto all plugin builds and succeeds;npm run build-plugins:zipwith no arguments still builds/zips as before.Use of AI Tools
This PR was authored with the assistance of Claude Code (Opus 4.8). The approach, implementation, and commit/PR text were AI-generated based on my direction, and I reviewed and verified the changes (including the manual build tests above).
🤖 Generated with Claude Code