agentsclimarketplace

Dependabot setup

Skill emaarco/hogwarts/plugins/felix-felicis/skills/dependabot-setup

A magical place where my skills, rules, and plugins for AI agents are defined, which magically boost productivity 🏰πŸͺ„

Install
npx -y skills add emaarco/hogwarts --skill dependabot-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Audits and sets up .github/dependabot.yml: recommends a grouping mode (low-noise, balanced, fine-grained) from the repo's use-case, gates setup on pinned dependency versions, wires CODEOWNERS over the deprecated reviewers key, groups security updates. Use when asked to set up, review, fix, or audit Dependabot / automated dependency updates / dependency grouping.

SKILL.md

23.7 KB, as published. Nobody here has run it

Skill: dependabot-setup

Analyzes .github/dependabot.yml β€” creating it if missing, repairing it if it deviates β€” and works collaboratively: gather evidence first, present findings and a recommended mode with reasons, let the user decide via AskUserQuestion, then write. Never overwrite an existing config without showing what's wrong with it. Pinned versions are the entry ticket: a Dependabot config over floating versions is theater, so the pin gate (Phase 3, delegating to the pin-node-dependencies / pin-github-actions siblings) must resolve before anything is written.

Run this when asked to "set up dependabot", review an existing config, or as the dependency-automation slice of a supply-chain audit (sibling skill release-audit).

The three modes

The core decision is how much review attention dependency PRs deserve. Ready-to-adapt templates ship in reference/ next to this SKILL.md.

ModeGroupingCadence starting pointRight forTemplate
low-noiseEverything (patch+minor+major) in one PR per ecosystem; optionally ONE repo-wide PR via multi-ecosystem groupsmonthlySolution templates, examples, internal tooling β€” minimal review capacity, CI is the gatemode-low-noise.yml, mode-low-noise-single-pr.yml
balanced (default)minor+patch grouped per ecosystem; each major = own PRweeklyOpen-source projects, production code, anything with external users β€” breaking changes get individual reviewmode-balanced.yml
fine-grainedbalanced + family groups (framework / testing / linting / …) + monorepo consolidationweeklyLarge dependency trees (β‰ˆ40+ direct deps in one ecosystem), grouped PRs that repeatedly conflict or fail CI, monoreposmode-fine-grained.yml

"Cadence starting point" is the mode's default before per-ecosystem tuning β€” see Per-ecosystem cadence in Phase 1 and the confirmation step in Phase 4. Security updates are never affected by schedule.interval (Dependabot opens those the moment a vulnerability is detected regardless of cadence), so the interval only trades off routine-update noise vs. staleness.

Within low-noise, one PR per ecosystem is the default: a single-tech repo is simply one fully-grouped block, and unrelated stacks (npm frontend + gradle backend) stay in separate PRs so a broken gradle major never blocks frontend updates. The repo-wide single PR is the escalation for when even one PR per ecosystem is too many β€” never for unrelated stacks.

The mode may differ per ecosystem: even in balanced mode, github-actions is commonly fully grouped (majors are mostly mechanical when actions are SHA-pinned and CI gates); keep actions majors separate only when workflows are the release pipeline.

Stack-groups variants β€” width follows repo type. When Phase 1d finds coupling (dependencies across ecosystems tracking the same underlying software), two widths can bundle it, both orthogonal to the mode. The choice is driven by what the repo is (Phase 1b), not by how many dependencies happen to be coupled:

  • Wide (mode-stack-groups.yml) β€” bundle each coupled ecosystem whole into one PR per stack (all gradle + all docker/compose as one backend group; backend & client in lockstep; terraform + infra images). Right for solution templates, examples, internal repos not consumed by other projects: nobody reviews these PRs individually, CI is the gate, and consolidation beats precision.
  • Narrow (mode-fine-grained-stack-groups.yml) β€” only the coupled dependency pair joins a multi-ecosystem group; the rest of each ecosystem keeps normal per-ecosystem handling. Right for libraries/OSS consumed elsewhere, or a large dependency tree, where unrelated majors still deserve individual review. Two blocks per coupled ecosystem, same directory: a "regular" block with the ecosystem's normal groups that ignores the coupled dependency, and a "stack" block scoped via patterns to just that dependency, joining the shared multi-ecosystem-group β€” ignore only suppresses updates within the block that declares it, so the stack block still gets version and security updates for the coupled dependency.

Trade-offs to state for either width when proposing a stack group: the stack shares one CI gate; everything the patterns match rides together, majors included; and a member block that joins a multi-ecosystem group carries only package-ecosystem, directory, patterns, and multi-ecosystem-group β€” schedule/labels live on the group, and cooldown, commit-message, and groups cannot sit on members. So every ecosystem pulled into a stack loses its per-block cooldown, commit-message prefix, and forced applies-to: security-updates grouping. Keep an ecosystem whose majors (or those knobs) need individual handling out of the stack, in a normal balanced/fine-grained block (mixing is fine).

Phase 1 β€” Discover

a) Ecosystems. Find every manifest Dependabot can watch, including nested ones (each distinct directory needs its own directory, or one block with a directories glob list):

Manifest foundpackage-ecosystem
package.jsonnpm (also covers pnpm/yarn) / bun
.github/workflows/*.yml, action.ymlgithub-actions
Dockerfile* / docker-compose*.yml / chartsdocker / docker-compose / helm
pom.xml / build.gradle(.kts)maven / gradle
requirements*.txt, pyproject.tomlpip / uv
go.mod / Cargo.toml / Gemfilegomod / cargo / bundler
*.csproj, global.jsonnuget / dotnet-sdk
*.tf / devcontainer.json / .pre-commit-config.yamlterraform / devcontainers / pre-commit
find . -path ./node_modules -prune -o \( -name package.json -o -name 'Dockerfile*' -o -name pom.xml \
  -o -name 'build.gradle*' -o -name go.mod -o -name Cargo.toml -o -name '*.tf' -o -name pyproject.toml \) -print
ls .github/workflows/ 2>/dev/null

Full ecosystem list: the options reference.

b) Repo identity β€” the primary evidence. The mode follows from what the repo is and who it serves β€” not from how updates were handled so far:

gh repo view --json isTemplate,isFork,isArchived,visibility,stargazerCount,description,licenseInfo
head -50 README.md                                       # what is this, who consumes it?
gh release list --limit 5 2>/dev/null                    # does it actually publish?
ls .github/workflows/                                    # is there a CI test job that gates PRs?
jq '(.dependencies//{}|length) + (.devDependencies//{}|length)' package.json 2>/dev/null   # dep count per ecosystem

Answer these explicitly before recommending anything:

  • Purpose β€” product people depend on, library/package others consume, solution template, example/demo, internal tooling?
  • Audience β€” open-source with external users, or closed/internal where the team is the only consumer?
  • What it ships β€” how many artifacts does it deploy or publish (npm packages, container images, marketplace extensions)? Every published artifact raises the cost of a silently-broken major.
  • Safety net β€” CI tests that actually gate merges; release automation.
  • Scale & shape β€” dep count per ecosystem, number of packages/workspaces. (Cross-ecosystem coupling is its own mandatory step β€” see d below.)

Per-ecosystem cadence. The mode sets a starting point, but schedule.interval is decided per ecosystem, not once for the whole config β€” different ecosystems in the same repo release at different speeds:

Ecosystem tendencyTypical starting interval
Fast-moving app deps (npm, pip, gradle/maven app libs) in an actively developed repoweekly
Slow-moving / mostly mechanical (github-actions, terraform providers, devcontainers)monthly
Docker base imagesweekly β€” patches land often and cooldown already absorbs the risk of a too-fresh tag
Any ecosystem in a low-activity or maintenance-mode repo, regardless of modemonthly (or slower) β€” matches actual review bandwidth

Treat this table as a heuristic to seed the Phase 4 question, not a rule to apply silently β€” always confirm the actual interval per ecosystem with the user rather than defaulting to the mode's starting point.

c) Update history β€” calibration only, never the basis. The existing config and past habits may be exactly what needs to change; deriving the target from the status quo would just ratify it. Use history to tune within the recommended mode:

gh pr list --author 'app/dependabot' --state all --limit 100 --json state,createdAt,closedAt,mergedAt,title
  • Many closed-without-merge / PRs open 30+ days β†’ noise exceeded capacity β†’ slower cadence or higher cooldown inside the chosen mode.
  • Grouped PRs repeatedly superseded, conflicting, or red β†’ groups too broad β†’ corroborates fine-grained.
  • Patches merge fast, majors rot β†’ raise semver-major-days cooldown, don't change mode.

d) Cross-ecosystem coupling β€” mandatory, explicit. Coupling is not a judgement call to leave to prose β€” run it as an explicit step. After collecting the pinned version of every dependency in every ecosystem (you read these anyway for the Phase 3 pin gate), identify dependencies in different ecosystems that track the same underlying software or release train, and flag each such pair as a coupled candidate β€” manifests that must bump together. Two signals surface a pair, don't rely on only the first: an identical version string shared across manifests (the strongest and easiest to grep β€” e.g. one library pinned in two places), and different version strings that nonetheless track one product β€” a server and the client library that talks to it version their releases independently, so a literal-value match would miss them; recognise the shared software by name, not by number.

Stay general β€” flag any shared software, not just the familiar shapes. Illustrative pairs only:

  • a server image in docker/docker-compose and its client SDK or driver in npm/gradle/pip β€” e.g. the postgres image (tag 16) and the org.postgresql:postgresql driver (42.7.x): different version numbers, same server, must move together
  • a backend library and the client's pinned copy of the same library β€” usually an identical version string (backend & client released in lockstep)
  • a provider/tool and the deployed image tag it manages β€” e.g. a terraform provider and the infra image it provisions (typically different numbers)

Every coupled pair becomes a candidate carried into Phase 4, where the width of the bundle is chosen by repo type. If nothing across ecosystems tracks the same software, record "no coupling found" and skip the stack-group variants.

Phase 2 β€” Analyze the existing config (if present)

Check each update block:

  • Coverage β€” a block (or directories entry) for every ecosystem/directory from Phase 1; no orphan blocks for manifests that no longer exist.
  • Mode coherence β€” which mode does the config resemble, and is it consistent across blocks? A "balanced" repo with one all-types group hides breaking majors inside routine PRs β€” finding.
  • Dead & deprecated config:
    • reviewers: β€” removed by GitHub (Aug 2025), silently ignored β†’ delete, wire CODEOWNERS instead.
    • target-branch: β€” a block with target-branch no longer applies to security updates, even when it names the default branch. Flag redundant target-branch: main for removal.
    • Duplicate blocks (same ecosystem + directory), overlapping directory/directories definitions.
  • Reviewer wiring β€” for a repo owned by a small group, prefer one CODEOWNERS * rule over per-block assignees: it covers all PRs (not just Dependabot's) and doesn't rot in N places. Keep assignees only where a dedicated person triages dependency PRs separately from code ownership (larger orgs).
  • Groups correct:
    • Group order matters β€” first match wins; specific families must precede the catch-all.
    • A group only affects version updates unless it says otherwise: without an applies-to: security-updates group, every CVE opens its own PR.
  • Noise controls β€” cooldown present (supply-chain guard: new releases mature before a PR opens); open-pull-requests-limit sized to the expected PR count (default 5 β€” too low for balanced mode where majors arrive individually).
  • Clutter β€” labels that don't exist in the repo or are typo'd (gh label list; e.g. "Technical Dept"), schedule.time without timezone (runs UTC), restated defaults, versioning-strategy that fights an exact-pin policy (widen vs pinned versions).

Phase 3 β€” Precondition: versions must be pinned

Dependabot PRs only reflect reality when manifests state exact versions β€” on floating specs the resolved dependency drifts on every install and the whole setup is theater. Treat pinning as a gate, not a finding: do not write a config while versions float.

Check per ecosystem, report with file:line evidence:

  • npm β€” no ^/~/>=/*/latest/mutable git refs; lockfile committed β†’ fix via sibling skill pin-node-dependencies
  • github-actions β€” every uses: pinned to a full 40-char commit SHA β†’ fix via sibling skill pin-github-actions
  • docker / docker-compose β€” exact tag, ideally tag + @sha256: digest, never latest
  • maven / gradle β€” no dynamic versions (1.+, [1.0,), latest.release)
  • pip β€” == pins or a committed lockfile (uv / poetry / pip-tools)

If anything floats, resolve the gate before Phase 5 via AskUserQuestion: fix pins now (recommended β€” invoke the sibling skills for npm and actions, patch the other ecosystems directly) or proceed anyway, with the user explicitly accepting that Dependabot PRs for the floating ecosystems won't match what actually runs. Record the choice in the Phase 4 report.

Phase 4 β€” Report, recommend, decide

Post the findings as a normal message first β€” table of Phase 2/3 checks plus the mode recommendation. The recommendation derives from the repo's use-case (Phase 1b); update history (Phase 1c) only tunes cadence, cooldown, and group breadth within it. If the recommendation contradicts the current setup, say so and explain the delta β€” matching the status quo is not a goal:

Use-caseRecommend
Solution template, example/demo, internal tooling with no external consumerslow-noise
Open-source project or product with external users; publishes artifacts β€” the more it deploys, the stronger the casebalanced
Large dependency tree (β‰ˆ40+ direct deps in one ecosystem), many packages/workspaces, monorepo with shared depsfine-grained
Coupling found (Phase 1d) and the repo is a solution template / example / internal tool not consumed by other projectswide stack groups on top β€” bundle each coupled ecosystem whole into one PR (mode-stack-groups); CI is the gate, consolidation beats precision
Coupling found (Phase 1d) and the repo is a library/OSS consumed elsewhere, or has a large dependency treenarrow targeted pairing on top β€” only the coupled pair joins a multi-ecosystem group, the rest of each ecosystem stays per-ecosystem (mode-fine-grained-stack-groups) so unrelated majors keep individual review
No CI test jobnever low-noise β€” grouped majors would merge blind; recommend balanced and adding CI

Then confirm via AskUserQuestion β€” recommendation first, marked "(recommended)", every option stating its consequence. Ask only what the evidence can't answer, max 4 questions:

  1. Mode β€” the three modes with one-line trade-offs. Include the single-PR multi-ecosystem variant only for clear low-noise repos. Whenever Phase 1d found coupling, surface both stack-group widths in the same question and mark the one matching the Phase-1b use-case "(recommended)":

    • wide β€” whole coupled ecosystems bundled (mode-stack-groups), recommended for solution-template/example/internal repos not consumed elsewhere (e.g. "all gradle + all docker/compose as one backend PR");
    • narrow β€” only the coupled pair joins the group, the rest stays per-ecosystem (mode-fine-grained-stack-groups), recommended for libraries/OSS consumed elsewhere or large dependency trees (e.g. "postgres image + postgres driver as one PR, rest of gradle/docker stays fine-grained").

    Name the concrete coupled manifests/pair. State the stack-group trade-off in the option text: bundled member blocks lose their per-block cooldown, commit-message prefix, and forced applies-to: security-updates grouping (schedule/labels live on the group; cooldown/commit-message/groups can't sit on members).

  2. Cadence per ecosystem β€” always confirm, never silently apply the mode's starting point. Propose an interval per detected ecosystem from the Per-ecosystem cadence heuristic (Phase 1) adjusted by PR history (Phase 1c) and repo activity level, and let the user override any of them.

  3. Review wiring β€” CODEOWNERS-only (recommended for small teams) vs keep assignees, only if the existing config has assignees/reviewers.

  4. Existing customizations (multiSelect) β€” which ignore: rules, labels, or schedule quirks to carry over vs drop.

Phase 5 β€” Create or update

Enter this phase only once the Phase 3 pin gate is resolved β€” pins fixed (sibling skills run, other ecosystems patched) or floating versions explicitly accepted by the user.

  • Update > replace. Fix the specific gaps; carry over confirmed customizations (especially ignore: rules) verbatim, including comments.

  • Strip teaching comments β€” never emit them. The reference/mode-*.yml files carry long explanatory prose comments for agent context only; they must not appear in the generated .github/dependabot.yml. Copy the config shape, not the rationale. The written file keeps at most brief one-line section labels in the host repo's existing comment style (or none at all). This does not conflict with update > replace above: comments already present in the repo's own config (e.g. a rationale line on an ignore: rule) are still carried over verbatim.

  • Start from the chosen reference/mode-*.yml, one block per detected ecosystem/directory. Templates show weekly/monthly as illustrative placeholders only β€” write the interval confirmed per ecosystem in Phase 4, not the template's literal value. For fine-grained: derive family groups from the actual manifests, never ship template families the repo doesn't use, and confirm the families with the user.

  • Every mode keeps: labels: ['dependencies'], commit-message prefix chore + include: scope, cooldown, and an applies-to: security-updates group per ecosystem.

  • If no CODEOWNERS exists, create .github/CODEOWNERS with a default owner (suggest from gh api repos/{owner}/{repo} --jq .owner.login):

    # Default owners β€” requested as reviewers on every PR, including Dependabot's
    * @<owner-or-team>
    
  • Ensure referenced labels exist: gh label create dependencies --description "Dependency updates" --color 0366d6 for any missing one.

Optional companion β€” patch/minor auto-merge

After the dependabot.yml is written, offer (never impose) a patch/minor auto-merge workflow from reference/automerge-workflow.yml. This writes .github/workflows/dependabot-automerge.yml β€” a separate file from dependabot.yml.

Precondition β€” state it, never skip it. Auto-merge is only safe when a branch ruleset with a required status check gates the default branch (sibling branch-ruleset-setup) and a CI test job actually runs on PRs (Phase 1b). Without a required check, gh pr merge --auto merges the moment merge requirements are met β€” i.e. immediately β€” so CI is not a gate and a broken patch lands unreviewed. If the precondition isn't met, name the option and exactly what it needs (a required-check ruleset), and stop there β€” do not write the workflow.

When the precondition holds, confirm via AskUserQuestion β€” recommend enabling for internal/low-noise repos (CI is the gate, review capacity is the constraint); recommend against auto-enabling for OSS/product repos where a maintainer may want eyes on every bump:

  • Enable auto-merge (patch + minor) β€” Dependabot patch/minor PRs merge once the required check passes; every major stays manual for breaking-change review.
  • No auto-merge β€” every Dependabot PR waits for a manual merge.

On enable: copy reference/automerge-workflow.yml to .github/workflows/dependabot-automerge.yml, stripping the teaching comments (per the comment rule above β€” keep at most a one-line label), re-resolve the fetch-metadata SHA to the intended release (gh api repos/dependabot/fetch-metadata/git/refs/tags/<tag> --jq .object.sha), and narrow the gate only if the user asked (e.g. dev-dependencies via contains(steps.meta.outputs.dependency-names, …), or an ecosystem check via steps.meta.outputs.package-ecosystem).

Keep the merge-step retry loop. on: pull_request fires while the required check is still queued and the merge state is UNSTABLE, so enablePullRequestAutoMerge rejects the first call with "Pull request is in unstable status" and a single-shot gh pr merge --auto exits 1 β€” auto-merge never queues. The template retries (5 attempts, 15s backoff) to ride out that race; don't collapse it back to one line when stripping comments.

Phase 6 β€” Verify

  • YAML parses: python3 -c "import yaml; yaml.safe_load(open('.github/dependabot.yml'))" (fall back to npx --yes yaml or careful review).
  • CODEOWNERS check after pushing: gh api repos/{owner}/{repo}/codeowners/errors.
  • Config errors and run logs surface under Insights β†’ Dependency graph β†’ Dependabot β€” tell the user to check there after the merge, since GitHub validates unknown keys only at run time.
  • If the auto-merge companion was written (Phase 5), YAML-parse it too and confirm the fetch-metadata uses: is SHA-pinned. Remind the user auto-merge does nothing until a required-status-check ruleset is in place (branch-ruleset-setup).

Sources

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.