fix(cli): generate .env and .env.example files during init#1281
Conversation
🦋 Changeset detectedLatest commit: 98e634f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
arkenv
@arkenv/build
@arkenv/bun-plugin
@arkenv/cli
@arkenv/fumadocs-ui
@arkenv/nextjs
@arkenv/nuxt
@arkenv/vite-plugin
commit: |
📦 Bundle Size Report✅ All size limits passed! |
… and add gitignore checks
There was a problem hiding this comment.
Important
Copying the full contents of .env into .env.example in existing projects risks leaking secret values into a file that is commonly committed.
Reviewed changes — This PR makes arkenv init generate .env and .env.example so scaffolded projects boot without a missing-env crash.
- Mirror existing env files —
InitUseCase.collectExistingProject()now reads any existing.env/.env.exampleand passes their contents intoProjectOptions. - Add default env values —
planner.tsadds per-example defaults for new projects and framework/keyed defaults for existing projects, then plans creation of missing env files. - Add planner tests —
planner.test.tscovers new-project defaults, key-derived existing-project defaults, and copying a single existing file to its missing counterpart.
⚠️ New-project env files can overwrite templates from the cloned example
In mode === "new", .env and .env.example are unconditionally added to plan.files. The executor clones the example first and then writes every planned file, so any .env / .env.example that ships inside the example repository will be overwritten. The current registry examples do not ship env files, so this is not a live bug, but it conflicts with the PR's stated intent of "generate if they don't already exist."
Technical details
# New-project env files can overwrite templates from the cloned example
## Affected sites
- `packages/cli/src/features/scaffold/planner.ts:199-224` — new-mode env files are always pushed to `plan.files`, independent of what the cloned example contains.
## Required outcome
- New-project scaffolding should not overwrite `.env` or `.env.example` files that already exist after the example is cloned.
## Suggested approach
- Either collect `existingFiles` from the cloned target directory before calling `createPlan`, or have the executor skip `plan.files` whose paths already exist when the action is `"create"`.Kimi K2 (free via Pullfrog for OSS) | 𝕏
01b0718 to
20bf113
Compare
Pullfrog Review Update:
|
There was a problem hiding this comment.
Important
The latest commit fixes the prior secret-leak concern but introduces regressions in planner.test.ts. The new-project template-overwrite concern from the previous review is unchanged.
Reviewed changes — The latest commit strips values when mirroring .env to .env.example and adds .gitignore checks for existing projects.
- Added
stripValuesFromEnvContentinplanner.tsto remove values from existing.envcontent before copying to.env.example, resolving the prior secret-leak concern. - Added gitignore handling in
planner.tsfor existing projects—creating.gitignorewhen missing or appending.env/.env.localrules when absent. init.tsnow reads the existing.gitignoreand passesgitignoreContentintoProjectOptions.- Added tests for value stripping, gitignore creation, gitignore append, and no-op when
.envis already ignored. - The new-project env-template overwrite concern flagged in the prior review remains unaddressed (no code changes in that path).
⚠️ Existing planner tests fail because of the new gitignore logic
defaultState includes .env and .env.example but not .gitignore. In existing-project mode this now causes a .gitignore file to be appended to the plan, so three existing assertions on plan.files.length fail. Add /test/.gitignore to defaultState.existingFiles (or update the affected length assertions) so the unrelated gitignore behavior is not asserted implicitly by every existing test.
Technical details
# Existing planner tests fail because of the new gitignore logic
## Affected sites
- `packages/cli/src/features/scaffold/planner.test.ts:21` — `defaultState.existingFiles` lacks `.gitignore`, causing unexpected plan entries in existing-project tests.
- `packages/cli/src/features/scaffold/planner.test.ts:27` — `creates a basic plan` expects 1 file but receives 2.
- `packages/cli/src/features/scaffold/planner.test.ts:308` — strict-layout test expects 3 files but receives 4.
- `packages/cli/src/features/scaffold/planner.test.ts:347` — rerun-overwrite test expects 3 files but receives 4.
## Required outcome
- Update the test fixture so existing tests do not fail due to unrelated gitignore behavior.
## Suggested approach
- Add `"/test/.gitignore"` to `defaultState.existingFiles`. Because no `gitignoreContent` is provided, the planner will see an existing `.gitignore` and take no action, keeping existing tests focused on env-schema behavior.
- Keep the new gitignore tests overriding `existingFiles` / `gitignoreContent` explicitly to exercise the feature.ℹ️ Nitpicks
- The appended
.gitignorerules only cover.envand.env.local. Other conventional env files (e.g..env.development,.env.production) are not ignored and could be committed by mistake."
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
Important
The latest delta adds the executor-level overwrite guard and passes its tests. No new issues were introduced. The planner.test.ts regressions flagged in the prior review are still present.
Reviewed changes — The delta between 20bf1139 and 6998468d adds the executor-level skip for existing files and applies autofix formatting.
Executornow skipsaction: "create"files that already exist, resolving the latent new-project template-overwrite concern.- Added
executor.test.tscoverage verifying that a planned create action is not written when the path is already present. - Applied Biome formatting fixes across
planner.tsandplanner.test.ts.
ℹ️ Note on prior feedback
No new issues were introduced by these commits. The existing-test regression noted in the previous review (planner.test.ts length assertions failing because defaultState omits .gitignore) is unchanged and still needs a fix before this PR should land."
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
Important
The latest delta adds a correct changeset, but the previously flagged planner.test.ts regression is still unaddressed. Three existing planner tests fail because defaultState triggers .gitignore generation; the open review thread at planner.test.ts:21 still contains the fix.
Reviewed changes — The only change since the prior review is a new .changeset/generate-env-files.md describing the init env-file generation as a patch release.
- Added changeset for
@arkenv/cli— accurately summarizes the.env/.env.examplescaffolding, value stripping,.gitignoreupdates, and create-action skip behavior.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — The planner.test.ts fixture now mocks gitignore existence so existing tests stay focused on env-schema behavior.
- Fixed
planner.test.tsregression — added/test/.gitignoretodefaultState.existingFiles, so existing-project tests no longer implicitly assert.gitignorecreation and the three previously failing length assertions pass. - Merged latest
devinto the feature branch.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to dev, this PR will be updated. # Releases ## @arkenv/cli@0.3.2 ### Patch Changes - #### Generate `.env` and `.env.example` files during initialization _[`#1281`](#1281) [`2aa2608`](2aa2608) [@yamcodes](https://github.com/yamcodes)_ - Scaffold default `.env` and `.env.example` files if missing to prevent Node/tsx `--env-file` boot crashes. - Parse existing `.env` file and securely strip all values to generate `.env.example` when `.env.example` is missing to avoid leaking user credentials to source control. - Automatically check and update `.gitignore` in existing projects to ignore `.env` and `.env.local` files. - Skip overwriting pre-existing files when their scaffolding action is set to `"create"`. - #### Configure pnpm whitelisting for esbuild during scaffolding _[`#1282`](#1282) [`d3fe2bb`](d3fe2bb) [@yamcodes](https://github.com/yamcodes)_ Automatically configure pnpm build whitelisting for `esbuild` during project scaffolding if `pnpm` is the detected package manager. This writes the `onlyBuiltDependencies` field to `package.json` and creates or updates a `pnpm-workspace.yaml` file with the `allowBuilds` configuration before running the installation phase. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary Forward-ports two clean fixes from `dev` to `v1` using cherry-pick (not a bulk merge): - **OG text overflow fix** (#1303 / #1302) — cherry-picked `ba2111ab` - **Vitest project name collision** — exclude legacy `packages/cli` stub from root vitest projects ## Context `dev` and `v1` are intentionally diverged (see CONTRIBUTING Use Case 4). The recent reconciliation (#1292) only covered v0 feature parity (#1281, #1282) — it did not eliminate the ~48 file conflicts that appear when bulk-merging the branches. Those conflicts are expected due to structural differences (`packages/cli` → `packages/arkenv`, removed `/shared` exports, etc.). This PR uses the documented **forward-porting** workflow instead. ## Test plan - [x] `pnpm test run lib/og-text.test.ts app/api/og/route.test.tsx` passes (7/7) - [x] Root vitest starts without duplicate project name error Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>

Closes #1280. Automatically generates .env and .env.example files at the project root during scaffold init if they don't already exist, preventing Node/tsx crash on boot.