Make .distignore the single source of truth for the release ZIP - #86
Merged
Conversation
.distignore and .gitattributes listed roughly the same paths (41 rules in common, two duplicated verbatim in .gitattributes) even though only the first one feeds the release ZIP: `wp dist-archive` reads .distignore and nothing else, while `export-ignore` shapes the source ZIP GitHub serves at archive/refs/heads/*.zip, the URL blueprint.json installs in Playground. Keeping them as mirrors hid two bugs, both found by diffing the built ZIP: - Unanchored rules match at any depth and case-insensitively, so `build`, `README.md`, `CHANGELOG.md` and `package.json` were stripping 16 files out of the bundled editor, among them dist/static/libs/yjs/build/ and dist/static/CHANGELOG.md. Root-only rules now carry a leading slash, the same fix the LICENSE.txt rule already documented. - test-results/ (Playwright output, gitignored) was shipping. .distignore also loses ~35 rules inherited from WordPress/plugin-check that match nothing here (plugin-check.iml, behat.yml, .gherkin-lintrc, phpstan.neon, /phpcs-sniffs/ and friends), keeping a deliberate block for the ones that must match at any depth. LICENSE.txt now ships. .gitattributes drops from 45 rules to 6 and states in its header that it does not feed the release: rules for untracked paths (node_modules/, vendor/, dist/, artifacts/) were noise, because git archive never sees them. Net effect on the package: +16 files inside dist/static/, +LICENSE.txt, -test-results/. ADR-0003 records the decision and SDD-0002 the cross-repository design, since wp-decker, wp-documentate and wp-autofirma carry the same two drifting files.
Contributor
Test in WordPress PlaygroundTest the plugin with the code from this branch:
|
This was referenced Aug 3, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #86 +/- ##
=========================================
Coverage 73.47% 73.47%
Complexity 848 848
=========================================
Files 42 42
Lines 4339 4339
=========================================
Hits 3188 3188
Misses 1151 1151
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
`wp dist-archive --force` does not truncate an existing archive. Version 3.1 shells out to the `zip` binary, which ADDS to one, so `--force` only bypasses the "file already exists" check. Proved with a controlled run: built with a rule excluding includes/, removed the rule and rebuilt over the same file (the 31 files appeared, as expected), then put the rule back and rebuilt over it again — the 31 files were still inside. A repeated `make package` at the same VERSION therefore keeps files that a new .distignore rule already excludes. CI starts from a clean checkout so releases were never affected, but it silently undermines any local verification of a packaging change.
check-editor-releases.yml calls `make package` but set up neither PHP nor Composer. That target needs the WP-CLI i18n command to build the runtime translations and the dist-archive command to build the ZIP, both of them in require-dev, so the Create package step failed outright whenever a new editor release appeared. Pre-existing; the steps mirror release.yml. Also corrects a stale comment on the PHPCS regression guard. It said checkout-index was used because .gitattributes export-ignored dotfiles including .phpcs.xml.dist, which stopped being true when the blanket `.*` rule went away. checkout-index is still the right tool, for a better reason: it writes the index verbatim with no export-ignore filtering, so the guard does not depend on whatever .gitattributes happens to exclude.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
.distignoreand.gitattributeslisted roughly the same paths — 41 rules in common, and two duplicated verbatim inside.gitattributes(README.md,phpunit.xml.dist) — even though they have different jobs:.distignoreis the only listwp dist-archivereads (vendor/wp-cli/dist-archive-command/src/Dist_Archive_Command.php:77-84), so it alone decides what ships..gitattributesexport-ignoreonly shapes the source ZIP GitHub serves atarchive/refs/heads/*.zip— the URLblueprint.jsoninstalls in Playground.Maintaining them as mirrors is wrong in both directions and hid two bugs.
Bugs fixed
1. Unanchored rules were eating the bundled editor.
wp dist-archivedelegates matching toinmarelibero/gitignore-checker, which compiles every rule with the regexiflag and matches at any depth. So the barebuild,README.md,CHANGELOG.mdandpackage.jsonrules reached insidedist/static/and silently stripped 16 files from the packaged editor. TheLICENSE.txtrule already carried a comment about this exact trap; now every root-only rule is anchored.2.
test-results/was shipping — Playwright output, gitignored, butdist-archivereads the working tree.Verification
Built the ZIP before and after and diffed the file lists (3910 → 3926 entries):
Nothing else changed.
make packageitself is untouched.Also in this PR
.distignoreloses ~35 rules inherited fromWordPress/plugin-checkthat match nothing here (plugin-check.iml,behat.yml,.gherkin-lintrc,phpstan.neon,/phpcs-sniffs/…), and keeps a deliberate block of rules that must match at any depth (.git,node_modules,.DS_Store,.idea,sftp-config.json).LICENSE.txtnow ships; it did not before..gitattributesgoes from 45 rules to 6. Rules for untracked paths (node_modules/,vendor/,dist/,artifacts/) were noise —git archivenever sees them.Context
wp-decker,wp-documentateandwp-autofirmacarry the same two drifting files, and two of them ship a ZIP with no top-level directory (WordPress then installs them asdecker-1.2.3/). ADR-0003 records the decision and SDD-0002 the cross-repository design; this is the first of four PRs and the only one that does not change the packaging command.Follow-up (not here)
ci.yml:127-128usesgit checkout-indexinstead ofgit archiveonly because the blanket.*rule hid.phpcs.xml.dist. That rule is gone, so the workaround can be revisited — left out to keep this PR to packaging.Añadido tras revisar la CI
check-editor-releases.ymlno instalaba PHP ni Composer y sin embargo llama amake package, que necesita el comando i18n de WP-CLI para las traducciones de runtime ydist-archivepara el ZIP, ambos enrequire-dev. El paso Create package fallaba en cuanto salía una versión nueva del editor. Es un fallo preexistente, no lo introduce esta PR; los pasos son los mismos que ya usarelease.yml.Comentario obsoleto en el guard de PHPCS. Decía que se usaba
checkout-indexporque.gitattributesexcluía los dotfiles, incluido.phpcs.xml.dist— dejó de ser cierto al desaparecer la regla.*.checkout-indexsigue siendo lo correcto, pero por una razón mejor: escribe el índice tal cual, sin filtrar porexport-ignore, así que el guard no depende de lo que.gitattributesexcluya en cada momento.rm -fantes de archivar, porque--forceno vacía el ZIP anterior (ver el commit correspondiente).