fix-dependabot
Skill160 starsChanged 6 months agoMITView on GitHub
Resolve Dependabot security alerts on owid/etl by upgrading vulnerable dependencies. Use when the user mentions "dependabot", "security alerts", "vulnerability", "CVE", "security fixes", "dependabot alerts", or wants to fix vulnerable packages. Also trigger when the user pastes a GitHub Dependabot URL or asks about outdated/insecure dependencies.
- Installs packages
We split this skill into the rules it gives an agent
27 rules. About 0 are common, 11 are distinctive, and 16 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
16
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 32
Ask the user which severities to fix (e.g.
- Distinctive: line 36
Always list open Dependabot PRs, not just open alerts.
- Distinctive: line 50
If the PR is obsolete, close it with a clear comment, for example:
- Distinctive: line 55
If you create a replacement PR that batches or supersedes Dependabot PRs, close the superseded PRs and re-run this list in Step 6.
- Very specific: line 78
If the package appears in a pyproject.toml dependencies or optional dependency group:
- Distinctive: line 80
Update the version constraint to require at least the patched version:
- Very specific: line 84
Run uv lock --upgrade-package <package> to update the lockfile
- Very specific: line 88
If the package is only in uv.lock (not a direct dependency):
- Distinctive: line 94
Check if any of those parent packages cap the vulnerable package below the patched version.
- Distinctive: line 106
If a cap blocks it: check if a newer version of the parent package relaxes the cap.
- Very specific: line 107
Check if the parent package is actually used in the codebase (grep -rn 'import <parent>\|from <parent>' --include='*.py')
- Very specific: line 108
If unused: remove it from pyproject.toml (this unblocks the transitive dep)
- Very specific: line 109
If used: inform the user that the fix requires either waiting for the parent to update, or adding a [tool.uv] override (explain the …
- Very specific: line 113
When removing a package, check if it's imported anywhere in the codebase.
- Very specific: line 138
Before adding a package to dependencies, check whether the extension actually imports it:
- Very specific: line 153
Read the target package + version from the PR title (Bump <pkg> from <old> to <new> in /<path>).
- Very specific: line 155
Verify it resolved: npm ls <pkg>.
- Distinctive: line 157
After applying all of them, compile each touched extension so a bad bump fails locally, not in CI:
- Distinctive: line 170
If a bump is risky or a major version jump with breaking changes, don't force it into the batch — leave that PR open and flag it for the …
- Very specific: line 174
Run make check-all (lint + format + typecheck across the root and every lib/).
- Distinctive: line 176
If it fails, fix the issues (commonly: removed/renamed kwargs that type checkers flag) and re-run until it passes.
- Very specific: line 180
If you modified any lib/{catalog,datautils,repack}/pyproject.toml, also bump that file's version = "x.y.z" (patch bump).
- Very specific: line 182
After bumping, re-run uv lock (top-level and inside each modified lib/<name>/) so the lockfiles pick up the new version.
- Distinctive: line 186
Follow the standard ETL PR workflow:
- Very specific: line 198
Use commit emoji 🐛🤖 (bug fix, AI-written).
- Very specific: line 200
After pushing, post @codex review as a PR comment.
- Very specific: line 210
When multiple packages need upgrading, batch them: uv lock --upgrade-package pkg1 --upgrade-package pkg2
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Fix Dependabot Alerts
Resolve open Dependabot security alerts by upgrading vulnerable dependencies across the ETL monorepo — including pip packages (pyproject.toml + uv.lock), lib/ subdirectories, and npm packages in vscode_extensions/.
Goal: leave zero open Dependabot PRs. Security alerts are the priority, but Dependabot also opens routine version-update PRs that have no associated alert (e.g. esbuild minor bumps, or js-yaml bumps in extensions GitHub didn't flag). Don't stop at the alerts — also clear these (Step 4c) so the PR list is empty afterward. The default is to fold every open Dependabot PR's bump into the single batch PR and close the originals; if the user only wants the security alerts, scope to those instead.
Step 1: Fetch and summarize alerts
gh api repos/owid/etl/dependabot/alerts \
--jq '.[] | select(.state == "open") | {
number, state,
package: .dependency.package.name,
ecosystem: .dependency.package.ecosystem,
severity: .security_advisory.severity,
summary: .security_advisory.summary,
patched: .security_advisory.vulnerabilities[0].first_patched_version.identifier,
manifest: .dependency.manifest_path
}'Present a summary table grouped by severity (critical > high > medium > low) with counts, then the detailed list showing package, ecosystem, severity, and summary.
Ask the user which severities to fix (e.g. "critical and high only" or "all"). If the user already specified a filter in their request, proceed with that.
Step 1b: Audit existing Dependabot PRs
Always list open Dependabot PRs, not just open alerts. Dependabot PRs can remain open after the default branch already contains the requested dependency version (especially old/conflicted PRs where automatic rebases have been disabled).
gh pr list --repo owid/etl --author app/dependabot --state open \
--json number,title,headRefName,mergeStateStatus,files --limit 100 \
--jq '.[] | {number,title,mergeStateStatus,files:[.files[].path]}'For each open PR:
- Identify the manifest/lockfile and target package/version from the title and changed files.
- Compare against the current default branch (
origin/masterormaster), not just your working branch. Check whether the dependency is already at the requested version or newer.- For
uv.lockfiles, inspect the relevant package entry in the affected lockfile. - For npm lockfiles, parse
package-lock.jsonand check all installed versions of the package in that extension.
- For
- If the PR is obsolete, close it with a clear comment, for example:
gh pr close <number> --repo owid/etl --comment \ "Closing as obsolete: the current default branch already has this dependency at the requested version or newer, so this stale Dependabot PR is no longer relevant." - If you create a replacement PR that batches or supersedes Dependabot PRs, close the superseded PRs and re-run this list in Step 6.
Map each open PR to an alert (or not). Cross-reference this PR list against the alert list from Step 1. A PR whose package/manifest matches an open alert is a security PR — handled by Steps 2–4. A PR with no matching open alert is a routine version-update PR — handled by Step 4c. Both kinds should be gone by the end.
Step 2: Categorize each alert
For each alert to fix, determine:
- Ecosystem:
pipornpm - Direct vs transitive: Is the package listed directly in
pyproject.toml(or alib/*/pyproject.toml), or is it only in the lockfile as a transitive dependency? - Manifest location: Which
pyproject.tomlorpackage.jsonowns this dependency?
For pip packages, check all pyproject.toml files:
grep -rn '<package-name>' pyproject.toml lib/*/pyproject.tomlFor npm packages, check the manifest path from the alert (usually under vscode_extensions/).
Step 3: Fix pip dependencies
Direct dependencies
If the package appears in a pyproject.toml dependencies or optional dependency group:
- Update the version constraint to require at least the patched version:
"package>=old_version" → "package>=patched_version" - Run
uv lock --upgrade-package <package>to update the lockfile
Transitive dependencies
If the package is only in uv.lock (not a direct dependency):
- Identify which direct dependency pulls it in:
uv tree --invert --package <vulnerable-package> --depth 1 - Check if any of those parent packages cap the vulnerable package below the patched version. For each parent, check its constraints on PyPI:
python3 -c " import json, urllib.request r = urllib.request.urlopen('https://pypi.org/pypi/<parent>/json') d = json.loads(r.read()) deps = d['info'].get('requires_dist') or [] matches = [dep for dep in deps if '<vulnerable-pkg>' in dep.lower()] print(matches) " - If no cap blocks it: simply run
uv lock --upgrade-package <vulnerable-package> - If a cap blocks it: check if a newer version of the parent package relaxes the cap. If it does, upgrade the parent. If the latest parent still caps it:
- Check if the parent package is actually used in the codebase (
grep -rn 'import <parent>\|from <parent>' --include='*.py') - If unused: remove it from
pyproject.toml(this unblocks the transitive dep) - If used: inform the user that the fix requires either waiting for the parent to update, or adding a
[tool.uv] override(explain the tradeoff — overrides can cause runtime incompatibilities)
- Check if the parent package is actually used in the codebase (
After removing a dependency
When removing a package, check if it's imported anywhere in the codebase. If it is, replace its usage with an alternative approach. For example, moviepy's ImageSequenceClip usage can be replaced with a direct ffmpeg subprocess call.
Always search broadly:
rg 'import <package>|from <package>' --type pyStep 4: Fix npm dependencies
For each vulnerable npm package:
- Navigate to the directory containing the affected
package.json - Update the package:
cd <directory> npm install # ensure node_modules exist npm install <package>@^<patched-version> - Verify the update:
npm ls <package>
npm transitive vs. direct deps
Before adding a package to dependencies, check whether the extension actually imports it:
rg -l "from ['\"]<package>|require\(['\"]<package>" vscode_extensions/<ext>/src- Imported in
src/→ it's a real runtime dependency; bump it independencies(npm install <package>@^<version>). - Not imported (it's a dev-tooling transitive dep, e.g. pulled in by eslint/mocha) → do not add it to
dependencies(that creates a phantom runtime dep). Instead force the patched version via the existingoverridesblock inpackage.json, thennpm install. This matches how Dependabot itself fixes those (lockfile-only).
Step 4c: Clear remaining (non-security) Dependabot version-update PRs
After the security alerts are handled, fold every remaining open Dependabot PR (the ones with no matching alert from Step 1b) into the same batch branch, then close them. These are routine bumps — usually npm devDeps in vscode_extensions/ (e.g. esbuild) or js-yaml in extensions GitHub didn't alert on.
For each remaining PR, apply its bump locally rather than merging the Dependabot branch (keeps everything in one PR with one CI run):
- Read the target package + version from the PR title (
Bump <pkg> from <old> to <new> in /<path>). cdinto the manifest's directory and apply it the same way as Step 4 (see "npm transitive vs. direct deps"). For a pure devDependency like esbuild, bump it indevDependencies:npm install -D <pkg>@^<new>.- Verify it resolved:
npm ls <pkg>.
After applying all of them, compile each touched extension so a bad bump fails locally, not in CI:
cd vscode_extensions/<ext> && npm run compile # or `npm run lint` if there's no compile scriptThen close each superseded Dependabot PR referencing the batch PR (do this in Step 6, after the batch PR exists):
gh pr close <number> --repo owid/etl --comment \
"Superseded by #<batch-PR>, which applies this bump as part of a single batched Dependabot sweep. Closing as obsolete."If a bump is risky or a major version jump with breaking changes, don't force it into the batch — leave that PR open and flag it for the user instead.
Step 5: Verify changes
Run make check-all (lint + format + typecheck across the root and every lib/). The plain make check only covers the top-level codebase, so breaking changes from upgrades to packages used by lib/ (e.g. gdown's fuzzy= removal in lib/datautils/) would slip through.
If it fails, fix the issues (commonly: removed/renamed kwargs that type checkers flag) and re-run until it passes.
Step 5b: Bump lib/ package versions
If you modified any lib/{catalog,datautils,repack}/pyproject.toml, also bump that file's version = "x.y.z" (patch bump). The publish-owid-packages.yml workflow republishes these packages to PyPI on master push and rejects the publish if the version already exists.
After bumping, re-run uv lock (top-level and inside each modified lib/<name>/) so the lockfiles pick up the new version.
Step 6: Create PR
Follow the standard ETL PR workflow:
.venv/bin/etl pr "Fix <severity> Dependabot vulnerabilities" dataStage and commit all changed files:
pyproject.tomland anylib/*/pyproject.tomluv.lock- Any modified
.pyfiles (from removing unused deps) - Any
package.json/package-lock.jsonfiles
Use commit emoji 🐛🤖 (bug fix, AI-written).
After pushing, post @codex review as a PR comment.
Then close every open Dependabot PR this batch covers — both the security ones (Steps 2–4) and the version-update ones (Step 4c) — with a comment referencing this PR (see the close commands in Steps 1b and 4c). Finally, re-run the Step 1b PR list and confirm it's empty (modulo anything you deliberately left open and flagged for the user). If the title only covers security fixes but you also swept version updates, use a broader title like Fix Dependabot vulnerabilities and clear version-update PRs.
Important notes
lib/contains subdirectories (catalog,datautils,owl,repack) with their ownpyproject.tomlfiles — check these too- Multiple alerts may reference the same package (e.g. 4 alerts for pytest) — one upgrade fixes them all
- The
uv.lockfile may also be affected by[tool.uv] exclude-newersettings in pyproject.toml — if a patched version exists on PyPI but uv won't resolve it, check this setting - Some alerts may be auto-dismissed by Dependabot (state
auto_dismissed) — skip those - When multiple packages need upgrading, batch them:
uv lock --upgrade-package pkg1 --upgrade-package pkg2
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- remotion-dev/remotion★ 70ksame name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository39 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/instructions/copilot-instructions.mdCopilot instructions
- add-gdp-scatterSkill
- add-ivs-indicatorsSkill
- add-provider-regionsSkill
- babysit-prSkill
- check-chart-previewSkill
- check-empty-entitiesSkill
- check-hardcoded-yearsSkill
- check-metadata-styleSkill
- check-metadata-typosSkill
- check-outdated-practicesSkill
- create-chartSkill
- create-datasetSkill
- create-etl-stepsSkill
- create-explorerSkill
- create-snapshotSkill
- create-static-vizSkill
- develop-vscode-extensionSkill
- develop-wizard-appSkill
- draft-data-update-slack-postSkill
- edit-faust-metadataSkill
- fact-check-datasetSkill
- find-chart-referencesSkill
- generate-metadataSkill
- map-charts-to-mdimSkill
- map-explorer-to-mdimSkill
- migrate-explorer-to-etlSkill
- profile-etl-stepSkill
- query-grapher-dbSkill
- remap-ghost-variablesSkill
- report-indicator-changesSkill
- review-data-prSkill
- sync-grapher-schemaSkill
- tool-owlSkill
- update-climate-dataSkill
- update-datasetSkill
- update-wildfires-dataSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

