Skip to content

Commit 6cf33f3

Browse files
milesjclaude
andauthored
fix: Prevent BASH_ENV from overwriting the injected task PATH (#2609)
fix: Prevent `BASH_ENV` from overwriting the injected task `PATH`. Non-interactive bash sources the file referenced by `BASH_ENV` on startup, after the process environment has been applied. CI providers like CircleCI persist environment variables between steps through this file, so an `export PATH=...` within it would overwrite the `PATH` that moon explicitly sets for task child processes, breaking lookup of `node_modules` binaries and proto shims. Strip `BASH_ENV` from bash wrapped child processes, unless it has been explicitly set on the command (e.g. task `env`). Closes #1998 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 5c16ccb commit 6cf33f3

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
- Fixed `moon ci` failing in certain CI provider pull request builds, where the base branch is
1919
provided as a fully-qualified `refs/heads/<branch>` ref that couldn't be resolved in a detached
2020
`HEAD` checkout.
21+
- Fixed task binaries failing with "command not found" in CI providers like CircleCI, where an
22+
`export PATH=...` in the `$BASH_ENV` file would overwrite the `PATH` that moon injects for tasks.
23+
`BASH_ENV` is no longer passed to `bash` wrapped child processes, unless explicitly set with the
24+
task `env` option.
2125

2226
## 2.4.2
2327

crates/process/src/exec_command.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,14 +397,29 @@ impl Command {
397397
// string of the full command line with args quoted correctly, as
398398
// it's passed as a single argument to the shell: `bash -c "command line"`
399399
let mut command = if self.shell.is_some() || self.exe.requires_shell() {
400-
let shell = self.shell.unwrap_or_default().build();
400+
let shell_type = self.shell.unwrap_or_default();
401+
let shell = shell_type.build();
401402

402403
let script = match &self.exe {
403404
CommandExecutable::Binary(bin) => join_exe_args(&shell, bin, &self.args, false),
404405
CommandExecutable::Script(script) => script.to_owned(),
405406
};
406407

407-
shell.create_wrapped_command_with(script)
408+
let mut command = shell.create_wrapped_command_with(script);
409+
410+
// Non-interactive bash sources the file referenced by `BASH_ENV`
411+
// on startup, after the process environment has been applied.
412+
// CI providers like CircleCI persist environment variables between
413+
// steps through this file, so an `export PATH=...` within it will
414+
// overwrite the `PATH` we explicitly set for this process.
415+
// https://github.com/moonrepo/moon/issues/1998
416+
if matches!(shell_type, starbase_shell::ShellType::Bash)
417+
&& !self.env.contains_key(OsStr::new("BASH_ENV"))
418+
{
419+
command.env_remove("BASH_ENV");
420+
}
421+
422+
command
408423
}
409424
// When the command is not in a shell, we can create a standard command
410425
// and pass the non-quoted args separately

0 commit comments

Comments
 (0)