Files
firezone/.github/workflows/_rust.yml
Thomas Eizinger 2c26fc9c0e ci: lint Rust dependencies using cargo deny (#7390)
One of Rust's promises is "if it compiles, it works". However, there are
certain situations in which this isn't true. In particular, when using
dynamic typing patterns where trait objects are downcast to concrete
types, having two versions of the same dependency can silently break
things.

This happened in #7379 where I forgot to patch a certain Sentry
dependency. A similar problem exists with our `tracing-stackdriver`
dependency (see #7241).

Lastly, duplicate dependencies increase the compile-times of a project,
so we should aim for having as few duplicate versions of a particular
dependency as possible in our dependency graph.

This PR introduces `cargo deny`, a linter for Rust dependencies. In
addition to linting for duplicate dependencies, it also enforces that
all dependencies are compatible with an allow-list of licenses and it
warns when a dependency is referred to from multiple crates without
introducing a workspace dependency. Thanks to existing tooling
(https://github.com/mainmatter/cargo-autoinherit), transitioning all
dependencies to workspace dependencies was quite easy.

Resolves: #7241.
2024-11-22 00:17:28 +00:00

187 lines
6.4 KiB
YAML

---
name: Rust
"on":
workflow_call:
defaults:
run:
working-directory: ./rust
permissions:
contents: "read"
id-token: "write"
# Never tolerate warnings. Duplicated in `_tauri.yml`
env:
RUSTFLAGS: "-Dwarnings --cfg tokio_unstable"
RUSTDOCFLAGS: "-D warnings"
jobs:
bench:
name: bench-${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
runs-on: [
windows-2019, # Only platform with a benchmark right now
]
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust
id: setup-rust
- run: cargo bench ${{ steps.setup-rust.outputs.bench-packages }}
env:
RUST_LOG: "debug"
name: "cargo bench"
shell: bash
static-analysis:
name: static-analysis-${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
# TODO: https://github.com/rust-lang/cargo/issues/5220
runs-on: [ubuntu-22.04, macos-14, windows-2022]
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust
id: setup-rust
- uses: ./.github/actions/setup-tauri-v2
timeout-minutes: 5
- uses: taiki-e/install-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tool: cargo-udeps,cargo-deny
- run: |
rustup install --no-self-update nightly-2024-09-01 --profile minimal # The exact nightly version doesn't matter, just pin a random one.
cargo +nightly-2024-09-01 udeps --all-targets --all-features ${{ steps.setup-rust.outputs.packages }}
name: Check for unused dependencies
- run: cargo fmt -- --check
- run: cargo doc --all-features --no-deps --document-private-items ${{ steps.setup-rust.outputs.packages }}
name: "cargo doc"
shell: bash
- run: cargo clippy --all-targets --all-features ${{ steps.setup-rust.outputs.packages }}
name: "cargo clippy"
shell: bash
- run: cargo deny check --hide-inclusion-graph
shell: bash
test:
name: test-${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
# TODO: https://github.com/rust-lang/cargo/issues/5220
runs-on:
[
ubuntu-22.04,
ubuntu-24.04,
macos-13,
macos-14,
windows-2019,
windows-2022,
]
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust
id: setup-rust
- uses: ./.github/actions/setup-tauri-v2
- uses: taiki-e/install-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tool: ripgrep
- name: "cargo test"
shell: bash
run: |
set -x
# First, run all tests.
cargo test --all-features ${{ steps.setup-rust.outputs.packages }} -- --include-ignored --nocapture
# Poor man's test coverage testing: Grep the generated logs for specific patterns / lines.
rg --count --no-ignore SendIcmpPacket $TESTCASES_DIR
rg --count --no-ignore SendUdpPacket $TESTCASES_DIR
rg --count --no-ignore SendTcpPayload $TESTCASES_DIR
rg --count --no-ignore SendDnsQueries $TESTCASES_DIR
rg --count --no-ignore "Packet for DNS resource" $TESTCASES_DIR
rg --count --no-ignore "Packet for CIDR resource" $TESTCASES_DIR
rg --count --no-ignore "Packet for Internet resource" $TESTCASES_DIR
rg --count --no-ignore "Performed IP-NAT46" $TESTCASES_DIR
rg --count --no-ignore "Performed IP-NAT64" $TESTCASES_DIR
rg --count --no-ignore "Too big DNS response, truncating" $TESTCASES_DIR
env:
# <https://github.com/rust-lang/cargo/issues/5999>
# Needed to create tunnel interfaces in unit tests
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER: "sudo --preserve-env"
PROPTEST_VERBOSE: 0 # Otherwise the output is very long.
PROPTEST_CASES: 2000 # Default is only 256.
CARGO_PROFILE_TEST_OPT_LEVEL: 1 # Otherwise the tests take forever.
TESTCASES_DIR: "connlib/tunnel/testcases"
# Runs the Tauri client smoke test, built in debug mode. We can't run it in release
# mode because of a known issue: <https://github.com/firezone/firezone/blob/456e044f882c2bb314e19cc44c0d19c5ad817b7c/rust/windows-client/src-tauri/src/client.rs#L162-L164>
gui-smoke-test:
name: gui-smoke-test-${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
runs-on: [ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022]
runs-on: ${{ matrix.runs-on }}
defaults:
run:
# Must be in this dir for `pnpm` to work
working-directory: ./rust/gui-client
# The Windows client ignores RUST_LOG because it uses a settings file instead
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-node
- uses: ./.github/actions/setup-rust
- uses: ./.github/actions/setup-tauri-v2
timeout-minutes: 5
with:
runtime: true
# These steps must be synchronized with build.sh and build.bat in `rust/gui-client`
- name: pnpm install
run: |
pnpm install
cp "node_modules/flowbite/dist/flowbite.min.js" "src/"
- name: Compile Tailwind
run: pnpm tailwindcss -i src/input.css -o src/output.css
- name: Run Vite bundler
run: pnpm vite build
- name: Build client
run: cargo build -p firezone-gui-client --all-targets
- uses: taiki-e/install-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tool: dump_syms
- name: Run smoke test
working-directory: ./rust
run: cargo run -p gui-smoke-test
headless-client:
name: headless-client-${{ matrix.test }}-${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
# TODO: Add Windows as part of issue #3782
runs-on: [ubuntu-22.04, ubuntu-24.04]
test: [linux-group, token-path]
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust
- uses: ./.github/actions/setup-tauri-v2
timeout-minutes: 5
- run: scripts/tests/${{ matrix.test }}.sh
name: "test script"
shell: bash
working-directory: ./