diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 00000000..0ace9471 --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,46 @@ +name: Dependency audit + +# `Cargo.lock` is not in the repository. Each run resolves the newest +# compatible versions. A scheduled run finds new advisories and yanked +# crates even when no one changes the code. +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + schedule: + - cron: "0 6 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + deny: + name: cargo deny + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run cargo-deny + uses: EmbarkStudios/cargo-deny-action@v2 + with: + command: check + arguments: --all-features + + audit: + name: cargo audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Install cargo-audit + uses: taiki-e/install-action@v2 + with: + tool: cargo-audit + - name: Create lockfile + run: cargo generate-lockfile + - name: Run cargo-audit + # Unmaintained crates give a warning only. Vulnerabilities fail the job + # by default. Yanked and unsound crates also fail the job. + run: cargo audit --deny yanked --deny unsound diff --git a/CHANGELOG.md b/CHANGELOG.md index ee8a8742..17cbef8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- A `Dependency audit` CI workflow runs `cargo deny` and `cargo audit` on each push and pull request, and every week. It fails when a dependency has a known vulnerability, is yanked, uses a license that is not allowed, or comes from an unknown source. The `deny.toml` file holds the rules. + ### Fixed - The ndarray implementation of `Array2::from_iterator` now preserves column-major input order, including for rectangular matrices that previously caused a panic. Column-major input produces a column-major array (#482). diff --git a/Cargo.toml b/Cargo.toml index 4ec3a4b5..1982de9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,8 @@ exclude = [ "smartcore.iml", "smartcore.svg", "tests/", - "AGENTS.md" + "AGENTS.md", + "deny.toml" ] [dependencies] diff --git a/deny.toml b/deny.toml new file mode 100644 index 00000000..a1e7afe2 --- /dev/null +++ b/deny.toml @@ -0,0 +1,35 @@ +# Configuration for cargo-deny. +# Documentation: https://embarkstudios.github.io/cargo-deny/ +# +# Run locally with: cargo deny --all-features check + +[graph] +all-features = true + +[advisories] +# Fail if a dependency is yanked. A yanked version can have a known defect. +yanked = "deny" +ignore = [ + # `atomic-polyfill` is unmaintained. It enters the graph only through + # `postcard` -> `heapless`, and `postcard` is a dev-dependency. + # Remove this entry when `postcard` stops using `heapless` 0.7. + { id = "RUSTSEC-2023-0089", reason = "Dev-dependency only (postcard -> heapless). Not in the published crate." }, +] + +[licenses] +# Licenses that dependencies can use. `smartcore` is Apache-2.0. +allow = [ + "Apache-2.0", + "MIT", + "Unicode-3.0", +] + +[bans] +# Different versions of one crate are common in the tree. Show them, do not fail. +multiple-versions = "warn" +wildcards = "deny" + +[sources] +unknown-registry = "deny" +unknown-git = "deny" +allow-registry = ["https://github.com/rust-lang/crates.io-index"]