Thanks for considering a contribution. This is a small CLI — keep changes focused and the bar for "is this needed" high.
git clone https://github.com/lorenzopant/envdrift.git
cd envdrift
pnpm installPackage manager is pnpm — please don't commit package-lock.json or
yarn.lock.
pnpm dev [dir] # run the CLI against a directory without building
pnpm run build # build with tsup -> dist/
pnpm start [dir] # run the built CLI
pnpm run typecheck # tsc --noEmit
pnpm test # run the test suite (node:test, via tsx)CI runs typecheck, test, and build on every push/PR
(.github/workflows/ci.yml) — make sure they pass locally first. Also try
your changes against a real (or fixture) directory of .env* files; tests
cover the core logic but not the CLI's terminal output.
- TypeScript, ESM (
"type": "module"), no transpilation tricks. - No comments explaining what code does — only why, when the reasoning isn't obvious from the code itself.
- Compare env files by key only, never value — this is a hard rule (see
CLAUDE.md). Don't add anything that reads, logs, or writes secret values. - Keep the dependency list small. Justify any new dependency in your PR description.
If you add, remove, or change a flag, output format, or exit-code behavior,
update README.md (options table, example output, "How it works" section)
in the same PR. Stale docs are worse than no docs.
Publishing to npm is automated via .github/workflows/publish.yml, triggered
by publishing a GitHub Release. It uses npm's OIDC trusted publishing —
no NPM_TOKEN secret is stored in the repo.
Published as the scoped package @lorenzopant/envdrift (the unscoped
envdrift name is already taken by an unrelated publisher).
One-time setup (maintainers only, done on npmjs.com):
- Publish version
1.0.0manually once first (npm publish --access publicfrom a logged-in shell) — trusted publishers can only be linked to a package that already exists. - Go to the
@lorenzopant/envdriftpackage -> Settings -> Trusted Publisher. - Add a GitHub Actions publisher: repo
lorenzopant/envdrift, workflowpublish.yml, environment left blank (or set one and mirror it in the workflow'senvironment:key).
The only sanctioned way to cut a release is pnpm release <patch|minor|major>
(scripts/release.mjs, requires gh CLI authenticated). Don't hand-edit
version in package.json, tag manually, or draft releases by hand — the
script is the gate that keeps releases consistent end-to-end. It:
- Refuses on a dirty working tree or any branch other than
main. - Runs
typecheck,test, andbuild— aborts on the first failure. - Bumps the version with
npm version <bump>, committing aschore: release vX.Y.Z 🚀and creating the tag. - Pushes the commit and tag.
- Creates the GitHub Release with
gh release create --generate-notes(auto-generated changelog from merged PRs/commits since the last tag).
Publishing the release triggers publish.yml, which builds and runs
npm publish --provenance — fully automated from pnpm release onward.
- Keep commits focused; one logical change per commit.
- PR description should explain why, not just what — link to an issue if one exists.
- Be ready to discuss trade-offs; this is a young project and design isn't fully settled.
Open a GitHub issue. Include:
- What you expected vs. what happened
- Repro steps (a minimal
.env*fixture helps a lot) - envdrift version (
envdrift --version) and Node version
By participating, you agree to abide by the Code of Conduct.