From 723d59484108eb1592d14b659a2a78616f141201 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 08:36:23 -0400 Subject: [PATCH 01/10] chore: update unlock-keyring to v1.2.0 --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0d8c2d9f..bc09539f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -105,7 +105,7 @@ jobs: cache-shared-key: ${{ runner.os }}-test cache-bin: false - - uses: t1m0thyj/unlock-keyring@e481cdc8833d4417a58f40734e8f197183317047 + - uses: t1m0thyj/unlock-keyring@cbcf205c879ebd86add70bab3a6abfcce59a5cae # 1.2.0 if: ${{ contains(matrix.os, 'ubuntu') }} - name: Run unit tests @@ -172,7 +172,7 @@ jobs: run: .github/scripts/init-docker.sh shell: wsl-bash_Ubuntu-22.04 {0} - - uses: t1m0thyj/unlock-keyring@e481cdc8833d4417a58f40734e8f197183317047 + - uses: t1m0thyj/unlock-keyring@cbcf205c879ebd86add70bab3a6abfcce59a5cae # 1.2.0 if: ${{ contains(matrix.os, 'ubuntu') }} - name: Install mops From 6dc7031b88769649b610ee7f4213d599b6a9817a Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 08:38:55 -0400 Subject: [PATCH 02/10] chore: update setup-wsl to v7.0.0 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bc09539f..dfdc543a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -163,7 +163,7 @@ jobs: - name: Setup WSL2 (Windows) if: ${{ contains(matrix.os, 'windows') }} - uses: Vampire/setup-wsl@6a8db447be7ed35f2f499c02c6e60ff77ef11278 # v6.0.0 + uses: Vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0 with: distribution: Ubuntu-22.04 From c157f9c0a5554057385970db2d0312a35b342b8d Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 08:49:16 -0400 Subject: [PATCH 03/10] ci: untap unused Homebrew taps on macOS to silence trust warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The macOS runner image pre-taps aws/tap and azure/bicep. Homebrew now emits an "untrusted taps" warning on every `brew install` — including the `brew install bash` inside setup-rust-toolchain, which is why even the unit-tests job warns. We use nothing from those taps (softhsm/mitmproxy and bash all come from homebrew/core), so untap them once up front, before any brew call, in both macOS jobs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dfdc543a..f0b12eac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,6 +94,15 @@ jobs: if: ${{ contains(matrix.os, 'ubuntu') }} run: ./.github/scripts/provision-linux-build.sh + # The macOS runner image pre-taps aws/tap and azure/bicep, which Homebrew + # now flags as untrusted on every `brew install` (including the one inside + # setup-rust-toolchain below). We use neither, so untap them up front to + # keep the logs clean. Guarded so it stays green if an image stops shipping + # them. Must run before any brew install to suppress the warning. + - name: Untap unused Homebrew taps (macOS) + if: ${{ contains(matrix.os, 'macos') }} + run: brew untap aws/tap azure/bicep 2>/dev/null || true + # rust-cache hashes all installed toolchains; the runner image's `stable` # drifts as the image updates, which moves the cache key and causes misses. # Remove it so only the rust-toolchain.toml-pinned version remains. @@ -137,6 +146,16 @@ jobs: "$env:USERPROFILE\.cargo", ` "$env:USERPROFILE\.rustup" -ErrorAction SilentlyContinue + # The macOS runner image pre-taps aws/tap and azure/bicep, which Homebrew + # now flags as untrusted on every `brew install` (including the one inside + # setup-rust-toolchain below and our provision-macos-test.sh). We use + # neither, so untap them up front to keep the logs clean. Guarded so it + # stays green if an image stops shipping them. Must run before any brew + # install to suppress the warning. + - name: Untap unused Homebrew taps (macOS) + if: ${{ contains(matrix.os, 'macos') }} + run: brew untap aws/tap azure/bicep 2>/dev/null || true + # rust-cache hashes all installed toolchains; the runner image's `stable` # drifts as the image updates, which moves the cache key and causes misses. # Remove it so only the rust-toolchain.toml-pinned version remains. From d3623e14a5edbc4ded424bc81ef5594504b03023 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 08:57:49 -0400 Subject: [PATCH 04/10] ci: force-untap azure/bicep so its installed bicep formula doesn't block it brew refuses to untap a tap that has an installed formula without --force, so the previous one-liner untapped aws/tap but left azure/bicep (which ships bicep). The 2>/dev/null also hid the "Refusing to untap" error. Add --force, split to one tap per line so a future missing tap can't abort the other, and drop the stderr suppression so real failures surface. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f0b12eac..088bfa68 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -97,11 +97,15 @@ jobs: # The macOS runner image pre-taps aws/tap and azure/bicep, which Homebrew # now flags as untrusted on every `brew install` (including the one inside # setup-rust-toolchain below). We use neither, so untap them up front to - # keep the logs clean. Guarded so it stays green if an image stops shipping - # them. Must run before any brew install to suppress the warning. + # keep the logs clean. --force because azure/bicep has an installed formula + # (bicep) that brew otherwise refuses to untap; one tap per line so a + # missing tap in a future image can't stop the other. Must run before any + # brew install to suppress the warning. - name: Untap unused Homebrew taps (macOS) if: ${{ contains(matrix.os, 'macos') }} - run: brew untap aws/tap azure/bicep 2>/dev/null || true + run: | + brew untap --force aws/tap || true + brew untap --force azure/bicep || true # rust-cache hashes all installed toolchains; the runner image's `stable` # drifts as the image updates, which moves the cache key and causes misses. @@ -149,12 +153,15 @@ jobs: # The macOS runner image pre-taps aws/tap and azure/bicep, which Homebrew # now flags as untrusted on every `brew install` (including the one inside # setup-rust-toolchain below and our provision-macos-test.sh). We use - # neither, so untap them up front to keep the logs clean. Guarded so it - # stays green if an image stops shipping them. Must run before any brew - # install to suppress the warning. + # neither, so untap them up front to keep the logs clean. --force because + # azure/bicep has an installed formula (bicep) that brew otherwise refuses + # to untap; one tap per line so a missing tap in a future image can't stop + # the other. Must run before any brew install to suppress the warning. - name: Untap unused Homebrew taps (macOS) if: ${{ contains(matrix.os, 'macos') }} - run: brew untap aws/tap azure/bicep 2>/dev/null || true + run: | + brew untap --force aws/tap || true + brew untap --force azure/bicep || true # rust-cache hashes all installed toolchains; the runner image's `stable` # drifts as the image updates, which moves the cache key and causes misses. From 363b04938d79b254ddd5a351112af962482a01ab Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 09:07:33 -0400 Subject: [PATCH 05/10] ci: uninstall bicep before untapping so no --force warning is emitted --force untapped azure/bicep but printed "even though it contains the following installed formulae or casks: bicep". Uninstall bicep (the only formula installed from these taps, and unused by us) first, then untap both taps cleanly without --force. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 088bfa68..8a13e2f7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -96,16 +96,18 @@ jobs: # The macOS runner image pre-taps aws/tap and azure/bicep, which Homebrew # now flags as untrusted on every `brew install` (including the one inside - # setup-rust-toolchain below). We use neither, so untap them up front to - # keep the logs clean. --force because azure/bicep has an installed formula - # (bicep) that brew otherwise refuses to untap; one tap per line so a - # missing tap in a future image can't stop the other. Must run before any - # brew install to suppress the warning. + # setup-rust-toolchain below). We use neither. bicep (from azure/bicep) is + # the only formula installed from them, so uninstall it first; then both + # taps untap cleanly without --force (which would untap but warn about the + # installed formula). || true keeps the step green if a future image no + # longer ships these. Must run before any brew install to suppress the + # warning. - name: Untap unused Homebrew taps (macOS) if: ${{ contains(matrix.os, 'macos') }} run: | - brew untap --force aws/tap || true - brew untap --force azure/bicep || true + brew uninstall bicep || true + brew untap aws/tap || true + brew untap azure/bicep || true # rust-cache hashes all installed toolchains; the runner image's `stable` # drifts as the image updates, which moves the cache key and causes misses. @@ -153,15 +155,17 @@ jobs: # The macOS runner image pre-taps aws/tap and azure/bicep, which Homebrew # now flags as untrusted on every `brew install` (including the one inside # setup-rust-toolchain below and our provision-macos-test.sh). We use - # neither, so untap them up front to keep the logs clean. --force because - # azure/bicep has an installed formula (bicep) that brew otherwise refuses - # to untap; one tap per line so a missing tap in a future image can't stop - # the other. Must run before any brew install to suppress the warning. + # neither. bicep (from azure/bicep) is the only formula installed from + # them, so uninstall it first; then both taps untap cleanly without --force + # (which would untap but warn about the installed formula). || true keeps + # the step green if a future image no longer ships these. Must run before + # any brew install to suppress the warning. - name: Untap unused Homebrew taps (macOS) if: ${{ contains(matrix.os, 'macos') }} run: | - brew untap --force aws/tap || true - brew untap --force azure/bicep || true + brew uninstall bicep || true + brew untap aws/tap || true + brew untap azure/bicep || true # rust-cache hashes all installed toolchains; the runner image's `stable` # drifts as the image updates, which moves the cache key and causes misses. From 47eae1ec320be9d2787c8164155721226e3e9e0f Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 09:14:52 -0400 Subject: [PATCH 06/10] ci: stop systemd docker before starting the tcp daemon in WSL2 setup-wsl v7 provisions the Ubuntu rootfs with systemd enabled, so `apt-get install docker.io` auto-starts docker.service, which holds /var/run/docker.pid and blocks our manual tcp-only dockerd (the one the Windows-side tests connect to). Stop the service and clear the pid file first. On a non-systemd image systemctl is absent, so this is a no-op. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/scripts/init-docker.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/scripts/init-docker.sh b/.github/scripts/init-docker.sh index 46dfeac9..fe4aac6f 100644 --- a/.github/scripts/init-docker.sh +++ b/.github/scripts/init-docker.sh @@ -5,6 +5,13 @@ set -ex apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io +# Installing docker.io enables a systemd docker service. The Ubuntu rootfs that +# setup-wsl v7 provisions has systemd enabled, so that service auto-starts and +# claims /var/run/docker.pid, which blocks the tcp-only daemon below (the one +# the Windows-side tests connect to). Stop it first. On a non-systemd image +# (e.g. setup-wsl v6) systemctl is absent, so this is a harmless no-op. +systemctl stop docker.socket docker.service 2>/dev/null || true +rm -f /var/run/docker.pid nohup dockerd -H tcp://127.0.0.1:2375 >/var/log/dockerd.log 2>&1 & for i in $(seq 1 30); do if docker -H tcp://127.0.0.1:2375 info >/dev/null 2>&1; then From 4bf2a633c95cc3822bd4cc620c6b5058f61cd19b Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 09:44:35 -0400 Subject: [PATCH 07/10] ci: only set up WSL2+Docker on Windows jobs whose tests need Docker Every test file gets its own Windows job, and all ~30 of them ran the WSL2 + dockerd setup (~1 min each), but only 4 test files use Docker. Add a needs_docker flag to the matrix (true for the Docker-backed test files) and gate the Setup WSL2 / Setup Docker steps on it, skipping the setup on the 26 Windows jobs that never touch Docker. Linux uses preinstalled Docker so the flag is a no-op there; macOS has no Docker steps. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/scripts/test-matrix.py | 21 ++++++++++++++++++--- .github/workflows/test.yml | 7 +++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/scripts/test-matrix.py b/.github/scripts/test-matrix.py index 87aab9d5..fc290753 100644 --- a/.github/scripts/test-matrix.py +++ b/.github/scripts/test-matrix.py @@ -5,6 +5,17 @@ MACOS_TESTS = ["network_tests"] +# Test files whose tests need a Docker daemon (Docker-backed managed networks). +# On Windows the daemon runs in WSL2, and that setup (setup-wsl + dockerd) adds +# ~1 min per job, so only these jobs run it. Linux uses its preinstalled Docker, +# so the flag is a no-op there. Keep in sync with the tests that use Docker. +DOCKER_TESTS = [ + "bundle_tests", + "canister_create_tests", + "deploy_tests", + "network_tests", +] + def test_names(): all_files = os.listdir(TEST_DIR) @@ -14,21 +25,25 @@ def test_names(): include = [] for test in test_names(): + needs_docker = test in DOCKER_TESTS # Ubuntu/Windows: run everything include.append({ "test": test, - "os": "ubuntu-22.04" + "os": "ubuntu-22.04", + "needs_docker": needs_docker, }) include.append({ "test": test, - "os": "windows-2025" + "os": "windows-2025", + "needs_docker": needs_docker, }) # macOS: only run selected tests if test in MACOS_TESTS: include.append({ "test": test, - "os": "macos-15" + "os": "macos-15", + "needs_docker": needs_docker, }) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8a13e2f7..b073b960 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -191,14 +191,17 @@ jobs: run: .github/scripts/provision-windows-test.ps1 shell: pwsh + # WSL2 exists solely to host the Docker daemon, so only set it up for the + # Windows jobs whose tests need Docker (matrix.needs_docker). This skips + # ~1 min of setup on the majority of Windows jobs that never use Docker. - name: Setup WSL2 (Windows) - if: ${{ contains(matrix.os, 'windows') }} + if: ${{ contains(matrix.os, 'windows') && matrix.needs_docker }} uses: Vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0 with: distribution: Ubuntu-22.04 - name: Setup Docker in WSL2 (Windows) - if: ${{ contains(matrix.os, 'windows') }} + if: ${{ contains(matrix.os, 'windows') && matrix.needs_docker }} run: .github/scripts/init-docker.sh shell: wsl-bash_Ubuntu-22.04 {0} From 50d448e36fe0cc4b2e98cfa1279f206fb54dc55d Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 09:54:27 -0400 Subject: [PATCH 08/10] ci: drop --verbose from clippy lint step --verbose is a cargo flag that prints the full rustc/clippy-driver command line for every crate compiled, flooding the log without adding any lint detail (diagnostics are printed regardless). Removing it keeps the actual clippy errors easy to find. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 335db6ae..07674138 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -80,7 +80,7 @@ jobs: cache-bin: false - name: Run Lint - run: cargo clippy --verbose --tests --benches -- -D warnings + run: cargo clippy --tests --benches -- -D warnings env: RUST_BACKTRACE: 1 From 39799f19ce7f4e390ebd6ea7c43b45ff0a1a133d Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 10:05:52 -0400 Subject: [PATCH 09/10] Revert "ci: only set up WSL2+Docker on Windows jobs whose tests need Docker" This reverts commit 4bf2a633. The needs_docker gating rested on a wrong assumption. On Windows the local test network itself runs as a Docker container (the native network launcher ships only for darwin/linux), so Docker is the default network backend there -- see network/config.rs: "A Docker container (used on Windows or when explicitly configured)". That means essentially any test that starts a network needs the WSL2+Docker setup, not just the handful of Docker-network test files, so gating it broke many Windows jobs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/scripts/test-matrix.py | 21 +++------------------ .github/workflows/test.yml | 7 ++----- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/.github/scripts/test-matrix.py b/.github/scripts/test-matrix.py index fc290753..87aab9d5 100644 --- a/.github/scripts/test-matrix.py +++ b/.github/scripts/test-matrix.py @@ -5,17 +5,6 @@ MACOS_TESTS = ["network_tests"] -# Test files whose tests need a Docker daemon (Docker-backed managed networks). -# On Windows the daemon runs in WSL2, and that setup (setup-wsl + dockerd) adds -# ~1 min per job, so only these jobs run it. Linux uses its preinstalled Docker, -# so the flag is a no-op there. Keep in sync with the tests that use Docker. -DOCKER_TESTS = [ - "bundle_tests", - "canister_create_tests", - "deploy_tests", - "network_tests", -] - def test_names(): all_files = os.listdir(TEST_DIR) @@ -25,25 +14,21 @@ def test_names(): include = [] for test in test_names(): - needs_docker = test in DOCKER_TESTS # Ubuntu/Windows: run everything include.append({ "test": test, - "os": "ubuntu-22.04", - "needs_docker": needs_docker, + "os": "ubuntu-22.04" }) include.append({ "test": test, - "os": "windows-2025", - "needs_docker": needs_docker, + "os": "windows-2025" }) # macOS: only run selected tests if test in MACOS_TESTS: include.append({ "test": test, - "os": "macos-15", - "needs_docker": needs_docker, + "os": "macos-15" }) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b073b960..8a13e2f7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -191,17 +191,14 @@ jobs: run: .github/scripts/provision-windows-test.ps1 shell: pwsh - # WSL2 exists solely to host the Docker daemon, so only set it up for the - # Windows jobs whose tests need Docker (matrix.needs_docker). This skips - # ~1 min of setup on the majority of Windows jobs that never use Docker. - name: Setup WSL2 (Windows) - if: ${{ contains(matrix.os, 'windows') && matrix.needs_docker }} + if: ${{ contains(matrix.os, 'windows') }} uses: Vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0 with: distribution: Ubuntu-22.04 - name: Setup Docker in WSL2 (Windows) - if: ${{ contains(matrix.os, 'windows') && matrix.needs_docker }} + if: ${{ contains(matrix.os, 'windows') }} run: .github/scripts/init-docker.sh shell: wsl-bash_Ubuntu-22.04 {0} From 6c7c6fe2b58fbe62b88fdc2e9f75cdcffe998324 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 15 Jun 2026 10:24:23 -0400 Subject: [PATCH 10/10] ci: simplify mops/ic-wasm install steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace dfinity/setup-mops with a direct `curl … cli.mops.one/install.sh` call. For our usage the action just wrapped this same script with a Linux/macOS-only package cache and two Node 20 actions (setup-node@v4, cache@v4), which were the remaining "Node.js 20 deprecation" warning at the Complete job step. - Gate mops to non-Windows: the Motoko (moc) tests that need it are all #[cfg(unix)], so Windows never used it. - Fold each tool's verify (which + --version) into its install step, so mops and ic-wasm are one step each instead of two. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8a13e2f7..77fd532c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -205,19 +205,20 @@ jobs: - uses: t1m0thyj/unlock-keyring@cbcf205c879ebd86add70bab3a6abfcce59a5cae # 1.2.0 if: ${{ contains(matrix.os, 'ubuntu') }} + # mops is only needed for the Motoko (moc) tests, which are all + # #[cfg(unix)], so skip it on Windows. Install the CLI directly rather + # than via dfinity/setup-mops, which only wraps this same script with a + # Linux/macOS-only package cache and Node 20 actions (setup-node/cache). - name: Install mops - uses: dfinity/setup-mops@3e94e453352269b34137b5ce49f09a8df81bed7d # v1.4.1 - - - name: Verify mops installation + if: ${{ !contains(matrix.os, 'windows') }} run: | + curl -fsSL cli.mops.one/install.sh | sh which mops mops --version - name: Install ic-wasm - run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/dfinity/ic-wasm/releases/download/0.9.10/ic-wasm-installer.sh | sh - - - name: Verify ic-wasm installation run: | + curl --proto '=https' --tlsv1.2 -LsSf https://github.com/dfinity/ic-wasm/releases/download/0.9.10/ic-wasm-installer.sh | sh which ic-wasm ic-wasm --version