fix: bootstrap.py loads REPO_ROOT/.env so direct invocation matches start.sh (#730) (#791)

* fix: bootstrap.py loads REPO_ROOT/.env so direct invocation matches start.sh

When users run 'python3 bootstrap.py' directly (the primary documented
entry point in README), HERMES_WEBUI_HOST, HERMES_WEBUI_PORT and other
.env settings were silently ignored because the shell-level 'source .env'
in start.sh was never executed.

Add _load_repo_dotenv() in bootstrap.py that reads REPO_ROOT/.env into
os.environ before DEFAULT_HOST / DEFAULT_PORT are evaluated at module
level. Uses unconditional assignment matching 'set -a; source .env'
shell semantics. Only loads the repo .env (bootstrap config) — not
~/.hermes/.env, which the server still loads independently at startup
for provider credentials.

Reported in #730 by @leap233 who had HERMES_WEBUI_HOST=0.0.0.0 and
HERMES_WEBUI_PORT=18787 in the webui .env; running bootstrap.py directly
caused the server to ignore both settings.

Tests: 15 new tests in tests/test_bootstrap_dotenv.py covering the
full loader (key=value, comments, blank lines, quoted values, no-file,
unreadable-file, overwrite semantics, values with = signs) and structural
assertions that _load_repo_dotenv() is called before DEFAULT_HOST/PORT.
1613 tests total.

* fix: address review feedback on PR #791

- bootstrap.py: document overwrite semantics and 'export' note in docstring
- bootstrap.py: handle 'export FOO=bar' prefix (strip before splitting on =)
- bootstrap.py: print warning to stderr on .env parse failure (not silent swallow)
- bootstrap.py: add side-effect comment at _load_repo_dotenv() call site
- CHANGELOG.md: restore v0.50.124 and v0.50.123 headers (were merged into
  v0.50.125 section, making three consecutive ### Fixed blocks with no ## header
  between them)
- tests: fix test_noop_when_dotenv_unreadable to assert warning is emitted
- tests: tighten test_does_not_set_empty_values with concrete assertion
- tests: add test_export_prefix_stripped
- tests: remove dead _import_bootstrap_with_env() helper (never called)
1614 tests total

---------

Co-authored-by: nesquena-hermes <hermes@nesquena.com>
This commit is contained in:
nesquena-hermes
2026-04-20 20:55:53 -07:00
committed by GitHub
parent 38e215e8f8
commit 49ff8b3185
3 changed files with 238 additions and 1 deletions

View File

@@ -1,10 +1,16 @@
# Hermes Web UI -- Changelog
## [v0.50.125] — 2026-04-21
### Fixed
- **`python3 bootstrap.py` now honours `.env` settings** — running bootstrap.py directly (the primary documented entry point) previously ignored `HERMES_WEBUI_HOST`, `HERMES_WEBUI_PORT`, and other repo `.env` settings because `start.sh`'s `source .env` step was skipped. bootstrap.py now loads `REPO_ROOT/.env` itself before reading any env-var defaults, making the two launch paths identical. Reported in #730 by @leap233. (#791)
## [v0.50.124] — 2026-04-21
### Fixed
- **Settings version badge now shows the real running version** — the badge in the Settings → System panel was hardcoded to `v0.50.87` (36 releases behind) and the HTTP `Server:` header said `HermesWebUI/0.50.38` (85 behind). Both are now resolved dynamically at server startup from `git describe --tags --always --dirty`. Docker images (where `.git` is excluded) receive the correct tag via a build-time `ARG HERMES_VERSION` written to `api/_version.py`. No manual "update the badge" step is needed going forward — tagging is sufficient. Version file parsing uses regex instead of `exec()` for supply-chain safety. (#790)
- **Settings version badge now shows the real running version** — the badge in the Settings → System panel was hardcoded to `v0.50.87` (36 releases behind) and the HTTP `Server:` header said `HermesWebUI/0.50.38` (85 behind). Both are now resolved dynamically at server startup from `git describe --tags --always --dirty`. Docker images (where `.git` is excluded) receive the correct tag via a build-time `ARG HERMES_VERSION` written to `api/_version.py`. No manual "update the badge" step is needed going forward — tagging is sufficient. Version file parsing uses regex instead of `exec()` for supply-chain safety. (#790, #792)
## [v0.50.123] — 2026-04-21
### Fixed
- **Default model change surfaced stale value after model-list TTL cache landed** — `set_hermes_default_model()` now explicitly invalidates `_available_models_cache` after `reload_config()`. The 60s TTL cache introduced in v0.50.121 (#780) only invalidates on config-file mtime change, but `reload_config()` resyncs `_cfg_mtime` before `get_available_models()` runs — so the mtime check never fires and the POST response (plus downstream reads within the TTL window) returned the previous model until the cache expired. Root cause of the `test_default_model_updates_hermes_config` CI flake as well. (#788)