Dependency Updates
Dependency Updates
Section titled “Dependency Updates”Runbook for managing Cargo and GitHub Actions dependencies in rust-template.
Dependabot Configuration
Section titled “Dependabot Configuration”Dependabot is configured in .github/dependabot.yml with two ecosystems:
Cargo Dependencies
Section titled “Cargo Dependencies”| Setting | Value |
|---|---|
| Schedule | Weekly, Mondays at 09:00 America/Chicago |
| PR limit | 10 open PRs |
| Commit prefix | chore(deps) |
| Labels | dependencies, rust |
| Reviewer | zircote |
Grouped updates (minor + patch combined into single PRs):
| Group | Packages |
|---|---|
dev-dependencies | proptest*, test-*, criterion* |
async-runtime | tokio*, async-* |
serde-ecosystem | serde* |
GitHub Actions Dependencies
Section titled “GitHub Actions Dependencies”| Setting | Value |
|---|---|
| Schedule | Weekly, Mondays at 09:00 America/Chicago |
| PR limit | 5 open PRs |
| Commit prefix | chore(deps) |
| Labels | dependencies, github-actions |
| Reviewer | zircote |
Grouped updates: All actions grouped together for minor + patch updates.
Dependabot Auto-Merge Policy
Section titled “Dependabot Auto-Merge Policy”The dependabot-automerge.yml workflow automatically squash-merges Dependabot PRs that meet these criteria:
| Update type | Auto-merge? | Rationale |
|---|---|---|
Patch (0.0.x) | Yes | Bug fixes, low risk |
Minor (0.x.0) | Yes | Backward-compatible features |
Major (x.0.0) | No — manual review | Potentially breaking changes |
What Auto-Merge Requires
Section titled “What Auto-Merge Requires”Auto-merge is enabled but the PR still must pass all CI checks before merging. The flow is:
- Dependabot opens a PR
dependabot-automerge.ymlruns and enables auto-merge (squash) for patch/minor- CI (
ci.yml) runs: fmt, clippy, test, doc, deny, msrv - Only after all CI checks pass does the PR actually merge
When to Intervene Manually
Section titled “When to Intervene Manually”- Major version bumps — always review the changelog for breaking changes
- PRs that fail CI — investigate the failure; the dependency update may be incompatible
- Security advisories — expedite the merge; do not wait for the weekly cycle
- Grouped PRs with many changes — scan the diff for unexpected changes
Manually Merging a Dependabot PR
Section titled “Manually Merging a Dependabot PR”# Review the PRgh pr view <number>gh pr diff <number>
# Approve and mergegh pr review <number> --approvegh pr merge <number> --squashManual Dependency Auditing
Section titled “Manual Dependency Auditing”cargo-deny (Supply Chain Policy)
Section titled “cargo-deny (Supply Chain Policy)”cargo-deny runs in CI as part of the deny job. It checks four categories defined in deny.toml:
| Check | What it does | Failure mode |
|---|---|---|
| advisories | Known vulnerabilities (RustSec DB) | Deny all advisory types |
| licenses | Only allow listed SPDX licenses | Deny anything not in the allow-list |
| bans | Block specific crates | openssl (use rustls), atty (use std) |
| sources | Only allow crates.io | Deny unknown registries and git sources |
Run locally:
# Installcargo install cargo-deny
# Run all checkscargo deny check
# Run a specific checkcargo deny check advisoriescargo deny check licensescargo deny check banscargo deny check sources
# Generate a reportcargo deny listcargo-audit (Security Advisories)
Section titled “cargo-audit (Security Advisories)”The security-audit.yml workflow runs cargo-audit:
- Daily at 00:00 UTC (cron schedule)
- On every push that changes
Cargo.tomlorCargo.lock - Can be triggered manually via
workflow_dispatch
Run locally:
# Installcargo install cargo-audit
# Run auditcargo audit
# Run with deny on warningscargo audit --deny warnings
# Generate JSON output for toolingcargo audit --jsonFull Manual Audit
Section titled “Full Manual Audit”# 1. Update the advisory databasecargo audit fetch
# 2. Run cargo-auditcargo audit --deny warnings
# 3. Run cargo-deny (broader checks)cargo deny check
# 4. Check for outdated dependenciescargo outdated
# 5. Inspect dependency treecargo treecargo tree --duplicates # find duplicate cratesHandling Security Advisories
Section titled “Handling Security Advisories”When cargo-audit or Dependabot flags a security advisory:
1. Assess Severity
Section titled “1. Assess Severity”# Check the advisory detailscargo audit
# Check if the vulnerable code path is reachablecargo tree -i <affected-crate>2. Update the Dependency
Section titled “2. Update the Dependency”# Update a specific dependencycargo update -p <crate-name>
# Update all dependenciescargo update
# Verify the update resolves the advisorycargo audit3. If No Fix Is Available
Section titled “3. If No Fix Is Available”Options in order of preference:
- Pin to an unaffected version in
Cargo.toml - Add to the ignore list in
deny.toml(temporary, with comment explaining why):[advisories]ignore = ["RUSTSEC-2024-XXXX", # No fix available; unexploitable in our usage. Revisit by YYYY-MM-DD.] - Replace the dependency with an alternative crate
- Fork and patch the dependency
4. Verify and Push
Section titled “4. Verify and Push”cargo deny check advisoriescargo test --all-featuresgit add Cargo.toml Cargo.lockgit commit -m "fix(deps): address RUSTSEC-XXXX-YYYY in <crate>"git pushUpdating Pinned GitHub Actions Versions
Section titled “Updating Pinned GitHub Actions Versions”All GitHub Actions in this repository are pinned to full commit SHAs for supply chain security (not tags). When updating:
1. Find the New SHA
Section titled “1. Find the New SHA”# Look up the commit SHA for a new release taggh api repos/<owner>/<action>/git/refs/tags/<tag> --jq '.object.sha'Or visit the action’s releases page and copy the full commit SHA from the tag.
2. Update the Workflow File
Section titled “2. Update the Workflow File”Replace the SHA and update the comment with the new version:
# Beforeuses: actions/checkout@OLD_SHA # v6.0.2
# Afteruses: actions/checkout@NEW_SHA # v6.1.03. Update All Occurrences
Section titled “3. Update All Occurrences”The same action may appear in multiple workflow files. Search across all of them:
grep -r "actions/checkout@" .github/workflows/Update every occurrence to the same SHA.
4. Let Dependabot Handle It
Section titled “4. Let Dependabot Handle It”Dependabot is configured to update GitHub Actions weekly. For minor and patch updates, these are grouped and auto-merged. For major updates, review manually.
Adding New Dependencies
Section titled “Adding New Dependencies”Evaluation Criteria
Section titled “Evaluation Criteria”Before adding a new dependency, evaluate:
- Necessity — Can this be done with
stdor existing dependencies? - Maintenance — Is the crate actively maintained? Check last commit date, open issues
- License — Must be in the
deny.tomlallow-list: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, Zlib, MPL-2.0, Unicode-DFS-2016, Unicode-3.0, CC0-1.0, BSL-1.0, 0BSD - Security — Run
cargo auditafter adding; check RustSec for known advisories - Size — Check transitive dependency count with
cargo tree -p <crate> - Quality — Does it have tests? Documentation? Is it widely used?
- Banned crates — Ensure it does not pull in
openssloratty(banned indeny.toml) - MSRV — Does the crate support Rust 1.92 (this project’s MSRV)?
Adding the Dependency
Section titled “Adding the Dependency”# Add the dependencycargo add <crate-name>
# Or for dev-onlycargo add --dev <crate-name>
# Verify it passes all checkscargo deny checkcargo clippy --all-targets --all-features -- -D warningscargo test --all-features
# Check the dependency tree impactcargo tree -p <crate-name>If the License Is Not in the Allow-List
Section titled “If the License Is Not in the Allow-List”- Evaluate whether the license is acceptable for your project
- Add it to
deny.toml:[licenses]allow = [# ...existing licenses..."NEW-LICENSE-SPDX",] - Document why the license was added in the commit message
Removing Unused Dependencies
Section titled “Removing Unused Dependencies”Detect Unused Dependencies
Section titled “Detect Unused Dependencies”# Install cargo-machetecargo install cargo-machete
# Find unused dependenciescargo macheteRemove a Dependency
Section titled “Remove a Dependency”# Remove from Cargo.tomlcargo remove <crate-name>
# Update the lock filecargo update
# Verify nothing brokecargo clippy --all-targets --all-features -- -D warningscargo test --all-featurescargo deny checkDependabot Configuration Changes
Section titled “Dependabot Configuration Changes”Adding a New Grouped Update
Section titled “Adding a New Grouped Update”Edit .github/dependabot.yml:
groups: new-group-name: patterns: - "crate-prefix*" update-types: - "minor" - "patch"Changing the Schedule
Section titled “Changing the Schedule”schedule: interval: "daily" # or "weekly" or "monthly" day: "monday" # for weekly time: "09:00" timezone: "America/Chicago"Ignoring a Dependency
Section titled “Ignoring a Dependency”ignore: - dependency-name: "crate-to-ignore" versions: [">=2.0.0"] # ignore major updates onlyQuick Reference
Section titled “Quick Reference”| Task | Command |
|---|---|
| Run all supply chain checks | cargo deny check |
| Audit for security advisories | cargo audit --deny warnings |
| Update all dependencies | cargo update |
| Update one dependency | cargo update -p <crate> |
| List outdated dependencies | cargo outdated |
| Show dependency tree | cargo tree |
| Find duplicates | cargo tree --duplicates |
| Find unused dependencies | cargo machete |
| Add a dependency | cargo add <crate> |
| Remove a dependency | cargo remove <crate> |
| Check Dependabot PRs | gh pr list --label dependencies |