Skip to content

Install the portability audit as a command; publish an allowlist of files - #59

Merged
jameskfry merged 2 commits into
mainfrom
feat/portability-audit-bin
Oct 8, 2026
Merged

jameskfry merged 2 commits into
mainfrom
feat/portability-audit-bin

Conversation

@jameskfry

Copy link
Copy Markdown
Owner

Summary

The portability audit becomes a command of the package, so people who install expression-language can run it on their own expressions without cloning the repo:

npm install --save-dev expression-language
npx expression-language-portability --extract ./src ./config
npx expression-language-portability rules.txt --fail-on ordinary   # exit 1 in CI

It audits the version of the package it comes with (the default --lib is the lib/ next to the script).

What changed

  • scripts/portability-audit.{cjs,php} moved to bin/, with a bin entry in package.json. scripts/ is repository tooling and stays unpublished. npm run portability still works from a checkout.

  • The tarball is now an allowlist (files in package.json; .npmignore removed). Doing this properly turned up that the old denylist published more than it should:

    3.0.0-beta.1 / before now
    files 183 62
    tarball 602 KB 286 KB
    contained .github/ (CI + release workflows), rollup.config.mjs, jest-reporter.cjs, tsconfig.json, .babelrc, examples/, and the compiled tests (lib/__tests__, 41 files) lib, dist, bin, CHANGELOG.md, UPGRADE-*.md (+ README, LICENSE, package.json, which npm always includes)

    The beta published from CI's clean checkout, so it did not leak anything sensitive. But packing from a working copy would also have shipped its coverage/ report (70 files, 1.8 MB) and .claude/ editor settings, because those are git-ignored but not npm-ignored. An allowlist makes that impossible rather than relying on remembering to list it.

  • scripts/check-package.cjs (npm run test:package, now a step of the CI build job) goes through npm pack like a user would: checks what's in the tarball (required files present, tooling/coverage/tests absent, every bin target shipped), installs the tarball into a clean project, and runs the entry point, the minified bundle, and the command with its exit codes (--help, an audit, --fail-on → 1, no args → 2).

Verification

  • Installed from a packed tarball into a clean project: command linked into .bin, --help, audit, --fail-on, --extract, and the PHP cross-check (--php-symfony, 360/360 identical) all work from inside node_modules.
  • Negative control: with files temporarily regressed to publish coverage/ and the compiled tests, npm run test:package fails (2 checks) and exits non-zero.
  • npm test: 562 passed (4 new: bin entry, shebang + exec bit, helper alongside, default --lib); 157 with the PHP-backed tests; coverage, tsc --strict, builds + smoke, npm audit --omit=dev all clean.

Notes for review

  • This changes what gets published for every consumer (less, not more). Anything that deep-imported something now excluded would break: lib/** and dist/** are unchanged, only lib/**/__tests__, types/, examples/ and tooling are gone. types already points to dist/index.d.ts.
  • bin/portability-audit.cjs is committed executable (100755); npm also sets the bit on install.
  • The command is not yet in a release; it ships with the next one (this is the Unreleased section of the changelog).

🤖 Generated with Claude Code

jameskfry and others added 2 commits October 8, 2026 13:55
…of files

The audit becomes the `expression-language-portability` command of the
package (`npx expression-language-portability --extract src`), so people who
install the package can audit their own expressions without cloning the
repository. It audits the version of the package it comes with.

- scripts/portability-audit.{cjs,php} move to bin/ (scripts/ is repository
  tooling and is not published); package.json gets a `bin` entry.

The tarball is now an allowlist. `.npmignore` was a denylist, so whatever it did
not name was published: the CI workflows, build configuration, examples and the
compiled tests (lib/__tests__) were in the 3.0.0-beta.1 tarball, and packing
from a working copy also included its coverage report and local editor
settings. `files` in package.json names what is published (lib, dist, bin, the
changelog and upgrade guide) and replaces .npmignore: 62 files and 286 KB
instead of 183 files and 602 KB, and nothing else can end up in it.

scripts/check-package.cjs (`npm run test:package`, run by the CI build job)
packs the package, checks what is in the tarball, installs it into a clean
project and runs the entry point, the browser bundle and the command, with its
exit codes. It fails when coverage/ or the compiled tests are published again.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The command and the package contents ship in 3.0.0, so the changelog that is in
the tarball should not call them unreleased. Also notes the range operator and
the matches subject, which the release notes are made from.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@jameskfry
jameskfry merged commit f656b62 into main Oct 8, 2026
9 checks passed
@jameskfry
jameskfry deleted the feat/portability-audit-bin branch October 8, 2026 20:01
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