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
A gate that never runs isn't a gate
An IPC contract test, a release smoke test, a dependency audit that found 18 advisories nobody asked about, and a contrast check that had been quietly broken the whole time it wasn't running.
Closing the PRD drift found in a code review pass
Four spots where Greenhouse's spec and its code disagreed - none of them bugs, all of them decisions I made in code and never wrote down.
Two notes nobody ever saw
Greenhouse saved a capture note and a handoff note faithfully, and showed neither: one had no field in the wire type, the other had a working command nobody called.