Skip to content

feat(worktree-cli): inherit non-port env vars from main worktree#33

Merged
rlueder merged 2 commits into
mainfrom
feat/worktree-env-inherit
May 13, 2026
Merged

feat(worktree-cli): inherit non-port env vars from main worktree#33
rlueder merged 2 commits into
mainfrom
feat/worktree-env-inherit

Conversation

@rlueder
Copy link
Copy Markdown
Member

@rlueder rlueder commented May 13, 2026

Resumo

Adiciona suporte a inheritEnvFromMain no WorktreeConfig — lista de arquivos .env.local cujas chaves KEY=VALUE o setup deve copiar do worktree principal para o novo worktree (sem sobrescrever as chaves que o próprio CLI escreveu via writeFiles, ex.: PORT, VITE_API_URL).

Motivação

Criar um worktree novo em um monorepo com vários serviços exige passos manuais não-óbvios antes de levantar dev servers:

  1. Rodar o build dos pacotes internos — senão a API quebra com ERR_MODULE_NOT_FOUND lendo packages/*/dist/index.js. Isso é solucionável só com config do repo (buildCommand), sem mudança no CLI.
  2. Copiar as credenciais de serviços externos de dev do .env.local principal para os arquivos do worktree. O CLI hoje só escreve as chaves de porta via writeFiles. Isso requer essa mudança no CLI.

Sintoma observado pelos consumidores: a API sobe e o primeiro request falha por falta de credenciais. Cada worktree novo quebra do mesmo jeito até alguém lembrar de copiar o env.

Como funciona

  • inheritEnvFromMain: ['apps/api/.env.local', 'apps/web/.env.local'] no package.json#worktree.
  • Após writeFiles, o setup lê cada arquivo no worktree principal, extrai as linhas KEY=VALUE, e anexa ao arquivo correspondente no novo worktree apenas as chaves ausentes. As linhas escritas por writeFiles (porta, VITE_API_URL etc.) ficam autoritativas.
  • Header # Inherited from main worktree by precisa-worktree setup separa as linhas anexadas para rastreabilidade.
  • Arquivos ausentes em main → log silencioso skip <path>, sem erro.
  • Comentários e linhas em branco do arquivo de origem não são copiados.

Implementação

  • src/env-merge.ts: helpers puros parseEnvKeys / buildInheritedAppend (sem I/O, fácil de testar).
  • src/commands/setup.ts: chama o helper após writeFiles, faz I/O e logging.
  • src/index.ts: re-exporta setup, buildInheritedAppend, parseEnvKeys para uso programático.
  • test/env-merge.test.mjs: 13 testes unitários cobrindo parser, dedup, headers, edge cases.
  • test/setup-inherit.integration.test.mjs: 1 teste end-to-end que faz git worktree add real em tmpdir e verifica que as chaves herdadas aparecem no destino.
  • Runner: node --test nativo (Node 22+). Sem nova devDep.

Test plan

  • pnpm --filter=@precisa-saude/worktree-cli test — 14 passam
  • pnpm --filter=@precisa-saude/worktree-cli typecheck — limpo
  • pnpm --filter=@precisa-saude/worktree-cli build — limpo
  • CI verde
  • Após merge + publish, atualizar package.json#worktree do consumidor para adotar inheritEnvFromMain + buildCommand (PR separado).

Adiciona `inheritEnvFromMain` ao `WorktreeConfig`: lista de arquivos
cujas linhas `KEY=VALUE` devem ser anexadas, no fim do `setup`, ao
arquivo correspondente do novo worktree. Chaves já presentes (tipicamente
as escritas por `writeFiles` — `PORT`, `VITE_API_URL`) NÃO são
sobrescritas; só as ausentes são anexadas.

Motivação: até hoje o `setup` só escrevia as chaves de porta nos
`.env.local` de cada app, exigindo que cada operador manualmente
copiasse Cognito/Stripe/S3/DynamoDB/etc. do worktree principal antes
de levantar o dev server. O sintoma era opaco — a API caía com 404
`NoSuchBucket` ou 500 sem `STRIPE_SECRET_KEY`, e cada worktree novo
quebrava do mesmo jeito.

Mudanças:
- `WorktreeConfig.inheritEnvFromMain?: string[]` documentado
- Helper puro `parseEnvKeys` / `buildInheritedAppend` em
  `src/env-merge.ts` (testável sem I/O)
- `setup.ts` invoca o helper após `writeFiles`, ignora silenciosamente
  arquivos ausentes em main, registra `inherited N key(s) into <path>`
- Tests com `node:test` (sem vitest, sem nova devDep): 13 unitários +
  1 integração que faz `git worktree add` real em tmpdir
- README com exemplo platform + nota explicando quando usar

Repo-side adoption: cada repo que quiser este comportamento adiciona
`inheritEnvFromMain` ao bloco `worktree` no `package.json`. Sem essa
config, o comportamento atual fica intacto.
@github-actions
Copy link
Copy Markdown

Automated Review — Round 1

Summary

The PR implements a mechanism for inheriting environment variables from the main worktree's .env.local files, improving the setup process for worktrees. It introduces new functionality without apparent bugs, but there are a few areas where improvements related to error handling and potential security issues could be considered.

Changes

  • Added inheritEnvFromMain functionality
  • Updated setup command to inherit environment variables from main worktree
  • Introduced env-merge utility functions
  • Extended tests for env variable handling

🔍 Found 3 suggestions (see inline comments)

Reviewed by OpenAI gpt-4o-mini (fallback) | 5,246 in / 257 out | $0.0009 — Round 1 of 2

Comment thread packages/worktree-cli/src/commands/setup.ts
Comment thread packages/worktree-cli/src/env-merge.ts
Comment thread packages/worktree-cli/test/setup-inherit.integration.test.mjs
…ritEnvFromMain

Substitui nomes de fornecedores específicos no .env.local sintético por
chaves neutras (INHERIT_KEY_A/B). O teste valida cópia chave-a-chave; a
identidade das chaves é irrelevante para o que está sendo testado e
manter nomes de fornecedores em um repo público enumera dependências
internas sem necessidade.

Refs: #33
@github-actions
Copy link
Copy Markdown

Automated Review — Round 2 (Final)

Summary

Integration tests have been updated to reflect changes in environment variable names, providing accurate validation of inherited keys.

Changes

  • Updated references from credential keys to generic inherited keys in tests.

✅ No issues found

Reviewed by OpenAI gpt-4o-mini (fallback) | 894 in / 46 out | $0.0002 — Round 2 (Final); no further reviews will be performed

@rlueder rlueder merged commit f57528b into main May 13, 2026
10 checks passed
@rlueder rlueder deleted the feat/worktree-env-inherit branch May 13, 2026 14:41
precisa-saude-release-bot Bot pushed a commit that referenced this pull request May 13, 2026
## [1.9.0](v1.8.0...v1.9.0) (2026-05-13)

### Features

* **worktree-cli:** inherit non-port env vars from main worktree ([#33](#33)) ([f57528b](f57528b))

### CI/CD

* bump pnpm/action-setup para v5 (Node.js 24) ([#30](#30)) ([a50119c](a50119c))

### Chores

* **templates:** adicionar environment gate npm-publish no _publish.yml ([#31](#31)) ([f7f7d23](f7f7d23))
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