diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 817170ece83..7a43f42d0fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -271,6 +271,56 @@ jobs: 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" + CARGO_CHECK_EXTERNAL_TYPES_NIGHTLY: "nightly-2025-10-18" + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.CARGO_CHECK_EXTERNAL_TYPES_NIGHTLY }} + - name: Install sccache + uses: mozilla-actions/sccache-action@v0.0.9 + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@v1.18.1 + + - name: Install cargo-check-external-types + # Match the version of wasm-bindgen used in Cargo.lock + run: cargo binstall cargo-check-external-types@${{ env.CARGO_CHECK_EXTERNAL_TYPES_VERSION }} --locked --no-confirm + + - name: Check external types + run: | + set -e + fail=0 + for crate in iroh-base iroh-dns iroh-relay iroh iroh-dns-server; do + echo "::group::$crate" + if ! cargo check-external-types \ + --manifest-path "$crate/Cargo.toml" \ + --config external-types.toml \ + --all-features; then + fail=1 + fi + echo "::endgroup::" + done + exit $fail + check_fmt: timeout-minutes: 30 name: Checking fmt diff --git a/external-types.toml b/external-types.toml new file mode 100644 index 00000000000..716e1cb5263 --- /dev/null +++ b/external-types.toml @@ -0,0 +1,45 @@ +# List of types from foreign crates allowed to appear in our public APIs. +# +# This can be used with `cargo check-external-types` to ensure that no other +# items than the ones allow-listed here appear in our public APIs. A semver-breaking +# update to any crate listed here automatically becomes a semver-breaking update +# to one of our workspace crates. +# +# There's a `check_external_types` CI job that fails when any foreign item not listed +# here appears in the public API of a workspace crate. + +allowed_external_types = [ + # workspace crates + "iroh_base::*", + "iroh_dns::*", + "iroh_relay::*", + + # 1.0 crates that we deem fine to be part of the public API + "bytes::*", + "http::*", + "http_body::*", + "hyper::*", + "rustls_pki_types::*", + "serde::*", + "serde_core::*", + "tokio::*", + "url::*", + + # crates owned by us that will move to 1.0 as well + "iroh_metrics::*", + "n0_error::*", + "n0_watcher::*", + "noq::*", + "noq_proto::*", + "noq_udp::*", + "portmapper::metrics::Metrics", + + # non-1.0 crates that we decided to accept in the public API + "rustls::*", + "tokio_rustls::*", + "futures_core::stream::Stream", + "futures_sink::Sink", + # these are only type aliases + "futures_lite::future::Boxed", + "futures_lite::stream::Boxed", +]