diff --git a/docker/build.sh b/docker/build.sh index 94f820b35..bd6ac05bc 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -64,7 +64,9 @@ case "$commit" in *[!0-9a-f]*|"") commit="" ;; esac # tools/: every .py at any depth, because the bundle's DeepSeek scripts are nested (INSTALLER_SCRIPTS in package_terminal.py names dsv41/*: # the Dockerfile's terminal stage stops at "installer tool missing: tools/dsv41/tune.py" when only the top-level modules are in the context) cd "$repo" -paths="packaging bin strata.py strata_control strata_cli serve requirements.txt requirements-monitor.txt docs/MANAGEMENT_PROTOCOL.md docs/TERMINAL_LAUNCH.md data bench/prompts/standard-v1 setup.py ref/load.py CMakeLists.txt" +# metal/tools/: the two repack scripts the bundle carries (INSTALLER_METAL_TOOLS in package_terminal.py; without them the terminal stage +# stops at "No such file or directory: '/src/metal/tools/metal_repack.py'", as the v0.2.11 image build did) +paths="packaging bin strata.py strata_control strata_cli serve requirements.txt requirements-monitor.txt docs/MANAGEMENT_PROTOCOL.md docs/TERMINAL_LAUNCH.md data bench/prompts/standard-v1 setup.py ref/load.py CMakeLists.txt metal/tools/metal_repack.py metal/tools/stream_experts.py" if git rev-parse --git-dir >/dev/null 2>&1; then # shellcheck disable=SC2086 { git ls-files -z -- $paths ':(glob)tools/**/*.py'; } | tar --null -T - -cf - | tar -xf - -C "$ctx/terminal-src" diff --git a/tests/terminal/test_docker_files.py b/tests/terminal/test_docker_files.py index 295e0349e..9745b4eb9 100644 --- a/tests/terminal/test_docker_files.py +++ b/tests/terminal/test_docker_files.py @@ -64,6 +64,14 @@ class Scripts(unittest.TestCase): self.assertTrue({"dsv41/pack_gguf", "dsv41/tune"} <= tools) # the nested ones this assertion exists for for name in sorted(tools): self.assertTrue((ctx / "terminal-src" / "tools" / f"{name}.py").is_file(), f"build.sh did not copy tools/{name}.py into the context") + # the Mac repack scripts the bundle carries (the v0.2.11 image build stopped at "No such file ... metal/tools/metal_repack.py") + metal: set[str] = set() + for node in pt.body: + if isinstance(node, ast.Assign) and any(getattr(t, "id", "") == "INSTALLER_METAL_TOOLS" for t in node.targets): + metal.update(ast.literal_eval(node.value)) + self.assertTrue(metal) + for name in sorted(metal): + self.assertTrue((ctx / "terminal-src" / "metal" / "tools" / f"{name}.py").is_file(), f"build.sh did not copy metal/tools/{name}.py into the context") def test_scripts_use_unix_line_ends(self): for name in ("entrypoint.sh", "strata-wrapper.sh", "healthcheck.sh", "build.sh", "publish.sh"):