Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,31 @@ jobs:
# advisories (unsound / unmaintained) are reported as warnings only —
# Dependabot does not surface those at all, so the log is the record.
run: cargo audit

deny:
name: cargo deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo-deny binary
id: cache-deny
uses: actions/cache@v6
with:
path: ~/.cargo/bin/cargo-deny
key: ${{ runner.os }}-cargo-deny

- name: Install cargo-deny
if: steps.cache-deny.outputs.cache-hit != 'true'
run: cargo install cargo-deny --locked

- name: Check licenses, bans and sources
# `advisories` is intentionally omitted — the cargo audit job above
# already covers RustSec. This job guards the other three: license
# compatibility with GPL-3.0-only, duplicate crate versions (a second
# crypto trait generation in the graph), and dependencies resolving to
# anything other than crates.io.
run: cargo deny check licenses bans sources
22 changes: 20 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ benchmark/
scripts/
release.sh Automated release + Homebrew formula update
.github/
workflows/ci.yml GitHub Actions CI (fmt, clippy, test, cargo audit)
workflows/ci.yml GitHub Actions CI (fmt, clippy, test, cargo audit, cargo deny)
dependabot.yml Weekly cargo + github-actions dependency updates
deny.toml cargo-deny policy (licenses, duplicate versions, sources)
```

## Development Guidelines
Expand All @@ -115,6 +116,23 @@ scripts/
- Run `cargo clippy` and fix any warnings
- Follow standard Rust naming conventions

### Dependencies

CI enforces a dependency policy on top of the test suite. Both tools are
optional locally (`cargo install cargo-audit cargo-deny --locked`), but a PR
that trips either one will fail:

- `cargo audit` fails on known RustSec vulnerabilities. Informational
advisories (unsound / unmaintained) are reported as warnings only.
- `cargo deny check licenses bans sources` enforces `deny.toml`: dependency
licenses must be compatible with GPL-3.0-only, no crate may appear at two
versions, and every dependency must resolve to crates.io. The `advisories`
check is deliberately left to `cargo audit` rather than run twice.

A duplicate-version failure matters most for the RustCrypto crates — two
generations of the `cipher` / `digest` traits in one graph will not compile.
That is why `.github/dependabot.yml` groups them into a single PR.

### Compatibility

This is the most important constraint. Gitveil must remain **byte-compatible** with git-crypt:
Expand Down Expand Up @@ -157,7 +175,7 @@ This is the most important constraint. Gitveil must remain **byte-compatible** w
1. Fork the repository
2. Create a feature branch (`git checkout -b my-feature`)
3. Make your changes
4. Run `cargo fmt && cargo clippy && cargo test`
4. Run `cargo fmt && cargo clippy && cargo test` (and `cargo deny check licenses bans sources` if you changed dependencies)
5. Commit with a clear message
6. Open a pull request

Expand Down
47 changes: 47 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# cargo-deny configuration.
#
# Scope note: the `advisories` check is deliberately NOT run in CI — the
# separate `cargo audit` job already covers RustSec advisories and reports
# informational (unsound / unmaintained) findings as warnings. Running both
# would duplicate the signal. CI runs `cargo deny check licenses bans sources`.

[graph]
all-features = true

[licenses]
# GPL-3.0-only is this crate's own license. Everything below is either
# permissive or GPL-3.0-compatible weak copyleft. Crates offering a choice
# (e.g. rustix: "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT")
# resolve against the first allowed term, so only the terms actually
# selected need listing here.
allow = [
"Apache-2.0",
"GPL-3.0-only",
"MIT",
# `colored` is MPL-2.0: file-level copyleft, explicitly GPL-compatible.
"MPL-2.0",
# `unicode-ident` is "(MIT OR Apache-2.0) AND Unicode-3.0".
"Unicode-3.0",
]
confidence-threshold = 0.9

[bans]
# A second copy of a crypto crate in the graph means two incompatible
# trait generations (see the `rustcrypto` group in .github/dependabot.yml).
# Denying duplicates outright is what catches that.
multiple-versions = "deny"
wildcards = "deny"

skip = [
# syn 2 and syn 3 coexist because zeroize_derive is still on 2 while
# clap_derive and thiserror-impl moved to 3. Both are proc-macro
# build-time only and never reach the shipped binary.
{ crate = "syn" },
]

[sources]
# Every dependency must come from crates.io. A git or alternate-registry
# source appearing in the graph is the supply-chain case worth failing on.
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
Loading