diff --git a/.github/scripts/provision-macos-test.sh b/.github/scripts/provision-macos-test.sh index c263885ad..bf0045c25 100755 --- a/.github/scripts/provision-macos-test.sh +++ b/.github/scripts/provision-macos-test.sh @@ -1,3 +1,8 @@ #!/bin/bash set -euo pipefail brew install softhsm mitmproxy +# The new macOS runner image ships with Homebrew's rustup formula, which places +# /opt/homebrew/bin/cargo as a rustup-init shim. brew install above can activate +# it, shadowing the rustup-managed cargo. Unlink it so setup-rust-toolchain wins. +brew unlink rust || true +brew unlink rustup || true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1a43a0370..082715a3a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: with: # With 'every', a changed file is matched only when it satisfies # ALL rules: the positive pattern AND every negated pattern. - predicate-quantifier: 'every' + predicate-quantifier: "every" filters: | src: - '**' @@ -73,6 +73,10 @@ jobs: if: ${{ contains(matrix.os, 'ubuntu') }} run: ./.github/scripts/provision-linux-build.sh + - name: Setup image (macOS) + if: ${{ contains(matrix.os, 'macos') }} + run: ./.github/scripts/provision-macos-test.sh + - uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4 with: cache-shared-key: ${{ runner.os }}-test @@ -98,10 +102,6 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4 - with: - cache-shared-key: ${{ runner.os }}-test - - name: Setup image (Linux) if: ${{ contains(matrix.os, 'ubuntu') }} run: ./.github/scripts/provision-linux-build.sh && ./.github/scripts/provision-linux-test.sh @@ -115,6 +115,10 @@ jobs: run: .github/scripts/provision-windows-test.ps1 shell: pwsh + - uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4 + with: + cache-shared-key: ${{ runner.os }}-test + - name: Setup WSL2 (Windows) if: ${{ contains(matrix.os, 'windows') }} uses: Vampire/setup-wsl@6a8db447be7ed35f2f499c02c6e60ff77ef11278 # v6.0.0 diff --git a/crates/icp-cli/src/commands/network/ping.rs b/crates/icp-cli/src/commands/network/ping.rs index b5f857336..2f42cd8a9 100644 --- a/crates/icp-cli/src/commands/network/ping.rs +++ b/crates/icp-cli/src/commands/network/ping.rs @@ -5,6 +5,7 @@ use icp::{context::Context, identity::IdentitySelection}; use std::time::Duration; use tokio::time::sleep; use tracing::info; +use url::Url; use super::args::NetworkOrEnvironmentArgs; @@ -15,19 +16,22 @@ Examples: # Ping default 'local' network icp network ping - + # Ping explicit network icp network ping mynetwork - + + # Ping by URL (no project required) + icp network ping http://localhost:4943 + # Ping using environment flag icp network ping -e staging - + # Ping using ICP_ENVIRONMENT variable ICP_ENVIRONMENT=staging icp network ping - + # Name overrides ICP_ENVIRONMENT ICP_ENVIRONMENT=staging icp network ping local - + # Wait until healthy icp network ping --wait-healthy ")] @@ -41,24 +45,31 @@ pub(crate) struct PingArgs { } pub(crate) async fn exec(ctx: &Context, args: &PingArgs) -> Result<(), anyhow::Error> { - // Load project - let _ = ctx.project.load().await?; - - // Convert args to selection and get network - let selection: Result<_, _> = args.network_selection.clone().into(); - let network = ctx.get_network_or_environment(&selection?).await?; - - // NetworkAccess - let access = ctx.network.access(&network).await?; - - // Agent - // TODO We might want to expose the ctx.create_agent function that takes a NetworkAccess - // instead of doing this - let agent = ctx - .get_agent_for_url(&IdentitySelection::Anonymous, &access.api_url) - .await?; - - agent.set_root_key(access.root_key); + let agent = if let Some(ref name) = args.network_selection.name + && let Ok(url) = Url::parse(name) + && (url.scheme() == "http" || url.scheme() == "https") + { + // URL supplied directly: skip project loading + ctx.get_agent_for_url(&IdentitySelection::Anonymous, &url) + .await? + } else { + // Load project + let _ = ctx.project.load().await?; + + // Convert args to selection and get network + let selection: Result<_, _> = args.network_selection.clone().into(); + let network = ctx.get_network_or_environment(&selection?).await?; + + // NetworkAccess + // TODO We might want to expose the ctx.create_agent function that takes a NetworkAccess + // instead of doing this + let access = ctx.network.access(&network).await?; + let agent = ctx + .get_agent_for_url(&IdentitySelection::Anonymous, &access.api_url) + .await?; + agent.set_root_key(access.root_key); + agent + }; // Query let status = match args.wait_healthy { diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 67dcd9c0a..a069aeb19 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -1239,19 +1239,22 @@ Examples: # Ping default 'local' network icp network ping - + # Ping explicit network icp network ping mynetwork - + + # Ping by URL (no project required) + icp network ping http://localhost:4943 + # Ping using environment flag icp network ping -e staging - + # Ping using ICP_ENVIRONMENT variable ICP_ENVIRONMENT=staging icp network ping - + # Name overrides ICP_ENVIRONMENT ICP_ENVIRONMENT=staging icp network ping local - + # Wait until healthy icp network ping --wait-healthy