fix(ci): pass UTF-8 locale through to e2e tests#9823
Conversation
within_isolated_env() uses `env -i` to clear the environment before each test, but did not pass through LANG/LC_ALL. Tests that compile tools from source (e.g. backend/test_gem_slow building ruby 4.0.4) then ran with the POSIX/ASCII locale and failed when ruby-build's rdoc step hit non-ASCII bytes in C sources. The earlier Dockerfile change to set LANG/LC_ALL had no effect inside the test because `env -i` stripped them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryFixes
Confidence Score: 5/5Safe to merge — a two-line addition to the test harness's environment passthrough list with no production code changes. The change is confined to the e2e test harness and only adds two well-understood locale variables to env -i's passthrough list. The default values are conservative and match the Docker image's existing settings, so no test behaviour should regress. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "fix(ci): default only LANG, let LC_ALL p..." | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request modifies the isolated test environment in e2e/run_test by adding default C.UTF-8 values for the LANG and LC_ALL environment variables. A review comment points out that defaulting LC_ALL will override LANG due to environment variable precedence, and suggests only defaulting LANG while passing LC_ALL through without a default to ensure correct locale fallback behavior.
| LANG="${LANG:-C.UTF-8}" \ | ||
| LC_ALL="${LC_ALL:-C.UTF-8}" \ |
There was a problem hiding this comment.
Setting a default value for LC_ALL will override LANG even if LANG is explicitly provided in the environment. Since LC_ALL has the highest precedence among locale environment variables, defaulting it to C.UTF-8 here means that any value passed via LANG will be ignored by the test process unless LC_ALL is also explicitly set.
To allow LANG passthrough while still ensuring a UTF-8 default when nothing is specified, it is better to only default LANG and pass LC_ALL through without a default (which results in an empty string, triggering the standard locale fallback to LANG).
LANG="${LANG:-C.UTF-8}" \
LC_ALL="${LC_ALL:-}" \
Defaulting LC_ALL to C.UTF-8 would silently override LANG (LC_ALL has the highest precedence among locale env vars), so anyone with only LANG set in their env would have it ignored. Default only LANG and pass LC_ALL through verbatim, so users' explicit locale is respected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.5.6 x -- echo |
19.1 ± 0.9 | 17.1 | 22.8 | 1.00 |
mise x -- echo |
19.7 ± 3.1 | 17.2 | 38.2 | 1.03 ± 0.17 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.5.6 env |
18.6 ± 0.7 | 16.7 | 21.9 | 1.00 |
mise env |
18.8 ± 0.9 | 16.9 | 23.1 | 1.01 ± 0.06 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.5.6 hook-env |
20.1 ± 1.2 | 18.1 | 25.2 | 1.00 |
mise hook-env |
21.8 ± 1.6 | 18.4 | 28.7 | 1.08 ± 0.10 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.5.6 ls |
20.1 ± 1.6 | 16.5 | 26.0 | 1.00 |
mise ls |
20.8 ± 2.1 | 17.0 | 31.4 | 1.03 ± 0.13 |
xtasks/test/perf
| Command | mise-2026.5.6 | mise | Variance |
|---|---|---|---|
| install (cached) | 137ms | 137ms | +0% |
| ls (cached) | 66ms | 67ms | -1% |
| bin-paths (cached) | 76ms | 74ms | +2% |
| task-ls (cached) | 540ms | 546ms | -1% |
### 🐛 Bug Fixes - **(backend)** use runtime paths for backend bin dirs by @risu729 in [#9606](#9606) - **(ci)** preserve vendor/aqua-registry/ in PPA publish workflow by @jdx in [#9782](#9782) - **(ci)** set UTF-8 locale in e2e Docker image by @jdx in [#9820](#9820) - **(ci)** pass UTF-8 locale through to e2e tests by @jdx in [#9823](#9823) - **(conda)** dedup repodata by archive identifier instead of URL by @jdx in [#9831](#9831) - **(github)** use default shell for credential command by @risu729 in [#9664](#9664) - **(settings)** distinguish unset known settings from unknown ones by @jdx in [#9818](#9818) - **(upgrade)** remove completed progress jobs to prevent duplicate output by @jdx in [#9779](#9779) - **(vfox)** resolve GitHub token lazily inside Lua plugins by @jdx in [#9816](#9816) ### 🚜 Refactor - **(config)** separate core and backend tool options by @risu729 in [#9753](#9753) - **(schema)** reuse env directive property schemas by @risu729 in [#9651](#9651) ### 📚 Documentation - **(aliases)** fix Aliased Versions example and drop stale asdf callout by @jdx in [#9830](#9830) ### ⚡ Performance - **(aqua)** use phf for baked registry lookups by @risu729 in [#9763](#9763) - **(task)** cache per-file content hashes for source_freshness_hash_contents by @jdx in [#9819](#9819) ### 🧪 Testing - **(e2e)** pin aube to known-good version in npm package_manager test by @jdx in [#9794](#9794) ### 📦 Registry - replace unsupported exe options by @risu729 in [#9587](#9587) - update pi by @garysassano in [#9792](#9792) ### Chore - **(ci)** use non-large runners for release builds by @jdx in [#9786](#9786) - **(ci)** compare registry PRs from fork point by @risu729 in [#9643](#9643) - **(ci)** make build-copr.sh the single source of truth for COPR chroots by @jdx in [#9788](#9788) - **(ci)** use crates.io trusted publishing in release-plz by @jdx in [#9793](#9793) - **(ci)** remove autofix.ci workflow by @jdx in [#9801](#9801) - **(ci)** restore -large runner for Linux release builds by @jdx in [#9815](#9815) - **(ci)** add zizmor workflow for github actions security analysis by @jdx in [#9804](#9804) - **(ci)** assert mise run render produces no diff by @jdx in [#9803](#9803) - **(copr)** publish EL9 builds via centos-stream+epel-next-9 chroot by @jdx in [#9787](#9787) ### Ci - remove pull_request_target workflow by @jdx in [#9799](#9799) - remove caching from publishing workflows by @jdx in [#9800](#9800) ### Security - reject shell metacharacters in version strings and CI inputs by @jdx in [#9814](#9814) ## 📦 Aqua Registry Updates ### New Packages (11) - [`Code-Hex/Neo-cowsay`](https://github.com/Code-Hex/Neo-cowsay) - [`SonarSource/sonarqube-cli`](https://github.com/SonarSource/sonarqube-cli) - [`earendil-works/pi`](https://github.com/earendil-works/pi) - [`hylo-lang/hylo-new`](https://github.com/hylo-lang/hylo-new) - [`jfernandez/bpftop`](https://github.com/jfernandez/bpftop) - [`modem-dev/hunk`](https://github.com/modem-dev/hunk) - [`npm/cli`](https://github.com/npm/cli) - [`racket/racket/minimal`](https://github.com/racket/racket) - [`slackapi/slack-cli`](https://github.com/slackapi/slack-cli) - [`vectordotdev/vector`](https://github.com/vectordotdev/vector) - [`wasilibs/go-yamllint`](https://github.com/wasilibs/go-yamllint) ### Updated Packages (10) - [`DataDog/pup`](https://github.com/DataDog/pup) - [`aquasecurity/trivy`](https://github.com/aquasecurity/trivy) - [`astral-sh/uv`](https://github.com/astral-sh/uv) - [`caarlos0/svu`](https://github.com/caarlos0/svu) - [`cargo-bins/cargo-binstall`](https://github.com/cargo-bins/cargo-binstall) - [`foundry-rs/foundry`](https://github.com/foundry-rs/foundry) - [`gastownhall/beads`](https://github.com/gastownhall/beads) - [`gruntwork-io/terragrunt`](https://github.com/gruntwork-io/terragrunt) - [`pnpm/pnpm`](https://github.com/pnpm/pnpm) - [`santosr2/TerraTidy`](https://github.com/santosr2/TerraTidy)
### 🐛 Bug Fixes - **(backend)** use runtime paths for backend bin dirs by @risu729 in [jdx#9606](jdx#9606) - **(ci)** preserve vendor/aqua-registry/ in PPA publish workflow by @jdx in [jdx#9782](jdx#9782) - **(ci)** set UTF-8 locale in e2e Docker image by @jdx in [jdx#9820](jdx#9820) - **(ci)** pass UTF-8 locale through to e2e tests by @jdx in [jdx#9823](jdx#9823) - **(conda)** dedup repodata by archive identifier instead of URL by @jdx in [jdx#9831](jdx#9831) - **(github)** use default shell for credential command by @risu729 in [jdx#9664](jdx#9664) - **(settings)** distinguish unset known settings from unknown ones by @jdx in [jdx#9818](jdx#9818) - **(upgrade)** remove completed progress jobs to prevent duplicate output by @jdx in [jdx#9779](jdx#9779) - **(vfox)** resolve GitHub token lazily inside Lua plugins by @jdx in [jdx#9816](jdx#9816) ### 🚜 Refactor - **(config)** separate core and backend tool options by @risu729 in [jdx#9753](jdx#9753) - **(schema)** reuse env directive property schemas by @risu729 in [jdx#9651](jdx#9651) ### 📚 Documentation - **(aliases)** fix Aliased Versions example and drop stale asdf callout by @jdx in [jdx#9830](jdx#9830) ### ⚡ Performance - **(aqua)** use phf for baked registry lookups by @risu729 in [jdx#9763](jdx#9763) - **(task)** cache per-file content hashes for source_freshness_hash_contents by @jdx in [jdx#9819](jdx#9819) ### 🧪 Testing - **(e2e)** pin aube to known-good version in npm package_manager test by @jdx in [jdx#9794](jdx#9794) ### 📦 Registry - replace unsupported exe options by @risu729 in [jdx#9587](jdx#9587) - update pi by @garysassano in [jdx#9792](jdx#9792) ### Chore - **(ci)** use non-large runners for release builds by @jdx in [jdx#9786](jdx#9786) - **(ci)** compare registry PRs from fork point by @risu729 in [jdx#9643](jdx#9643) - **(ci)** make build-copr.sh the single source of truth for COPR chroots by @jdx in [jdx#9788](jdx#9788) - **(ci)** use crates.io trusted publishing in release-plz by @jdx in [jdx#9793](jdx#9793) - **(ci)** remove autofix.ci workflow by @jdx in [jdx#9801](jdx#9801) - **(ci)** restore -large runner for Linux release builds by @jdx in [jdx#9815](jdx#9815) - **(ci)** add zizmor workflow for github actions security analysis by @jdx in [jdx#9804](jdx#9804) - **(ci)** assert mise run render produces no diff by @jdx in [jdx#9803](jdx#9803) - **(copr)** publish EL9 builds via centos-stream+epel-next-9 chroot by @jdx in [jdx#9787](jdx#9787) ### Ci - remove pull_request_target workflow by @jdx in [jdx#9799](jdx#9799) - remove caching from publishing workflows by @jdx in [jdx#9800](jdx#9800) ### Security - reject shell metacharacters in version strings and CI inputs by @jdx in [jdx#9814](jdx#9814) ## 📦 Aqua Registry Updates ### New Packages (11) - [`Code-Hex/Neo-cowsay`](https://github.com/Code-Hex/Neo-cowsay) - [`SonarSource/sonarqube-cli`](https://github.com/SonarSource/sonarqube-cli) - [`earendil-works/pi`](https://github.com/earendil-works/pi) - [`hylo-lang/hylo-new`](https://github.com/hylo-lang/hylo-new) - [`jfernandez/bpftop`](https://github.com/jfernandez/bpftop) - [`modem-dev/hunk`](https://github.com/modem-dev/hunk) - [`npm/cli`](https://github.com/npm/cli) - [`racket/racket/minimal`](https://github.com/racket/racket) - [`slackapi/slack-cli`](https://github.com/slackapi/slack-cli) - [`vectordotdev/vector`](https://github.com/vectordotdev/vector) - [`wasilibs/go-yamllint`](https://github.com/wasilibs/go-yamllint) ### Updated Packages (10) - [`DataDog/pup`](https://github.com/DataDog/pup) - [`aquasecurity/trivy`](https://github.com/aquasecurity/trivy) - [`astral-sh/uv`](https://github.com/astral-sh/uv) - [`caarlos0/svu`](https://github.com/caarlos0/svu) - [`cargo-bins/cargo-binstall`](https://github.com/cargo-bins/cargo-binstall) - [`foundry-rs/foundry`](https://github.com/foundry-rs/foundry) - [`gastownhall/beads`](https://github.com/gastownhall/beads) - [`gruntwork-io/terragrunt`](https://github.com/gruntwork-io/terragrunt) - [`pnpm/pnpm`](https://github.com/pnpm/pnpm) - [`santosr2/TerraTidy`](https://github.com/santosr2/TerraTidy)
Summary
LANGandLC_ALL(defaulting toC.UTF-8) to the env passthrough in e2e/run_test:90-91.Why
Follow-up to #9820, which set
LANG=C.UTF-8/LC_ALL=C.UTF-8in the e2e Docker image — butbackend/test_gem_slowkept failing becausewithin_isolated_env()usesenv -ito clear the environment before each test, and the locale wasn't on the pass-through list. The Dockerfile defaults were stripped before the test process ever started.Symptom: ruby 4.0.4 source build fails at the
rdocstep with(ArgumentError) invalid byte sequence in US-ASCIIwhen rdoc's C parser hits non-ASCII bytes inobject.c.Reproduced inside
ghcr.io/jdx/mise:e2eon bamboo (Ubuntu 24.04 host):env -i ... mise install ruby@4.0.4→ fails identically to CIenv -i ... LANG=C.UTF-8 LC_ALL=C.UTF-8 mise install ruby@4.0.4→ succeedsTest plan
e2e-3on release PR #9780 and confirmbackend/test_gem_slowpasses🤖 Generated with Claude Code
Note
Low Risk
Low risk: only adjusts environment variables for e2e test execution, with no production code or data-path changes.
Overview
E2E test runner now preserves locale settings when running tests in a fully cleared environment (
env -i) by explicitly passing throughLANG(defaulting toC.UTF-8) andLC_ALL.This prevents locale-dependent failures (e.g., tooling assuming US-ASCII) during source builds inside CI and the e2e Docker image.
Reviewed by Cursor Bugbot for commit b7d7f06. Bugbot is set up for automated code reviews on this repo. Configure here.