Skip to content
Development

Adding Dependabot to Greenhouse (and the Rust workspace gotcha it surfaced)

By Victor Da Luz
rustdependabotcidev-loggreenhouse

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

Development

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.

Read
Development

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.

Read