Adding Dependabot to Greenhouse (and the Rust workspace gotcha it surfaced)
A repo review on Greenhouse (my Tauri desktop app for managing creative projects) flagged something I’d been putting off: there was no dependency scanning at all. No cargo-audit, no npm-audit, nothing watching for known-vulnerable crates or packages. On a fresh project that’s easy to ignore until it isn’t.
Why this approach
GitHub’s Dependabot covers this without adding a CI job. Its advisory database already includes RustSec, so a config file does what I’d otherwise need a separate cargo-audit workflow for. It also updates the GitHub Actions pins in my CI file, which I never remember to bump myself.
I grouped minor and patch updates per ecosystem so I get roughly one PR a week instead of a dozen. Majors still come through individually, since those are the ones actually worth reading before merging.
Implementation
The config itself is short:
version: 2
updates:
- package-ecosystem: cargo
directory: /
schedule: { interval: weekly }
groups: { cargo-minor: { update-types: [minor, patch] } }
- package-ecosystem: npm
directory: /
schedule: { interval: weekly }
groups: { npm-minor: { update-types: [minor, patch] } }
- package-ecosystem: github-actions
directory: /
schedule: { interval: weekly }
Gotcha
The original plan pointed the cargo entry at /src-tauri, since that’s where the Tauri crate’s Cargo.toml lives. That’s wrong for this repo. Greenhouse’s root Cargo.toml is a virtual workspace ([workspace] members = ["src-tauri"], no [package] of its own), and in that layout the Cargo.lock lives at the workspace root, not inside the member crate’s directory. Dependabot’s cargo updater needs the directory that actually holds the lockfile it resolves against, so it has to be /. It still tracks src-tauri’s dependencies fine, since Dependabot walks all workspace members from the root.
Easy to miss if you’re pattern-matching off where the “real” code lives instead of where the lockfile is.
Results
One new file, .github/dependabot.yml, no code or CI changes otherwise. I confirmed it parses with yq and checked that all three directories map to real manifests before merging. Full validation happens once GitHub runs it after the push, since there’s no local way to dry-run Dependabot.
Wrote up the workspace-root gotcha as a pattern note in my knowledge base too, since it’ll bite me again the next time I add Dependabot to a Rust workspace project.
Related reading
The scan that offered to import itself
An import scanner found the app's own scaffolding, then re-offered a folder it had just imported - two versions of one missing conversation.
Reading changelogs before bumping three stale dependencies
An archived YAML crate, nine minor versions of rusqlite drift, and a duplicate thiserror major. The work was the reading, not the writing.
When your app can't take back a permission it already gave
Tauri's asset-protocol scope has an allow_directory and no revoke - so switching vaults became a restart, trading instant switching for a security property that actually holds.
You might also find useful
Proton Drive
Encrypted cloud storage from the team behind Proton Mail.
As a Proton Partner, I earn from qualifying purchases of Proton's privacy and security services (Pass, Mail, VPN, Drive).
Learn moreNordPass
Password manager from the team behind NordVPN, with a free tier.
As a NordPass affiliate, I earn from qualifying purchases.
Learn moreProton VPN
Commercial VPN with NetShield filtering and a kill switch.
As a Proton Partner, I earn from qualifying purchases of Proton's privacy and security services (Pass, Mail, VPN, Drive).
Learn more