Skip to content

Build: Fail plugin ZIP build when untracked files would be included - #2567

Merged
westonruter merged 2 commits into
trunkfrom
fix/fail-zip-on-untracked-files
Jul 7, 2026
Merged

Build: Fail plugin ZIP build when untracked files would be included#2567
westonruter merged 2 commits into
trunkfrom
fix/fail-zip-on-untracked-files

Conversation

@westonruter

@westonruter westonruter commented Jul 3, 2026

Copy link
Copy Markdown
Member

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 trunk once #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:

  1. Runs git ls-files --others --exclude-standard on plugins/<slug> to list files that Git considers untracked and not gitignored.
  2. Narrows that list to files that actually made it into the build output (build/<slug>/…), so files excluded by the copy step's ignore patterns (e.g. tests/, docs/, *.cache) don't trigger a false positive.
  3. If any remain, the build fails with a message listing the offending files.

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=true for the rare case where including untracked files is intentional.

Overriding the check

The force flag is a webpack --env value, so it must be passed after -- — otherwise npm consumes the flag and never forwards it to the build:

# A single plugin:
npm run build:plugin:webp-uploads -- --env zip=true --env force=true

# The whole suite:
npm run build-plugins:zip -- --env force=true

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:zip script also had to be updated to forward these arguments through npm-run-all to each build:plugin:* build (via the {@} argument placeholder). Without that change there was no way to pass --env force=true to the whole-suite build. npm run build-plugins:zip with no arguments continues to work unchanged.

Verified manually:

  • Stray file in a plugin source root → build fails (non-zero exit) with the file listed.
  • Same build with --env force=true → succeeds and includes the file.
  • Stray file under an ignored path (tests/) → build succeeds (not included, not flagged).
  • Clean source → build succeeds.
  • npm run build-plugins:zip -- --env force=true → forwards force to all plugin builds and succeeds; npm run build-plugins:zip with 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

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>
@github-actions

github-actions Bot commented Jul 3, 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.

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

Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: b1ink0 <b1ink0@git.wordpress.org>

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

@westonruter westonruter added [Type] Enhancement A suggestion for improvement of an existing feature no milestone PRs that do not have a defined milestone for release skip changelog PRs that should not be mentioned in changelogs labels Jul 3, 2026
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>
@westonruter

Copy link
Copy Markdown
Member Author

Currently, I have an untracked file in auto-sizes:

$ git status plugins/auto-sizes/
On branch fix/fail-zip-on-untracked-files
Your branch is up to date with 'origin/fix/fail-zip-on-untracked-files'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        plugins/auto-sizes/bindtest.txt

nothing added to commit but untracked files present (use "git add" to track)

Running npm run build-plugins:zip -- --env force=true successfully fails when coming to that plugin:

image

@westonruter
westonruter requested a review from b1ink0 July 3, 2026 20:23
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (fix/preserve-zip-mtime-when-unchanged@c490437). Learn more about missing BASE report.

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           
Flag Coverage Δ
multisite 70.38% <ø> (?)
single 35.59% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@b1ink0 b1ink0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Base automatically changed from fix/preserve-zip-mtime-when-unchanged to trunk July 7, 2026 23:49
@westonruter
westonruter merged commit 34e535c into trunk Jul 7, 2026
31 checks passed
@westonruter
westonruter deleted the fix/fail-zip-on-untracked-files branch July 7, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no milestone PRs that do not have a defined milestone for release skip changelog PRs that should not be mentioned in changelogs [Type] Enhancement A suggestion for improvement of an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants