diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ba139e..4abd495 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,6 +104,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 + id: rust-toolchain with: toolchain: nightly, 1.94 components: rustfmt, clippy @@ -113,6 +114,19 @@ jobs: - name: Install just run: cargo install --locked just + # Restore after Rust cache cleanup; save before its post-job cleanup. + - name: Cache Windows surrogate + if: runner.os == 'Windows' + id: windows-surrogate + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: target/debug/build/hls/x86_64-pc-windows-msvc/debug/hyperlight_surrogate.exe + key: windows-surrogate-${{ steps.rust-toolchain.outputs.cachekey }}-${{ hashFiles('Cargo.lock', 'rust-toolchain.toml') }} + + - name: Rebuild host when the surrogate cache is missing + if: runner.os == 'Windows' && steps.windows-surrogate.outputs.cache-hit != 'true' + run: just clean-rust-host-cache + - name: Format check run: just fmt-check-rust diff --git a/Justfile b/Justfile index 6d87c5a..c1a237c 100644 --- a/Justfile +++ b/Justfile @@ -20,6 +20,10 @@ lint: lint-rust wasm::lint js::lint python::lint lint-rust: cargo clippy -p hyperlight-sandbox --all-targets --features test-utils -- -D warnings +# Rebuild the host when its separately cached Windows surrogate is unavailable. +clean-rust-host-cache: + cargo clean --package hyperlight-host + fmt: fmt-rust python::fmt dotnet::fmt fmt-rust: diff --git a/scripts/tests/test_ci_guest_artifacts.py b/scripts/tests/test_ci_guest_artifacts.py index af38068..a35da0b 100644 --- a/scripts/tests/test_ci_guest_artifacts.py +++ b/scripts/tests/test_ci_guest_artifacts.py @@ -1,4 +1,4 @@ -"""Keep shared guest artifacts out of Rust cache restore cleanup.""" +"""Keep generated build artifacts out of Rust cache cleanup.""" import re import unittest @@ -6,6 +6,27 @@ class GuestArtifactWorkflowTests(unittest.TestCase): + def test_windows_surrogate_cache_follows_rust_cache_restore(self): + workflow = Path(__file__).resolve().parents[2] / ".github" / "workflows" / "ci.yml" + rust_job = workflow.read_text(encoding="utf-8").split("\n rust:\n", 1)[1].split("\n wasm-sandbox:", 1)[0] + self.assertIn("name: Cache Windows surrogate", rust_job) + restore = rust_job.index("- uses: actions-rust-lang/setup-rust-toolchain@") + surrogate = rust_job.index("name: Cache Windows surrogate") + lint = rust_job.index("name: Lint") + self.assertLess(restore, surrogate, "Rust cache cleanup removes the nested surrogate build directory") + self.assertLess(surrogate, lint, "The surrogate must be restored before compiling hyperlight-host") + surrogate_step = rust_job[surrogate:].split("\n - ", 1)[0] + self.assertIn("if: runner.os == 'Windows'", surrogate_step) + self.assertIn("uses: actions/cache@", surrogate_step) + self.assertIn("target/debug/build/hls/x86_64-pc-windows-msvc/debug/hyperlight_surrogate.exe", surrogate_step) + self.assertIn("steps.rust-toolchain.outputs.cachekey", surrogate_step) + self.assertIn("hashFiles('Cargo.lock', 'rust-toolchain.toml')", surrogate_step) + repair = rust_job.index("run: just clean-rust-host-cache") + self.assertLess(surrogate, repair) + self.assertLess(repair, lint) + repair_step = rust_job[surrogate:].split("\n - ", 2)[1] + self.assertIn("runner.os == 'Windows' && steps.windows-surrogate.outputs.cache-hit != 'true'", repair_step) + def test_guest_download_follows_rust_cache_restore(self): workflow = Path(__file__).resolve().parents[2] / ".github" / "workflows" / "ci.yml" jobs = re.split(r"(?m)^ ([\w-]+):\s*$", workflow.read_text(encoding="utf-8").split("jobs:\n", 1)[1])