Hive Hive
Sign in

perf(server): compile a single locale in :test to speed up cold test builds

GitHub issue · Closed

Metadata
Source
tuist/tuist #11618
Updated
Jul 5, 2026
Details

Speeds up a cold mix test in a fresh worktree by not compiling all ten ex_cldr locales in the :test environment.

What changed

Tuist.Environment.dev_single_locale?/0 is renamed to single_locale?/0 and widened from dev?() and not dev_all_locales?() to (dev?() or test?()) and not dev_all_locales?(). Both :dev and :test now compile only the "en" locale by default. The three compile-time consumers were updated: the ex_cldr backend (Tuist.Cldr.Configuration), the Gettext backend (TuistWeb.Gettext.Configuration), and the supported-language list (Tuist.Locale).

The existing TUIST_DEV_ALL_LOCALES=1 escape hatch still compiles the full set. Tests that assert non-en behaviour are tagged :locale and excluded by default (via test_helper.exs) unless the full set was compiled:

CI’s test job now sets TUIST_DEV_ALL_LOCALES=1 (server.yml) so it compiles the full locale set and runs the :locale tests, keeping i18n coverage unchanged in CI.

Why

:test fell into the all-locales branch of the gate while :dev compiled one, so a fresh worktree with a cold _build/test regenerated the ex_cldr code for all ten locales on the first mix test, whereas the long-running dev server stayed fast on its single-locale build and masked the discrepancy. This was a dev/test inconsistency, not an inherent cost: production (MIX_ENV=prod) is unaffected and still compiles every locale.

Measured impact

Anchored to real CI timings, since CI runs the repo-pinned Elixir 1.19.5. On main today the Test job — which already compiles all ten locales — breaks down roughly as:

Step Duration
Compile (all 10 locales, incl. deps) ~283s
Setup database ~159s
Run tests ~305s
Total ~880s (~14.7 min)

So compiling all ten locales is a modest slice of a ~15-minute job — localization is not the CI bottleneck. This PR keeps CI on all locales, so CI cost is unchanged. The win is local: a fresh worktree’s first mix test no longer regenerates the ex_cldr backend for all ten locales.

Caveat on an earlier local number: I first measured a ~16-min all-locales cldr.ex compile, but that shell was running Elixir 1.20.1 (pulled from a global mise latest pin), not the repo-pinned 1.19.5 that CI uses. 1.20.1’s type checker appears to choke on the large generated cldr module. On the pinned toolchain the all-locales compile is a few minutes (per the CI table), so the local saving from this change is on the order of a couple of minutes off a cold compile, not fifteen.

Root cause vs. alternatives

The compiled locale set is a compile-time decision (ex_cldr generates code per locale via a macro), so the fast/full split has to be a compile-time flag. Keeping Application.compile_env (rather than reading the env var directly) is deliberate: it makes Mix raise a clear “recompile your project” error if the build and the flag disagree, instead of silently running the :locale tests against a single-locale build. The trade-off is that toggling the flag on an already-built worktree needs a recompile; a fresh build with the flag set — CI, or a dev’s first run — just works.

User/developer impact

  • Default cd server && mix test compiles one locale; the :locale tests are reported as excluded.
  • No production behaviour change; managed builds compile all locales as before.
  • CI behaviour is unchanged (still all locales, all tests).

How to test locally

Default fast path (single locale):

cd server && mix test

The :locale-tagged tests show as excluded and the cold _build/test compile no longer generates the full locale set.

Full i18n coverage (what CI runs) — set the flag on a fresh test build:

cd server
TUIST_DEV_ALL_LOCALES=1 mix test

If you flip the flag on an already-built worktree, Mix will (correctly) refuse with a :dev_all_locales compile-env mismatch; force the recompile first, e.g. touch config/config.exs, then rerun.

Functional validation

  • cd server && mix test test/tuist_web/helpers/cldr_helpers_test.exs test/tuist/accounts/user_test.exs on a cold single-locale build: 9 passed, 5 excluded — the :locale tests are skipped and the rest pass.
  • Confirmed the single-locale _build/test generates only Tuist.Cldr for 2 locales [:en, :und], and that TUIST_DEV_ALL_LOCALES=1 regenerates Tuist.Cldr for 14 locales for the opt-in path.

🤖 Generated with Claude Code

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments

No GitHub comments yet.