Skip to content

Commit bb2ca2d

Browse files
committed
fix(env): use --env-file flags to pass env vars to script subprocesses
Bun's automatic .env loading doesn't pass env vars to subprocesses like drizzle-kit. This fixes the issue by explicitly passing --env-file flags. Also updates init-worktree to: - Explicitly create new branches from HEAD to get latest tooling - Merge base branch into existing branches to get latest tooling
1 parent 6643e80 commit bb2ca2d

File tree

2 files changed

+62
-12
lines changed

2 files changed

+62
-12
lines changed

.bin/bun

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
#!/usr/bin/env bash
22

33
# Bun wrapper that syncs secrets from Infisical to .env.local
4-
# Bun natively loads .env files in this order (highest precedence last):
5-
# 1. .env
6-
# 2. .env.development (or .env.production/.env.test based on NODE_ENV)
7-
# 3. .env.local
8-
# 4. .env.development.local - Worktree-specific overrides (ports, etc.)
94
#
10-
# .env.development.local has highest precedence, so worktree port overrides
11-
# correctly override values from Infisical-synced .env.local.
5+
# Why this wrapper exists:
6+
# Bun's automatic .env loading doesn't pass env vars to script subprocesses
7+
# (e.g., drizzle-kit, tsx, etc.). This wrapper explicitly passes --env-file
8+
# flags to ensure env vars are available everywhere.
129
#
13-
# This wrapper ensures .env.local is up-to-date from Infisical before running bun.
14-
# If Infisical is not set up, it falls back to using existing .env.local if present.
10+
# Env file precedence (later files override earlier ones):
11+
# 1. .env.local - Main secrets from Infisical
12+
# 2. .env.development.local - Worktree-specific overrides (ports, etc.)
13+
#
14+
# This wrapper:
15+
# 1. Syncs .env.local from Infisical (with caching)
16+
# 2. Creates symlinks in subdirectories for tools that need local .env files
17+
# 3. Passes --env-file flags to bun so subprocesses inherit env vars
1518

1619
# Common bun installation paths to check
1720
BUN_PATHS=(
@@ -202,11 +205,29 @@ check_env_setup() {
202205
echo "" >&2
203206
}
204207

208+
# Build env file arguments for bun
209+
# Bun's automatic .env loading doesn't pass vars to script subprocesses (like drizzle-kit),
210+
# so we explicitly pass --env-file flags to ensure env vars are available everywhere.
211+
build_env_file_args() {
212+
ENV_FILE_ARGS=""
213+
214+
# Add .env.local if it exists
215+
if [ -f "$ENV_LOCAL_FILE" ]; then
216+
ENV_FILE_ARGS="--env-file=$ENV_LOCAL_FILE"
217+
fi
218+
219+
# Add .env.development.local if it exists (higher precedence for worktree overrides)
220+
if [ -f "$ENV_DEVELOPMENT_LOCAL_FILE" ]; then
221+
ENV_FILE_ARGS="$ENV_FILE_ARGS --env-file=$ENV_DEVELOPMENT_LOCAL_FILE"
222+
fi
223+
}
224+
205225
run_bun() {
206226
create_env_symlinks
207227
check_env_setup
208-
# Bun natively loads .env files and gives them precedence over inherited shell vars
209-
exec "$REAL_BUN" "$@"
228+
build_env_file_args
229+
# Use --env-file to ensure env vars are passed to script subprocesses
230+
exec "$REAL_BUN" $ENV_FILE_ARGS "$@"
210231
}
211232

212233
# Main logic

scripts/init-worktree.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ async function checkGitBranchExists(branchName: string): Promise<boolean> {
206206
}
207207
}
208208

209+
async function getCurrentBranch(): Promise<string> {
210+
const proc = Bun.spawn(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], {
211+
stdout: 'pipe',
212+
stderr: 'pipe',
213+
})
214+
const output = await new Response(proc.stdout).text()
215+
return output.trim() || 'main'
216+
}
217+
209218
function createEnvDevelopmentLocalFile(
210219
worktreePath: string,
211220
args: WorktreeArgs,
@@ -387,14 +396,33 @@ async function main(): Promise<void> {
387396
console.log(`Location: ${worktreePath}`)
388397

389398
// Create the git worktree (with or without creating new branch)
399+
// Explicitly use HEAD to ensure worktree has latest tooling (.bin/bun, etc.)
400+
const baseBranch = await getCurrentBranch()
390401
const worktreeAddArgs = ['worktree', 'add', worktreePath]
391402
if (branchExists) {
403+
// Branch exists - check it out
392404
worktreeAddArgs.push(args.name)
393405
} else {
394-
worktreeAddArgs.push('-b', args.name)
406+
// New branch - explicitly create from HEAD to get latest tooling
407+
worktreeAddArgs.push('-b', args.name, 'HEAD')
395408
}
396409
await runCommand('git', worktreeAddArgs)
397410

411+
// If branch already existed, merge in the base branch to get latest tooling
412+
if (branchExists) {
413+
console.log(`Merging ${baseBranch} into ${args.name} to get latest tooling...`)
414+
const mergeResult = await runCommand(
415+
'git',
416+
['merge', baseBranch, '--no-edit', '-m', `Merge ${baseBranch} to get latest tooling`],
417+
worktreePath,
418+
)
419+
if (mergeResult.exitCode !== 0) {
420+
console.warn(
421+
`Warning: Merge had conflicts. Please resolve them manually in the worktree.`,
422+
)
423+
}
424+
}
425+
398426
console.log('Setting up worktree environment...')
399427
console.log(`Backend port: ${args.backendPort}`)
400428
console.log(`Web port: ${args.webPort}`)
@@ -416,6 +444,7 @@ async function main(): Promise<void> {
416444

417445
console.log(`✅ Worktree '${args.name}' created and set up successfully!`)
418446
console.log(`📁 Location: ${worktreePath}`)
447+
console.log(`🌿 Based on: ${baseBranch} (HEAD)`)
419448
console.log(`🚀 You can now cd into the worktree and start working:`)
420449
console.log(` cd ${worktreePath}`)
421450
console.log(``)

0 commit comments

Comments
 (0)