diff --git a/.github/workflows/pm-bundle.yml b/.github/workflows/pm-bundle.yml index 6e7c0919dc..05e4aee21e 100644 --- a/.github/workflows/pm-bundle.yml +++ b/.github/workflows/pm-bundle.yml @@ -55,7 +55,8 @@ jobs: bundle: name: bundle ${{ matrix.target.label }} runs-on: ${{ matrix.target.runner }} - timeout-minutes: 45 + # Leave time for setup, cache saves and smoke tests around the wheel build. + timeout-minutes: 180 strategy: fail-fast: false matrix: diff --git a/scripts/bundles/native.py b/scripts/bundles/native.py index 5d28e0bea3..7895348f8d 100644 --- a/scripts/bundles/native.py +++ b/scripts/bundles/native.py @@ -195,8 +195,10 @@ def _stage_native(args) -> int: from pm.package import InstallError try: + # Cold native wheels need a larger budget than interactive installs. build_environment(source=repo_dir, python=python_bin, out=venv_dir, - env=env, cache=cache, all_extras=True, sealed=True, explicit=True) + env=env, cache=cache, all_extras=True, sealed=True, explicit=True, + timeout=2 * 60 * 60) except InstallError as exc: print(f"✗ venv: {exc}") return 1 diff --git a/tests/scripts/test_bundle_native.py b/tests/scripts/test_bundle_native.py index df58d5f2ff..194e636a22 100644 --- a/tests/scripts/test_bundle_native.py +++ b/tests/scripts/test_bundle_native.py @@ -19,6 +19,8 @@ from scripts.bundles import native def test_bundle_stages_git_tree_and_runs_native_children_before_manifest(tmp_path, monkeypatch): + import inspect + from hermes_cli.runtime_paths import site_packages monkeypatch.setattr(Path, "home", lambda: tmp_path / "home") @@ -63,6 +65,7 @@ def test_bundle_stages_git_tree_and_runs_native_children_before_manifest(tmp_pat monkeypatch.setattr("pm.extras.ANCHORS", {"payloadtest": "bundle_probe.present"}) import pm real_build = pm.build_environment + install_timeout = inspect.signature(real_build).parameters["timeout"].default calls = [] witness = tmp_path / "inventory-python.json" fail_inventory = False @@ -70,6 +73,7 @@ def test_bundle_stages_git_tree_and_runs_native_children_before_manifest(tmp_pat def build(**kwargs): assert "uv" not in kwargs assert kwargs["sealed"] is True + assert kwargs.get("timeout", install_timeout) > install_timeout calls.append(kwargs) assert not (output / "manifest.json").exists() marker = json.loads((output / "pm-runtime/pm-runtime.json").read_text())