fix(iroh): add global address validation token store #17789
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| types: ["labeled", "unlabeled", "opened", "synchronize", "reopened"] | |
| merge_group: | |
| push: | |
| branches: | |
| - main | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| RUST_BACKTRACE: 1 | |
| RUSTFLAGS: -Dwarnings | |
| RUSTDOCFLAGS: -Dwarnings | |
| MSRV: "1.91" | |
| SCCACHE_CACHE_SIZE: "10G" | |
| IROH_FORCE_STAGING_RELAYS: "1" | |
| jobs: | |
| pick-runner: | |
| uses: "./.github/workflows/pick-runner.yml" | |
| with: | |
| min_free_runners: 3 | |
| secrets: | |
| RUNNER_READ_TOKEN: ${{ secrets.RUNNER_READ_TOKEN }} | |
| tests: | |
| name: CI Test Suite | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| uses: "./.github/workflows/tests.yaml" | |
| cross_build: | |
| name: Cross Build Only | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| timeout-minutes: 30 | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_1) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTFLAGS: "-Dwarnings --cfg skip_patchbay" | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| # cross tests are currently broken vor armv7 and aarch64 | |
| # see https://github.com/cross-rs/cross/issues/1311 | |
| # - armv7-linux-androideabi | |
| # - aarch64-linux-android | |
| # Freebsd execution fails in cross | |
| # - i686-unknown-freebsd # Linking fails :/ | |
| - x86_64-unknown-freebsd | |
| # Netbsd execution fails to link in cross | |
| # - x86_64-unknown-netbsd | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - name: Install rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cleanup Docker | |
| continue-on-error: true | |
| run: | | |
| docker kill $(docker ps -q) | |
| # See https://github.com/cross-rs/cross/issues/1222 | |
| - name: Cache cross | |
| id: cache-cross | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cargo/bin/cross | |
| key: cross-${{ runner.os }}-${{ runner.arch }} | |
| - name: Install cross | |
| if: steps.cache-cross.outputs.cache-hit != 'true' | |
| uses: taiki-e/install-action@cross | |
| - name: build | |
| # cross tests are currently broken vor armv7 and aarch64 | |
| # see https://github.com/cross-rs/cross/issues/1311. So on | |
| # those platforms we only build but do not run tests. | |
| run: cross build --all --target ${{ matrix.target }} | |
| env: | |
| RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}} | |
| CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: cc | |
| android: | |
| name: Android Build & Test | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| timeout-minutes: 60 | |
| # runs-on: [self-hosted, linux, X64] | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_2) }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: aarch64-linux-android | |
| - target: armv7-linux-androideabi | |
| - target: x86_64-linux-android | |
| api-level: 35 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Enable KVM for nested virtualization | |
| if: matrix.target == 'x86_64-linux-android' | |
| run: | | |
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666"' \ | |
| | sudo tee /etc/udev/rules.d/99-kvm4all.rules | |
| sudo udevadm control --reload-rules | |
| sudo udevadm trigger --name-match=kvm | |
| - name: Set up Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| target: ${{ matrix.target }} | |
| - name: Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: "temurin" | |
| java-version: "17" | |
| - name: Setup Android SDK | |
| uses: android-actions/setup-android@v4 | |
| # Pinned to a release tag (rather than @main) for supply-chain hygiene. | |
| - name: Setup Android NDK | |
| uses: nttld/setup-ndk@v1 | |
| id: setup-ndk | |
| with: | |
| ndk-version: r25c | |
| add-to-path: true | |
| - name: Install cargo-ndk | |
| run: cargo install --version 4.1.2 cargo-ndk | |
| # Replace cargo-ndk-runner with a wrapper that forwards RUST_LOG | |
| # and RUST_BACKTRACE into the emulator shell. The upstream binary | |
| # does `adb shell <bin>` without inheriting any host env. | |
| - name: Wrap cargo-ndk-runner to forward logging env | |
| if: matrix.target == 'x86_64-linux-android' | |
| run: | | |
| cat > "$(which cargo-ndk-runner)" <<'WRAPPER' | |
| #!/bin/sh | |
| set -e | |
| dev=/data/local/tmp/$(basename "$1") | |
| adb push "$1" "$dev" >/dev/null | |
| adb shell chmod 755 "$dev" | |
| shift | |
| adb shell "RUST_LOG=$RUST_LOG RUST_BACKTRACE=$RUST_BACKTRACE $dev $*" | |
| WRAPPER | |
| chmod +x "$(which cargo-ndk-runner)" | |
| - name: Build | |
| if: matrix.target != 'x86_64-linux-android' | |
| env: | |
| ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} | |
| run: cargo ndk --target ${{ matrix.target }} build | |
| # Build all the test binaries up front so the emulator boot can | |
| # overlap with compilation. cargo-ndk runs `cargo test --no-run` | |
| # against each crate; the binaries land in | |
| # target/$CARGO_NDK_TARGET/debug/deps/. | |
| - name: Build workspace test binaries | |
| if: matrix.target == 'x86_64-linux-android' | |
| env: | |
| ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} | |
| CARGO_NDK_TARGET: ${{ matrix.target }} | |
| run: | | |
| cargo ndk test --no-run -p iroh-base --all-features | |
| cargo ndk test --no-run -p iroh-dns --features tls-ring | |
| cargo ndk test --no-run -p iroh-relay --features tls-ring,metrics | |
| cargo ndk test --no-run -p iroh --features tls-ring,metrics,portmapper,test-utils | |
| - name: Run workspace tests on Android emulator | |
| if: matrix.target == 'x86_64-linux-android' | |
| uses: reactivecircus/android-emulator-runner@v2 | |
| env: | |
| ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} | |
| # Forwarded into the emulator by the cargo-ndk-runner wrapper. | |
| RUST_LOG: trace | |
| RUST_BACKTRACE: "1" | |
| CARGO_NDK_TARGET: ${{ matrix.target }} | |
| with: | |
| api-level: ${{ matrix.api-level }} | |
| arch: x86_64 | |
| target: google_apis | |
| force-avd-creation: false | |
| # `-dns-server` + `-netfast` + `-no-metrics` is the combination reported to give | |
| # working public-internet connectivity on the GH-hosted runner; without them wlan0 | |
| # stays NO-CARRIER and every connect() to a public IP fails with ENETUNREACH. | |
| # See https://github.com/ReactiveCircus/android-emulator-runner/issues/348#issuecomment-2578082030 | |
| emulator-options: -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect -dns-server 8.8.8.8 -netfast -no-metrics | |
| disable-animations: true | |
| script: | | |
| adb wait-for-device | |
| # Wait for full boot and a working outbound TCP. `sys.boot_completed=1` fires | |
| # before the radio/Wi-Fi stack comes up, and `ip route get 8.8.8.8` reports | |
| # success while the kernel's per-network fwmark route is still missing. Probe | |
| # an actual TCP connect to 8.8.8.8:53 instead - it exercises the same path | |
| # the test sockets will use. | |
| adb shell 'i=0; while [ -z "$(getprop sys.boot_completed | tr -d "\r")" ]; do i=$((i+1)); if [ $i -gt 300 ]; then exit 1; fi; sleep 2; done' | |
| adb shell 'i=0; while ! nc -w 2 8.8.8.8 53 </dev/null >/dev/null 2>&1; do i=$((i+1)); if [ $i -gt 30 ]; then exit 1; fi; sleep 2; done' | |
| # Disable IPv6: the emulator has site-local + link-local v6 but no global v6 | |
| # route, so connect() to a global v6 address hangs instead of returning ENETUNREACH. | |
| adb root && adb wait-for-device | |
| adb shell sysctl -w net.ipv6.conf.all.disable_ipv6=1 || true | |
| adb shell sysctl -w net.ipv6.conf.default.disable_ipv6=1 || true | |
| adb shell sysctl -w net.ipv6.conf.lo.disable_ipv6=1 || true | |
| adb shell ip addr | |
| cargo ndk test -p iroh-base --all-features | |
| cargo ndk test -p iroh-dns --features tls-ring | |
| cargo ndk test -p iroh-relay --features tls-ring,metrics | |
| cargo ndk test -p iroh --features tls-ring,metrics,portmapper,test-utils | |
| cross_test: | |
| name: Cross Test | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| timeout-minutes: 30 | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_3) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - i686-unknown-linux-gnu | |
| env: | |
| RUSTFLAGS: "-Dwarnings --cfg skip_patchbay" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - name: Install rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cleanup Docker | |
| continue-on-error: true | |
| run: | | |
| docker kill $(docker ps -q) | |
| # See https://github.com/cross-rs/cross/issues/1222 | |
| - name: Cache cross | |
| id: cache-cross | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cargo/bin/cross | |
| key: cross-${{ runner.os }}-${{ runner.arch }} | |
| - name: Install cross | |
| if: steps.cache-cross.outputs.cache-hit != 'true' | |
| uses: taiki-e/install-action@cross | |
| - name: test | |
| run: cross test --all --target ${{ matrix.target }} -- --test-threads=12 | |
| env: | |
| RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG' }} | |
| CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: cc | |
| wasm_test: | |
| name: Build & test wasm32 for browsers | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_4) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTFLAGS: '--cfg getrandom_backend="wasm_js"' | |
| steps: | |
| - name: Checkout sources | |
| uses: actions/checkout@v6 | |
| - name: Setup node.js version 22.5 # needed for browser-like websocket API support in node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22.5 | |
| - name: Install stable toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Add wasm target | |
| run: rustup target add wasm32-unknown-unknown | |
| - name: Install cargo-binstall | |
| uses: cargo-bins/cargo-binstall@v1.18.1 | |
| - name: Install wasm-bindgen-test-runner | |
| # Match the version of wasm-bindgen used in Cargo.lock | |
| run: cargo binstall wasm-bindgen-cli@0.2.122 --locked --no-confirm | |
| - name: Install wasm-tools | |
| uses: bytecodealliance/actions/wasm-tools/setup@v1 | |
| - name: wasm32 build (iroh-base) | |
| run: cargo build --target wasm32-unknown-unknown -p iroh-base --all-features | |
| - name: wasm32 build (iroh-relay) | |
| run: cargo build --target wasm32-unknown-unknown -p iroh-relay | |
| - name: wasm32 build (iroh) | |
| run: cargo build --target wasm32-unknown-unknown -p iroh | |
| # If the Wasm file contains any 'import "env"' declarations, then | |
| # some non-Wasm-compatible code made it into the final code. | |
| - name: Ensure no 'import "env"' in iroh-relay Wasm | |
| run: | | |
| ! wasm-tools print --skeleton target/wasm32-unknown-unknown/debug/iroh_relay.wasm | grep 'import "env"' | |
| - name: Ensure no 'import "env"' in iroh Wasm | |
| run: | | |
| ! wasm-tools print --skeleton target/wasm32-unknown-unknown/debug/iroh.wasm | grep 'import "env"' | |
| - name: Run integration test in wasm | |
| run: cargo test -p iroh --test integration --target=wasm32-unknown-unknown | |
| check_semver: | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_5) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTC_WRAPPER: "sccache" | |
| SCCACHE_GHA_ENABLED: "on" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| continue-on-error: true | |
| - uses: ./.github/workflows/sccache-probe | |
| - name: Setup Environment (PR) | |
| if: ${{ github.event_name == 'pull_request' }} | |
| shell: bash | |
| run: | | |
| echo "HEAD_COMMIT_SHA=$(git rev-parse origin/${{ github.base_ref }})" >> ${GITHUB_ENV} | |
| - name: Setup Environment (Push) | |
| if: ${{ github.event_name == 'push' || github.event_name == 'merge_group' }} | |
| shell: bash | |
| run: | | |
| echo "HEAD_COMMIT_SHA=$(git rev-parse origin/main)" >> ${GITHUB_ENV} | |
| - name: Check semver | |
| # uses: obi1kenobi/cargo-semver-checks-action@v2 | |
| uses: n0-computer/cargo-semver-checks-action@feat-baseline | |
| with: | |
| package: iroh, iroh-base, iroh-dns-server, iroh-relay, iroh-net-report | |
| baseline-rev: ${{ env.HEAD_COMMIT_SHA }} | |
| use-cache: false | |
| check_external_types: | |
| timeout-minutes: 30 | |
| name: Check external types in public API | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_9) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTC_WRAPPER: "sccache" | |
| SCCACHE_GHA_ENABLED: "on" | |
| # The tool drives an internal rustdoc invocation that only emits JSON | |
| # for the analyzer, so the workflow-wide `-Dwarnings` would just turn | |
| # unrelated rustdoc lints (e.g. `private-intra-doc-links`) into hard | |
| # failures here. Clear it for this job. | |
| RUSTDOCFLAGS: "" | |
| # Pin to the nightly that the pinned `cargo-check-external-types` | |
| # release was last tested against. Update both together. | |
| CARGO_CHECK_EXTERNAL_TYPES_VERSION: "0.4.0" | |
| TOOLCHAIN: "nightly-2025-10-18" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ env.TOOLCHAIN }} | |
| - name: Install sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Install cargo-binstall | |
| uses: cargo-bins/cargo-binstall@v1.18.1 | |
| - uses: taiki-e/install-action@cargo-make | |
| - name: Install cargo-check-external-types | |
| run: cargo binstall cargo-check-external-types@${{ env.CARGO_CHECK_EXTERNAL_TYPES_VERSION }} --locked --no-confirm | |
| - name: Check external types | |
| run: cargo make check-external-types | |
| check_fmt: | |
| timeout-minutes: 30 | |
| name: Checking fmt | |
| runs-on: ubuntu-latest | |
| env: | |
| RUSTC_WRAPPER: "sccache" | |
| SCCACHE_GHA_ENABLED: "on" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt | |
| - uses: mozilla-actions/sccache-action@v0.0.10 | |
| continue-on-error: true | |
| - uses: ./.github/workflows/sccache-probe | |
| - uses: taiki-e/install-action@cargo-make | |
| - run: cargo make format-check | |
| check_docs: | |
| timeout-minutes: 30 | |
| name: Checking docs | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_6) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTC_WRAPPER: "sccache" | |
| SCCACHE_GHA_ENABLED: "on" | |
| RUSTDOCFLAGS: --cfg docsrs | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: nightly-2025-10-09 | |
| - name: Install sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| continue-on-error: true | |
| - uses: ./.github/workflows/sccache-probe | |
| - name: Docs | |
| run: cargo doc --workspace --all-features --no-deps --document-private-items | |
| clippy_check: | |
| timeout-minutes: 30 | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_7) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTC_WRAPPER: "sccache" | |
| SCCACHE_GHA_ENABLED: "on" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - name: Install sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| continue-on-error: true | |
| - uses: ./.github/workflows/sccache-probe | |
| # TODO: We have a bunch of platform-dependent code so should | |
| # probably run this job on the full platform matrix | |
| - name: clippy check (all features) | |
| run: cargo clippy --workspace --all-features --all-targets --lib --bins --tests --benches --examples | |
| - name: clippy check (no features) | |
| run: cargo clippy --workspace --no-default-features --all-targets --lib --bins --tests --benches --examples | |
| - name: clippy check (default features) | |
| run: cargo clippy --workspace --all-targets --lib --bins --tests --benches --examples | |
| check_optional_deps: | |
| timeout-minutes: 10 | |
| name: Check optional deps are absent without features | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Verify optional deps are absent without features | |
| run: | | |
| fail=0 | |
| for dep in portmapper igd-next swarm-discovery ring aws-lc-rs; do | |
| echo "cargo tree -p iroh --no-default-features --edges normal --target all -i $dep"; | |
| output=$(cargo tree -p iroh --no-default-features --edges normal --target all -i "$dep" 2>&1) || true | |
| if ! echo "$output" | grep -qE "(nothing to print|did not match any packages)"; then | |
| echo "ERROR: $dep should not be in the dependency tree without its feature" | |
| echo "$output" | |
| fail=1 | |
| fi | |
| done | |
| exit $fail | |
| msrv: | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| timeout-minutes: 30 | |
| name: Minimal Supported Rust Version | |
| needs: pick-runner | |
| runs-on: ${{ fromJSON(needs.pick-runner.outputs.overflow_8) }} | |
| # runs-on: [self-hosted, linux, X64] | |
| env: | |
| RUSTC_WRAPPER: "sccache" | |
| SCCACHE_GHA_ENABLED: "on" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ env.MSRV }} | |
| - name: Install sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| continue-on-error: true | |
| - uses: ./.github/workflows/sccache-probe | |
| - name: Check MSRV all features | |
| run: | | |
| cargo +$MSRV check --workspace --all-targets | |
| cargo_deny: | |
| timeout-minutes: 30 | |
| name: cargo deny | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: EmbarkStudios/cargo-deny-action@v2 | |
| with: | |
| arguments: --workspace --all-features | |
| command: check | |
| command-arguments: "-Dwarnings" | |
| netsim-integration-tests: | |
| permissions: write-all | |
| if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" | |
| uses: "./.github/workflows/netsim_runner.yaml" | |
| secrets: inherit | |
| with: | |
| branch: ${{ github.ref }} | |
| max_workers: 6 | |
| netsim_branch: "main" | |
| sim_paths: ${{ github.event_name == 'pull_request' && 'sims/integration' || 'sims/iroh/iroh.json,sims/integration' }} | |
| pr_number: ${{ github.event.pull_request.number || '' }} | |
| filter: ${{ github.event_name == 'pull_request' && 'skip:intg_iroh_full__1_to_3,intg_iroh_full__1_to_1x3,intg_iroh_relay_only__1_to_3' || '' }} | |
| codespell: | |
| timeout-minutes: 30 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Cache pip | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: pip-codespell-2.4.1 | |
| - run: pip install --user codespell[toml]==2.4.1 | |
| - run: codespell --ignore-words-list=ans,atmost,crate,inout,ratatui,ser,stayin,swarmin,worl,keep-alives --skip=CHANGELOG.md |