Thanks for helping improve envra. Small fixes and large refactors are welcome.
Requirements: Node 18+, pnpm 9.
pnpm install
pnpm build
pnpm testpackages/core— schema, validation, generators, doctor helperspackages/cli—envrabinary (Commander + jiti)packages/next—defineNextEnvpackages/eslint-plugin—no-process-env
- Open an issue first if the change is large or API-shaping.
- Keep commits focused; match existing style (TypeScript, minimal comments).
- Add or update tests when behavior or public API changes.
- Ensure
pnpm buildandpnpm testpass locally.
Before pushing a release or opening the version PR:
pnpm installpnpm build(orpnpm run buildfrom repo root)pnpm test- From
packages/cli, runpnpm packand confirmpackage/package.jsonin the tarball lists a real semver for@envra/core(notworkspace:*).
We use Changesets for versioning and npm releases of @envra/*.
We do not use NPM_TOKEN in GitHub Actions. Releases use npm Trusted Publishing: short-lived OIDC from GitHub-hosted runners, no long-lived publish token in secrets.
Requirements (from npm): npm CLI ≥ 11.5.1, Node ≥ 22.14. The Release workflow pins a new enough npm globally after setup-node.
Trusted Publisher is configured per package on npm, but the link is to one GitHub repo + one workflow file (release.yml). For this repo you repeat the same publisher setup for each published package:
| Package | On npm → Package → Settings → Trusted publishing |
|---|---|
@envra/core |
GitHub: hasansmadix/envra, workflow release.yml |
@envra/cli |
same |
@envra/next |
same |
@envra/eslint-plugin |
same |
All must live under an npm org/user that allows those publishes. The workflow filename must match exactly (e.g. release.yml, case-sensitive).
The Release job needs:
id-token: write— OIDC for npm (no token secret).contents: writeandpull-requests: write— required by Changesets to open/update the “Version packages” PR and push version bumps.
Using onlycontents: readwould break that flow.
After Trusted Publishing works, npm recommends restricting classic publish tokens for those packages. See npm docs: Publishing access → require 2FA / disallow tokens where appropriate.
- After meaningful changes:
pnpm changeset— select affected@envra/*packages and semver bump (patch/minor/major), write a summary. - Commit and push the new file under
.changeset/. - Merge to
main. The Release action opens or updates the Version packages PR; when that merges, the next run runspnpm release(pnpm buildthenchangeset publish) using OIDC.
If packages are not on the registry yet, you may need a one-time authenticated publish (npm login or a disposable token) so the packages exist; then attach Trusted Publishers on each package and switch fully to CI. Alternatively follow npm’s current UI for empty packages + trusted publisher.
After the first successful CI publish, prefer Changesets + Release workflow only.
From a clean main, with local npm login (or token) and builds done:
pnpm build
pnpm exec changeset publishPrefer the GitHub Action so versions and git tags stay aligned with changelogs.
warn Received 404 for npm info "@envra/..."
Often normal: Changesets checks whether the new version (e.g. 0.1.1) is already on the registry; until it is published, that can return 404. Your previous release (e.g. 0.1.0) can still be live — verify with:
npm view @envra/core versionpackages failed to publish with no npm error
Changesets does not always print npm’s stderr. Run one package to see the real code:
pnpm build
pnpm --filter @envra/core publish --access public --no-git-checksnpm error code EOTP (most common after 0.1.0 works)
Your npm account uses 2FA for publishing. Non-interactive changeset publish cannot prompt for an OTP.
- Quick: publish with a fresh code from your authenticator:
pnpm --filter @envra/core publish --access public --no-git-checks --otp=123456
(repeat for other packages in order: core → cli, next, eslint-plugin — or use an Automation token below and runpnpm exec changeset publishonce.) - Better for repeated CLI publishes: create an Automation granular access token (publish-capable, no OTP), then
npm loginor set in user.npmrc:
//registry.npmjs.org/:_authToken=npm_yourTokenHere
GitHub Actions releases use Trusted Publishing (OIDC) and do not need this OTP when OIDC is configured on each package.
ENEEDAUTH: workflow file name on npm must match.github/workflows/release.ymlexactly; repo slug must match; use GitHub-hosted runners.workflow_call/ reusable workflows: npm validates the caller workflow name — avoid indirect publish flows that confuse that check (see npm troubleshooting).- Private GitHub repo: trusted publishing can still publish public packages, but npm may not generate provenance (npm documents this limitation).
Please be respectful. For reporting security issues, see SECURITY.md.