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
27 changes: 24 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,25 @@ jobs:
- uses: jdx/mise-action@v4
with:
cache_key_prefix: mise-ci-${{ github.job }}
- name: Check licenses and advisories
run: mise run lint:rust:deny
- name: Check licenses, bans, and sources
run: cargo deny --manifest-path crates/Cargo.toml check bans licenses sources

# Advisory checks run against a live database that can change at any time.
# A new RUSTSEC entry would break CI on every branch even though no code
# changed, so this job is informational only (continue-on-error).
# A weekly cron workflow (rust-advisories.yaml) opens issues for new advisories.
lint-rust-advisories:
name: Lint Rust (advisories)
runs-on: ubuntu-latest
timeout-minutes: 10
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
cache_key_prefix: mise-ci-${{ github.job }}
- name: Check advisories (informational)
run: cargo deny --manifest-path crates/Cargo.toml check advisories

lint-python:
name: Lint Python
Expand Down Expand Up @@ -664,6 +681,7 @@ jobs:
- lint-go
- lint-rust
- lint-rust-deny
- lint-rust-advisories
- lint-python
- lint-docs
- test-go
Expand Down Expand Up @@ -692,6 +710,7 @@ jobs:
echo " lint-go: ${{ needs.lint-go.result }}"
echo " lint-rust: ${{ needs.lint-rust.result }}"
echo " lint-rust-deny: ${{ needs.lint-rust-deny.result }}"
echo " lint-rust-advisories: ${{ needs.lint-rust-advisories.result }} (informational)"
echo " lint-python: ${{ needs.lint-python.result }}"
echo " lint-docs: ${{ needs.lint-docs.result }}"
echo " test-go: ${{ needs.test-go.result }}"
Expand All @@ -702,7 +721,9 @@ jobs:
echo " integration-shards: ${{ needs.integration-shards.result }}"
echo " test-integration: ${{ needs.test-integration.result }}"

# Fail if any job failed
# Fail if any required job failed.
# lint-rust-advisories is excluded: it uses continue-on-error because
# advisory DB updates shouldn't block unrelated PRs.
FAILED=false
for result in \
"${{ needs.setup.result }}" \
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/rust-advisories.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Rust Advisory Check

on:
schedule:
# Monday 9am UTC
- cron: "0 9 * * 1"
workflow_dispatch:

permissions:
issues: write

jobs:
check-advisories:
name: Check Rust advisories
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
cache_key_prefix: mise-ci-${{ github.job }}
- name: Check advisories
id: advisories
continue-on-error: true
run: cargo deny --manifest-path crates/Cargo.toml check advisories 2>&1 | tee /tmp/deny-output.txt
- name: Open issue on failure
if: steps.advisories.outcome == 'failure'
env:
GH_TOKEN: ${{ github.token }}
run: |
# Don't open a duplicate if one already exists
EXISTING=$(gh issue list --label "security" --search "Rust security advisory" --state open --json number --jq '.[0].number')
if [ -n "$EXISTING" ]; then
echo "Issue #$EXISTING already open, skipping"
exit 0
fi

SNIPPET=$(grep -A5 'error\[vulnerability\]' /tmp/deny-output.txt | head -30 || echo "See CI logs for details")

gh issue create \
--title "Rust security advisory detected" \
--label "security" \
--body "\`cargo deny check advisories\` found new security advisories in Rust dependencies.

\`\`\`
$SNIPPET
\`\`\`

Run \`cargo deny --manifest-path crates/Cargo.toml check advisories\` locally for full details.
Typically fixed with \`cargo update -p <crate>\` in \`crates/\`."
6 changes: 5 additions & 1 deletion mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,13 @@ description = "Lint Rust code (clippy)"
run = "cargo clippy --manifest-path crates/Cargo.toml --workspace -- -D warnings"

[tasks."lint:rust:deny"]
description = "Check Rust licenses and advisories"
description = "Check Rust licenses, bans, sources, and advisories"
run = "cargo deny --manifest-path crates/Cargo.toml check"

[tasks."lint:rust:deny:advisories"]
description = "Check Rust advisory database (RUSTSEC)"
run = "cargo deny --manifest-path crates/Cargo.toml check advisories"

[tasks."lint:rust:fix"]
description = "Fix Rust lint issues"
run = "cargo clippy --manifest-path crates/Cargo.toml --workspace --fix --allow-dirty -- -D warnings"
Expand Down
Loading