fix: preserve platform-specific core shell env vars (#16707)

## Why

We were seeing failures in the following tests as part of trying to get
all the tests running under Bazel on Windows in CI
(https://github.com/openai/codex/pull/16528):

```
suite::shell_command::unicode_output::with_login
suite::shell_command::unicode_output::without_login
```

Certainly `PATHEXT` should have been included in the extra `CORE_VARS`
list, so we fix that up here, but also take things a step further for
now by forcibly ensuring it is set on Windows in the return value of
`create_env()`. Once we get the Windows Bazel build working reliably
(i.e., after #16528 is merged), we should come back to this and confirm
we can remove the special case in `create_env()`.

## What

- Split core env inheritance into `COMMON_CORE_VARS` plus
platform-specific allowlists for Windows and Unix in
[`exec_env.rs`](1b55c88fbf/codex-rs/core/src/exec_env.rs (L45-L81)).
- Preserve `PATHEXT`, `USERNAME`, and `USERPROFILE` on Windows, and
`HOME` / locale vars on Unix.
- Backfill a default `PATHEXT` in `create_env()` on Windows if the
parent env does not provide one, so child process launch still works in
stripped-down Bazel environments.
- Extend the Windows exec-env test to assert mixed-case `PathExt`
survives case-insensitive core filtering, and document why the
shell-command Unicode test goes through a child process.

## Verification

- `cargo test -p codex-core exec_env::tests`
This commit is contained in:
Michael Bolin
2026-04-03 12:07:07 -07:00
committed by GitHub
parent 0ab8eda375
commit faab4d39e1
3 changed files with 95 additions and 9 deletions

View File

@@ -256,6 +256,9 @@ async fn shell_command_times_out_with_timeout_ms() -> anyhow::Result<()> {
Ok(())
}
/// This test verifies that a shell, particularly PowerShell, can correctly
/// handle unicode output when the UTF-8 BOM is used. See
/// https://github.com/openai/codex/pull/7902 for more context.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[test_case(true ; "with_login")]
#[test_case(false ; "without_login")]
@@ -264,10 +267,11 @@ async fn unicode_output(login: bool) -> anyhow::Result<()> {
let harness = shell_command_harness_with(|builder| builder.with_model("gpt-5.2")).await?;
// We use a child process on windows instead of a direct builtin like 'echo' to ensure that Powershell
// config is actually being set correctly.
let call_id = "unicode_output";
let command = if cfg!(windows) {
// We use a child process on Windows instead of a PowerShell command
// like `Write-Output` to ensure that the Powershell config is set
// correctly.
"cmd.exe /c echo naïve_café"
} else {
"echo \"naïve_café\""