Salvage of #35508 (@dchenk), rebased onto current main. Resolved the tests/tools/test_stage2_hook_puid_pgid.py conflict (kept both the envdir-creation regression test on main and the new config-migration tests). Docker image upgrades replace code under $INSTALL_DIR but preserve $HERMES_HOME on the mounted volume, so the persisted config.yaml never received the schema migrations that non-Docker `hermes update` runs (#35406). This adds scripts/docker_config_migrate.py, invoked from stage2-hook after first-boot seeding and before gateway services start: it backs up config.yaml + .env, runs migrate_config(interactive=False), and honors HERMES_SKIP_CONFIG_MIGRATION=1 for manual control. Also fixes a latent bug in check_config_version(): it called load_config() which deep-merges DEFAULT_CONFIG, so a legacy config with no raw _config_version falsely reported as already-current. It now reads the raw on-disk file so legacy configs are correctly detected for migration. Differs from #35508 as submitted (Option B cleanup): dropped the `_config_version` line added to cli-config.yaml.example and removed the accompanying test_cli_config_example_declares_latest_version change-detector test. The example is a copy-template and has no business asserting a schema version; check_config_version() reads the user's real config.yaml, not the example. This removes a second sync point that drifts on every version bump. Closes #35508. Fixes #35406. Co-authored-by: Dmitriy Cherchenko <17372886+dchenk@users.noreply.github.com>
This commit is contained in:
co-authored by
Dmitriy Cherchenko
parent
92be989291
commit
04d620d91f
@@ -9,6 +9,7 @@ import yaml
|
||||
|
||||
from hermes_cli.config import (
|
||||
DEFAULT_CONFIG,
|
||||
check_config_version,
|
||||
get_hermes_home,
|
||||
ensure_hermes_home,
|
||||
get_compatible_custom_providers,
|
||||
@@ -542,6 +543,28 @@ class TestConfigMigrationSecretPrompts:
|
||||
assert results["env_added"] == ["TEST_API_KEY"]
|
||||
|
||||
|
||||
class TestConfigVersionDetection:
|
||||
def test_check_config_version_uses_raw_on_disk_version(self, tmp_path):
|
||||
config_path = tmp_path / "config.yaml"
|
||||
config_path.write_text("model: {}\n", encoding="utf-8")
|
||||
|
||||
with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}):
|
||||
assert load_config()["_config_version"] == DEFAULT_CONFIG["_config_version"]
|
||||
assert check_config_version() == (0, DEFAULT_CONFIG["_config_version"])
|
||||
|
||||
def test_check_config_version_treats_missing_file_as_current(self, tmp_path):
|
||||
with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}):
|
||||
latest = DEFAULT_CONFIG["_config_version"]
|
||||
assert check_config_version() == (latest, latest)
|
||||
|
||||
def test_check_config_version_does_not_migrate_invalid_yaml(self, tmp_path):
|
||||
(tmp_path / "config.yaml").write_text("model: [unterminated\n", encoding="utf-8")
|
||||
|
||||
with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}):
|
||||
latest = DEFAULT_CONFIG["_config_version"]
|
||||
assert check_config_version() == (latest, latest)
|
||||
|
||||
|
||||
class TestAnthropicTokenMigration:
|
||||
"""Test that config version 8→9 clears ANTHROPIC_TOKEN."""
|
||||
|
||||
@@ -904,4 +927,3 @@ class TestEnvWriteDenylist:
|
||||
# But the write path still refuses to update it
|
||||
with pytest.raises(ValueError, match="denylist"):
|
||||
save_env_value("LD_PRELOAD", "/tmp/evil.so")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user