| name | dependency-updates |
| description | Triage, evaluate, and apply dependency updates safely — whether from Renovate PRs, a proactive audit, or a project that has fallen behind. Use this skill when you need to discover what is outdated, decide what is safe to update in parallel, sequence updates that have ordering constraints, evaluate changelogs and blast radius, adapt code to breaking changes, and verify the result. Covers any ecosystem (Python, JavaScript/TypeScript, Go, Ruby, Rust, Java, etc.) and any layer of the stack (libraries, frameworks, Helm/Kubernetes charts, Docker base images, Apt/system packages, databases, operators, Terraform/Pulumi providers).
|
| license | BSD-3-Clause |
| metadata | {"category":"process"} |
Dependency Updates
Scope
| Layer | Examples |
|---|
| Language library / framework | Python packages, npm packages, Go modules, Ruby gems, Cargo crates, Maven artifacts |
| Container base image | FROM python:3.9-slim → 3.12-slim, ubuntu:20.04 → 24.04, distroless variants |
| System / OS packages | apt-get install, Alpine apk, Homebrew brew in CI |
| Helm / Kubernetes charts | Bitnami charts, operator Helm releases, CRD-carrying chart upgrades |
| Database / storage | PostgreSQL, Redis, Elasticsearch, MongoDB — via Helm, Docker Compose, or operators |
| Infrastructure tooling | Terraform providers, Pulumi SDKs, OpenTofu modules |
Effort sizing
| Bump | Library | Infra / DB | Base image |
|---|
| Patch (x.y.z) | Changelog skim + test run | Changelog skim + test run | Rebuild + smoke |
| Minor (x.y.0) | Changelog + usage check + test | Changelog + values diff + test | Rebuild + smoke test |
| Major (x.0.0) | Full Phase 1–6 | Full Phase 1–6 + staging | Full Phase 1–6 + rebuild |
| Digest / date pin | Rebuild + smoke | N/A | Rebuild + smoke |
Phase 0 — Discover what is outdated
When you don't have an automated tool handing you a list, generate it yourself. Run the appropriate command for each ecosystem present in the project.
Python
uv pip list --outdated
pip list --outdated
pip-audit
JavaScript / TypeScript
npm outdated
bun outdated
yarn outdated
pnpm outdated
npm audit
Go
go list -m -u all
govulncheck ./...
Ruby
bundle outdated
bundle audit
Rust
cargo outdated
cargo audit
Helm / Kubernetes charts
helm repo update
helm search repo <chart-name> --versions | head -20
helm dependency list
Docker base images
There is no universal "outdated" command for base images. Check freshness by:
docker pull <image>:<tag> --quiet
docker inspect <image>:<tag> --format '{{index .RepoDigests 0}}'
Or check the image's registry page / GitHub releases for the upstream project.
Terraform / OpenTofu providers
terraform providers lock -upgrade
tofu providers lock -upgrade
git diff .terraform.lock.hcl
Apt / system packages (in Dockerfile or CI)
apt-get update && apt list --upgradable 2>/dev/null
Phase 1 — Characterize each update
For each outdated package (from Phase 0, from Renovate, or from a targeted single-package check):
gh pr checkout <PR number>
git diff HEAD~1 -- '*.toml' '*.json' '*.yaml' '*.lock' 'Dockerfile*' '*.tf'
Establish for each package:
- Version range: old → new
- Bump classification: patch / minor / major / digest
- Direct or transitive dependency
- Stack layer (library, chart, base image, system, DB)
Phase 2 — Evaluate the changelog
Where to find it
- GitHub releases (most authoritative):
gh api repos/<owner>/<repo>/releases --jq '.[].body'
- Package registry pages — PyPI, npm, crates.io, pkg.go.dev all link to changelogs
CHANGELOG.md in the repo — often more complete than release notes
- Helm charts — diff
values.yaml between versions, which is where breaking changes hide:
helm show values <repo>/<chart> --version <old> > old.yaml
helm show values <repo>/<chart> --version <new> > new.yaml
diff old.yaml new.yaml
- Docker base images — check the upstream project release page plus the base OS release notes (e.g., Debian Bookworm migration guide)
What to flag
Read every entry from the current version to the new version:
- Breaking change — API removals, signature changes, renamed config keys, removed CLI flags
- Deprecation — items that now emit warnings; not merge blockers, but open a follow-up task
- Security fix — CVE IDs and advisory links; these jump to the front of the queue
- Silent behavior change — changed defaults, altered retry/timeout/encoding behavior
- Runtime requirement raised — minimum Python/Node/Go version bumped above what you run
Phase 3 — Locate usages (blast radius)
Build a list of every file that references the package.
Language libraries
rg "<package-name>" --type py
rg "\"<package-name>\"" go.mod
rg "<package-name>" --type ts --type tsx
rg "'<gem-name>'" Gemfile
rg '"<crate>"' Cargo.toml
Also search config files that reference the package by name: plugin configs, lint configs, CI workflow steps.
Docker / container base images
rg "FROM <image-name>" --glob 'Dockerfile*' --glob '*.dockerfile'
rg "apt-get install" --glob 'Dockerfile*'
Multi-stage builds: check whether intermediate AS build stages also use the image.
Helm / Kubernetes charts
rg "<chart-name>" charts/ -l
helm template <release-name> <chart> -f values.yaml > baseline.yaml
Phase 4 — Evaluate impact
Cross-reference each usage site against the changelog flags from Phase 2.
| Finding | Decision |
|---|
| No breaking changes in range | Skip Phase 5, go to Phase 6 |
| Deprecated API in use | Note; do not block; open a follow-up task |
| Removed/changed API in use | Must adapt before applying → Phase 5 |
| Behavior change at a usage site | Write or update a test to assert the new behavior |
| Runtime requirement raised above current | Upgrade runtime first as a separate dependency |
Layer-specific checks
Base image (Docker):
Helm chart major bumps:
- Diff CRDs: fields may be promoted, removed, or have changed validation
- Verify
apiVersion in rendered manifests is supported by your target cluster version
- Identify renamed or removed
values.yaml keys against your override files
- Run
helm template <release> <chart> --version <new> -f your-values.yaml | kubectl apply --dry-run=server -f - to surface renamed or missing keys before upgrading
Database / operator major versions:
- Check for removed SQL functions, changed defaults, wire protocol changes
- Verify the ORM or driver supports the new server version
- Determine if the chart upgrade implies a data migration — PostgreSQL major upgrades require
pg_upgrade or a dump-restore cycle; this must be planned independently of the chart bump
- Validate against a staging or local instance before applying to production
Infrastructure tooling:
- Run
plan / preview before merging — provider majors often rename resources or move arguments
- Check for deprecated resource types that were removed in the new version
Phase 5 — Adapt code (only if Phase 4 found a blocker)
Make the minimum change to satisfy the new API. Do not refactor surrounding code.
If the package provides a codemod, migration script, or official upgrade guide, follow it rather than hand-editing.
After adapting:
- Re-run type checkers and linters
- Confirm the changed call sites resolve (
python -c "import <pkg>", go build ./..., etc.)
- For Docker: rebuild locally and confirm startup behavior
Phase 6 — Verify
Run the full test suite before committing the update.
pytest -x
go test ./...
npm test
cargo test
bundle exec rspec
Also run linters and type checkers — minor bumps can introduce type errors without breaking tests.
For infrastructure:
helm template . -f values.yaml | kubectl apply --dry-run=server -f -
pulumi preview --stack <stack>
terraform plan
Interpreting failures
- Import / link errors → API changed; return to Phase 5
- Type errors → fix call sites; don't suppress without an explanatory comment
- Failures in unrelated modules → investigate before assuming pre-existing; transitive behavior changes surface far from the import
- Docker build failures → check
apt-get pins and runtime compatibility with the new base
- Helm dry-run failures → a value key was renamed or a CRD version changed; re-run the values diff
Batch strategy — working through a backlog
Whether you discovered the backlog via uv pip list --outdated, npm outdated, go list -m -u all, or a pile of Renovate PRs, the same sequencing logic applies.
Step 1: Build the full inventory
Run Phase 0 for every ecosystem in the project. Produce a flat list: package name, current version, latest version, bump type. Group by ecosystem.
Step 2: Classify by risk tier
| Tier | Criteria | Approach |
|---|
| 1 — Security | Known CVE or security advisory | Apply immediately, ahead of everything else |
| 2 — Patch | x.y.z bumps | Batch-apply per ecosystem; one test run per batch |
| 3 — Minor (clean) | No breaking flags in changelog | Review + test, one ecosystem group at a time |
| 4 — Minor (with deprecations) | Deprecations in use | Review + adapt + test; open follow-up tasks |
| 5 — Major | API or behavior changes | Full Phase 1–6 per package, one at a time |
| 6 — Runtime / OS / DB | Base image, database major, language runtime | Last; staging validation required |
Step 3: Determine what can be parallelized
Many updates within a tier can be applied simultaneously:
Safe to batch (apply together, one test run):
- All patch bumps within a single ecosystem (e.g., every Go module patch in one
go get -u=patch ./...)
- All minor bumps within an ecosystem that have no breaking flags and no dependency relationships between them
- Updates across different ecosystems at the same tier (Go patches and npm patches can proceed simultaneously on separate branches)
Must be sequenced (one at a time or in explicit order):
- Runtime before libraries — if a library requires Python 3.12+, upgrade Python first; the library upgrade is blocked until then
- Leaf before root — if package A imports package B, upgrade B before A, or their version constraints may conflict
- DB client before DB server — the driver or ORM must support the new protocol before the server is upgraded
- CRDs before operator chart — Kubernetes applies CRDs separately; an operator upgrade that references a missing CRD field will fail
- Major bumps within the same module graph — do not combine multiple major bumps that touch overlapping files; you won't be able to attribute failures
For cross-ecosystem updates (Go service + npm frontend + Helm charts), those ecosystems are independent and their work streams can proceed in parallel even when their internal sequencing differs.
Step 4: Apply in waves, test between each
Wave 1 — Security: apply individually; fast-path merge
Wave 2 — Patches: batch per ecosystem with `uv sync`, `go get -u=patch`, `npm update --save-exact`, etc.
Wave 3 — Clean minors: one ecosystem group at a time; full test suite after each group
Wave 4 — Minors with deprecations: adapt call sites, then test
Wave 5 — Majors: one package at a time, full Phase 1–6
Wave 6 — Runtime / OS / DB: coordinate with deployment; validate in staging
Run the full test suite after each wave. If a wave introduces failures, diagnose before proceeding to the next wave — do not accumulate undiagnosed failures across multiple waves.
Useful batch-apply commands by ecosystem
uv lock --upgrade-package <pkg>
uv lock --upgrade && uv sync
go get -u=patch ./...
go mod tidy
npm update
npm install <pkg>@<version>
cargo update
cargo update -p <crate>
bundle update --patch
bundle update <gem>
helm dependency update
Step 5: Track progress
Keep a simple checklist in a tracking issue or branch description:
[ ] Wave 1 — security: CVE-2024-xxxxx (pkg A), CVE-2024-yyyyy (pkg B)
[x] Wave 2 — patches: 14 Go modules, 8 npm packages — CI green
[ ] Wave 3 — clean minors: Go (in progress), npm (pending), Helm (pending)
Decision matrix
| Signal | Action |
|---|
| Patch bump, tests green | Apply |
| Minor bump, no breaking flags, tests green | Apply |
| Minor bump, deprecation warnings new | Apply + open follow-up task |
| Major bump, no usage of changed APIs, tests green | Apply |
| Major bump, removed API in use | Adapt code (Phase 5), then apply |
| Base image major bump | Build locally, smoke test, then apply |
| DB / operator major bump | Validate in staging; coordinate with deploy |
| Security advisory (any bump size) | Prioritize; apply ahead of the queue |
| Tests fail, root cause unclear | Do not apply; open investigation task |
| Runtime version requirement raised | Upgrade runtime first as its own wave |
| Two updates touch overlapping files | Sequence them; do not combine |