CI measured 90.6ms after the lazy-import refactor lands. Set baseline to
91ms with 15% margin (ceiling 104.65ms, ~14ms headroom for GHA variance
over the observed measurement).
CI now measures 81.2ms after the zeroconf/writer/yaml_util lazy loads.
Reset baseline to 82ms with the 15% margin (ceiling 94.3ms, ~13ms
headroom for GHA variance).
CI measured 126.2ms against 123ms baseline + 25% ceiling (153.8ms). That's
27.6ms of headroom — enough slack that a real regression could hide under
it. Drop to 15% (ceiling 141.5ms, ~15ms headroom over observed). Still
well above GHA runner variance, tight enough to catch the class of
regression we care about (zeroconf-style top-level import additions).
The previous parser walked `-X importtime` stderr by hand (string-splitting
on `|`, indent-width math). Replace it with a load of the HAR JSON that
importtime-waterfall already produces: each entry carries the module name,
self-time, and cumulative — no tree reconstruction needed. Drops the
hand-rolled retry loop too, since importtime-waterfall does best-of-6
internally.
The committed budget (75.2ms) was seeded on a fast local machine; GHA
runners measured 122.8ms, so the first CI run tripped the check. Reset
the baseline to 123ms with a 25% margin (ceiling ~154ms) to absorb GHA
variance. Tighten later once we have several data points.
Adds unit tests for should_run_import_time across the trigger matrix and
wires the new mock into the existing test_main_* suite.
Adds a CI gate that runs `python -X importtime -c "import esphome.__main__"`
via importtime-waterfall's best-of-N harness, compares the root cumulative
time against a checked-in budget (script/import_time_budget.json, seeded
at 75.2ms with a 15% margin), and fails the build when top-level imports
regress.
The CLI pays this cost on every invocation before the requested command
even runs, so silently adding a top-level dep chain (the recent zeroconf
move in #13135 being the motivating case) hurts every user. The check
gives us a signal without waiting for user reports.
- script/check_import_time.py: --check / --update / --har PATH modes.
On regression, prints a ranked top-15 offenders table by self-time.
- script/import_time_budget.json: baseline + margin_pct.
- script/determine-jobs.py: should_run_import_time() gates the job on
esphome/**/*.py, requirements.txt, requirements_dev.txt, pyproject.toml,
or changes to the check itself.
- .github/workflows/ci.yml: new import-time job, runs when gated and
uploads a waterfall HAR artifact (14-day retention) for inspection.