fix(infra-artifact): include pyproject.toml in rootfs version digest
test / integration (pull_request) Successful in 23s
test / unit (pull_request) Successful in 31s
lint / lint (push) Successful in 41s
test / coverage (pull_request) Successful in 39s

Dockerfile.gateway COPYs pyproject.toml into /src and runs pip install
/src, so it is a real input to the baked rootfs. A dependency-only change
previously reused stale artifact versions, potentially booting a rootfs
whose installed packages differed from the current checkout.

Also adds _fake_repo fixture support and a regression test so this input
can't silently drop out of the hash again.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 16:56:11 +00:00
parent 8458b221d9
commit 2d3bdc532d
2 changed files with 13 additions and 0 deletions
@@ -85,6 +85,8 @@ def infra_artifact_version(init_script: str, *, repo_root: Path = _REPO_ROOT) ->
h.update(name.encode())
h.update(b"\0")
h.update((repo_root / name).read_bytes())
h.update(b"pyproject.toml\0")
h.update((repo_root / "pyproject.toml").read_bytes())
h.update(b"init\0")
h.update(init_script.encode())
return h.hexdigest()[:16]
+11
View File
@@ -93,6 +93,7 @@ class TestVersionInputs(unittest.TestCase):
(pkg / "netpool.defaults.env").write_text("FOO=1\n")
for name in ("Dockerfile.orchestrator", "Dockerfile.gateway", "Dockerfile.infra"):
(root / name).write_text(f"FROM scratch # {name}\n")
(root / "pyproject.toml").write_text("[project]\nname = 'bot-bottle'\n")
def test_non_python_file_change_bumps_version(self) -> None:
with tempfile.TemporaryDirectory() as d:
@@ -104,6 +105,16 @@ class TestVersionInputs(unittest.TestCase):
after = ia.infra_artifact_version("init", repo_root=root)
self.assertNotEqual(before, after)
def test_pyproject_toml_change_bumps_version(self) -> None:
with tempfile.TemporaryDirectory() as d:
root = Path(d)
self._fake_repo(root)
before = ia.infra_artifact_version("init", repo_root=root)
(root / "pyproject.toml").write_text(
"[project]\nname = 'bot-bottle'\ndependencies = ['httpx']\n")
after = ia.infra_artifact_version("init", repo_root=root)
self.assertNotEqual(before, after)
def test_pyc_and_pycache_ignored(self) -> None:
with tempfile.TemporaryDirectory() as d:
root = Path(d)