diff --git a/.github/actions/setup-rust/action.yml b/.github/actions/setup-rust/action.yml index ed23936d..c87da649 100644 --- a/.github/actions/setup-rust/action.yml +++ b/.github/actions/setup-rust/action.yml @@ -59,7 +59,7 @@ runs: with: toolchain: ${{ inputs.toolchain-version }} components: ${{ inputs.components }} - targets: ${{ env.targets }} + targets: ${{ inputs.builder-triple }},${{ inputs.targets }} - name: Cache target/ id: cache-rust-target @@ -70,3 +70,7 @@ runs: key: rust-target-${{ inputs.cache-key }}-${{ inputs.builder-triple }}-${{ inputs.toolchain-version }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: rust-target-${{ inputs.cache-key }}-${{ inputs.builder-triple }}-${{ inputs.toolchain-version }}- + + - name: Set toolchain override + shell: bash + run: rustup override set ${{ inputs.toolchain-version }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c449a185..576852e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,9 @@ on: env: CARGO_TERM_COLOR: always + CARGO_TERM_VERBOSE: true + RUST_BACKTRACE: full + crates_environment: &crates_environment ${{ case(inputs.crates_repo == 'prod', 'crates.io', startsWith(github.ref, 'refs/tags/'), 'crates.io', 'staging.crates.io') }} is_tag_push: ${{ startsWith(github.ref, 'refs/tags/') }} @@ -34,6 +37,11 @@ env: prev_rust: &prev_rust 1.93.1 latest_rust: &latest_rust 1.94.0 + +defaults: + run: + shell: bash + jobs: build_test: strategy: @@ -48,6 +56,10 @@ jobs: runner: linux-arm64-16cpu - triple: aarch64-apple-darwin runner: macos-26 + - triple: x86_64-pc-windows-gnu + runner: windows-8vcpu + - triple: x86_64-pc-windows-msvc + runner: windows-8vcpu toolchain: - version: *prev_rust label: prev @@ -63,6 +75,12 @@ jobs: # status check matching on job name doesn't support regexes, just an exact job name match. name: test (rust ${{ matrix.toolchain.label }}, ${{ matrix.target.triple }}) runs-on: ${{ matrix.target.runner }} + + env: + COMMON_FLAGS: --all-features --workspace + CARGO_BUILD_TARGET: ${{ matrix.target.triple }} + is_windows_gnu: ${{ endsWith(matrix.target.triple, '-windows-gnu') }} + steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -75,28 +93,36 @@ jobs: components: clippy - name: Lint lib targets (cargo clippy) run: |- - cargo +${{ matrix.toolchain.version }} clippy \ - --all-features --workspace --no-deps \ + cargo clippy \ + $COMMON_FLAGS \ + --no-deps \ --lib \ - --target ${{ matrix.target.triple }} \ -- -D warnings - # These are separated from `--lib` to avoid enforcing missing docs in targets that - # can't become part of public API + # These are separated from `--lib` to avoid enforcing missing docs in targets that + # can't become part of public API - name: Lint other targets (cargo clippy) run: |- - cargo +${{ matrix.toolchain.version }} clippy \ - --all-features --workspace --no-deps \ + cargo clippy \ + $COMMON_FLAGS \ + --no-deps \ --bins --tests --benches --examples \ - --target ${{ matrix.target.triple }} \ -- -D warnings -A missing_docs - name: Build (cargo build) - run: cargo +${{ matrix.toolchain.version }} build --all-features --workspace --verbose --all-targets --target ${{ matrix.target.triple }} - - name: Test (cargo test) - run: cargo +${{ matrix.toolchain.version }} test --all-features --workspace --verbose --target ${{ matrix.target.triple }} + run: cargo build $COMMON_FLAGS --all-targets + + # `ts_python` has the same lib name as the `tailscale` root crate, which again appears + # to just be an issue on `*-windows-gnu` targets, so don't test it here (depend on + # python tests instead). + - name: Test (cargo test), --all-features + run: |- + cargo test \ + $COMMON_FLAGS \ + ${{ case(env.is_windows_gnu == 'true', '--exclude ts_python', '') }} + - name: Release build (cargo build --release) - run: cargo +${{ matrix.toolchain.version }} build --all-features --workspace --release --verbose --all-targets --target ${{ matrix.target.triple }} + run: cargo build $COMMON_FLAGS --release --all-targets - name: Docs (cargo doc) - run: cargo +${{ matrix.toolchain.version }} doc --workspace --no-deps --all-features --target ${{ matrix.target.triple }} + run: cargo doc $COMMON_FLAGS --no-deps arch_independent: name: arch-independent checks @@ -113,7 +139,7 @@ jobs: components: rustfmt - &binstall name: binstall - uses: cargo-bins/cargo-binstall@main + uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 #v1.18.1 - name: Install cargo-deny run: command -v cargo-deny || cargo binstall --no-confirm cargo-deny - &cargo_ws @@ -126,7 +152,7 @@ jobs: - name: Dependency audit (cargo deny) run: cargo deny --workspace --all-features check all - name: Check formatting (cargo fmt) - run: cargo +nightly fmt --check + run: cargo fmt --check - name: Custom workspace checks run: cargo run -p checks - &dry_publish diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 9fb65e80..42f386d1 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -82,7 +82,7 @@ jobs: uses: ./.github/actions/setup-rust with: toolchain-version: ${{ matrix.rust_toolchain.version }} - builder-triple: x86_64-linux-unknown-gnu + builder-triple: x86_64-unknown-linux-gnu - name: Install dependencies run: mix deps.get diff --git a/Cargo.lock b/Cargo.lock index 087427d4..25e2ef7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4142,6 +4142,7 @@ dependencies = [ name = "ts_cli_util" version = "0.2.0" dependencies = [ + "cfg-if", "clap", "futures-util", "tailscale", diff --git a/rust-toolchain.toml b/rust-toolchain.toml index cf06b692..0d8ed42d 100755 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,3 @@ [toolchain] channel = "1.94.0" -targets = ["armv7-unknown-linux-gnueabihf"] components = ["rustfmt", "clippy"] diff --git a/ts_cli_util/Cargo.toml b/ts_cli_util/Cargo.toml index 7596c3cb..46a30d74 100644 --- a/ts_cli_util/Cargo.toml +++ b/ts_cli_util/Cargo.toml @@ -19,11 +19,14 @@ ts_netcheck.workspace = true ts_transport_derp.workspace = true # Unconditionally required dependencies. +cfg-if.workspace = true clap = { workspace = true, features = ["derive", "env"] } futures-util.workspace = true tracing.workspace = true tracing-subscriber = { version = "0.3", features = ["env-filter", "tracing-log"] } + +[target.'cfg(not(all(target_os = "windows", target_env = "gnu")))'.dependencies] # Required dependencies for the "tracy" feature. tracy-client = { version = "0.18", optional = true } tracing-tracy = { version = "0.11", optional = true } diff --git a/ts_cli_util/src/lib.rs b/ts_cli_util/src/lib.rs index e439c9a7..f126306f 100644 --- a/ts_cli_util/src/lib.rs +++ b/ts_cli_util/src/lib.rs @@ -11,6 +11,7 @@ use ts_transport_derp::{RegionId, ServerConnInfo}; /// Result with a boxed [`core::error::Error`] trait object. pub type Result = core::result::Result>; +#[cfg(not(all(target_os = "windows", target_env = "gnu")))] #[cfg(feature = "tracy")] #[global_allocator] static GLOBAL_ALLOC: tracy_client::ProfiledAllocator = @@ -93,7 +94,13 @@ pub fn init_tracing() { #[cfg(feature = "tracy")] { - layers.push(tracing_tracy::TracyLayer::default().boxed()); + cfg_if::cfg_if! { + if #[cfg(not(all(target_os = "windows", target_env = "gnu")))] { + layers.push(tracing_tracy::TracyLayer::default().boxed()); + } else { + eprintln!("warning: ts_cli_util/tracy feature enabled but this is a noop on *-windows-gnu"); + } + } } tracing_subscriber::registry().with(layers).init(); diff --git a/ts_time/src/lib.rs b/ts_time/src/lib.rs index 82978702..c3faabd6 100644 --- a/ts_time/src/lib.rs +++ b/ts_time/src/lib.rs @@ -26,8 +26,14 @@ impl TimeRange { } /// Return a time range centered on `t`, with `plus_minus` time on either side. + /// + /// If `t` can't add or subtract `plus_minus`, the respective end of the range is + /// clamped to `t` instead. pub fn new_around(t: Instant, plus_minus: Duration) -> Self { - Self::new(t - plus_minus, t + plus_minus) + Self::new( + t.checked_sub(plus_minus).unwrap_or(t), + t.checked_add(plus_minus).unwrap_or(t), + ) } /// The first [`Instant`] that the interval covers.