Skip to content

package.sh: explicit allow-list of shipped paths instead of deny-list#91

Merged
epeicher merged 1 commit intotrunkfrom
fix/package-allow-list
May 6, 2026
Merged

package.sh: explicit allow-list of shipped paths instead of deny-list#91
epeicher merged 1 commit intotrunkfrom
fix/package-allow-list

Conversation

@epeicher
Copy link
Copy Markdown
Collaborator

@epeicher epeicher commented May 6, 2026

Summary

bin/package.sh was running git archive HEAD over the whole repo and relying on .gitattributes export-ignore rules to keep dev-only content out of the zip. That model is opt-out: anything new committed at the repo root ships by default unless someone remembers to update .gitattributes. That's how the stray script(1) recording from #77 ended up inside desktop-mode.zip (fixed in #90).

This PR flips the model. bin/package.sh now ships only the explicit allow-list:

  • desktop-mode.php
  • readme.txt
  • LICENSE
  • README.md
  • assets/
  • includes/
  • languages/

Anything else tracked in the repo — build config, tests, docs, dev tooling, accidental root-level files — is excluded by default. Adding a new top-level path to a release now requires consciously appending it to the include array in the script.

The script also runs git cat-file -e against each allow-listed path up front so a typo or removed-but-not-updated entry fails the package step instead of silently producing an incomplete zip.

.gitattributes deny-list rules stay in place as a second layer (in case someone runs git archive HEAD directly, or to exclude individual files within an allow-listed directory). The header comment is updated to reflect the new layered model.

Verification

Local run, before this change:

$ unzip -l desktop-mode.zip | awk '{print $4}' | grep -E '^desktop-mode/[^/]+/?$'
desktop-mode/LICENSE
desktop-mode/README.md
desktop-mode/assets/
desktop-mode/desktop-mode.php
desktop-mode/includes/
desktop-mode/languages/
desktop-mode/readme.txt
desktop-mode/typescript    ← stray script(1) recording

After this change:

$ unzip -l desktop-mode.zip | awk '{print $4}' | grep -E '^desktop-mode/[^/]+/?$'
desktop-mode/LICENSE
desktop-mode/README.md
desktop-mode/assets/
desktop-mode/desktop-mode.php
desktop-mode/includes/
desktop-mode/languages/
desktop-mode/readme.txt

All 6 Vite-built bundles + 2 hand-written assets/js/*.js files still get spliced in correctly.

Test plan

  • Run npm run package and confirm only the 7 top-level entries above appear.
  • Confirm the built JS bundles (assets/js/{desktop,iframe-bridge,recycle-bin}{,.min}.js) and the hand-written ones (admin-bar.js, media-library-enhanced.js) are inside the zip.
  • Touch a file at the repo root (e.g. git add foo.txt && git commit), re-run npm run package, confirm foo.txt is NOT in the zip.
  • Temporarily add a non-existent path to the include array and confirm the script errors out instead of silently producing an incomplete zip.
  • Cut a release end-to-end via bin/release.sh once merged, confirm the published zip matches expectations.

Relationship to #90

#90 removes the existing stray typescript file and gitignores the script(1) default name. This PR is the structural follow-up: even if a future stray file slips past .gitignore and gets committed, it can no longer end up in a release zip without someone explicitly allow-listing it.

Open WordPress Playground Preview

Previously bin/package.sh ran `git archive HEAD` over the whole repo
and relied on `.gitattributes` `export-ignore` rules to keep dev-only
content out. Two problems:

1. Anything new committed at the repo root shipped by default unless
   someone remembered to add it to `.gitattributes` first. That's how
   the stray `script(1)` recording from #77 ended up in the zip.

2. The mental model was inverted — opt-out, not opt-in — which is the
   wrong default for release artifacts.

Now `bin/package.sh` ships only the explicit allow-list:

    desktop-mode.php, readme.txt, LICENSE, README.md,
    assets/, includes/, languages/

Anything else tracked in the repo (build config, tests, docs, dev
tooling, stray editor recordings, …) is excluded by default. Adding a
new top-level path to a release means consciously appending it to the
`include` array.

The script also `git cat-file -e`-checks each entry up front so a typo
or a removed-but-not-updated path fails the package step rather than
producing a silently-incomplete zip.

`.gitattributes` deny-list rules stay in place as a second layer — both
in case someone runs `git archive HEAD` directly, and to handle paths
inside an allow-listed directory that still shouldn't ship.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@epeicher epeicher merged commit 96a204e into trunk May 6, 2026
5 checks passed
@epeicher epeicher deleted the fix/package-allow-list branch May 6, 2026 09:03
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.

1 participant