# Renovate

> Handle Renovate bot dependency update branches end-to-end. Use this skill whenever working on a renovate/* branch, reviewing a Renovate MR, or asked to "handle renovate", "process a renovate update", "fix a renovate branch", or "apply a dependency upgrade". The skill identifies what was upgraded, researches breaking changes, adapts code, and verifies builds and tests pass.

- Skill: `d-rk/renovate` (Agent Skill)
- Install (CLI): `npx skillmds@latest add d-rk/renovate`
- Raw SKILL.md: https://api.skillmd.com/api/skills/d-rk/renovate/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: d-rk (https://skillmd.com/u/d-rk)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/d-rk/renovate

---


# Renovate Update Handler

Renovate branches bump versions but can't adapt code to breaking changes. This skill picks up where Renovate left off: understand what changed, research the impact, fix the code, verify it works.

---

## Step 1: Identify the Update

Determine which branch to work on:
- If already on a `renovate/*` branch, use it.
- Otherwise, list the Gitlab MRs:
  ```bash
    PROJECT=$(git remote get-url origin | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|')
    glab api graphql -f query="
    {
      project(fullPath: \"$PROJECT\") {
        mergeRequests(state: opened, first: 100) {
          nodes {
            sourceBranch
            webUrl
            description
            headPipeline { status }
          }
        }
      }
    }" | jq '[
      .data.project.mergeRequests.nodes[]
      | select(.sourceBranch | startswith("renovate/"))
      | {
          branch: .sourceBranch,
          url: .webUrl,
          change: (
            .description
            | capture("`(?<from>[^`]+)` -> `(?<to>[^`]+)`")
            | "\(.from) -> \(.to)"
          ),
          pipeline: (.headPipeline.status // "none")
        }
    ]'
  ```
  - If the CLI is not available, stop here and tell the user to install it.
- Prefer the MRs where the pipeline did not fail.
- Ask the user which MR resp. branch to process.

Checkout the branch if not already on it, then inspect what changed:

```bash
BASE_BRANCH=$(git branch -r | grep -oE 'origin/(develop|main|master)' | head -1 | sed 's|origin/||'); \
git diff $(git merge-base HEAD $BASE_BRANCH)...HEAD -- \
  '*.mod' '*/go.sum' \
  '*/package.json' '*/package-lock.json' '*/yarn.lock' '*/pnpm-lock.yaml' \
  '*/pom.xml' \
  '*/Cargo.toml' '*/Cargo.lock' \
  '*/requirements*.txt' '*/pyproject.toml' '*/poetry.lock' \
  '*/Gemfile' '*/Gemfile.lock' \
  'Dockerfile*' '*.bicep'
```

Parse the diff to extract:
- **Package name(s)** — e.g., `com.example:artifact`, `@types/react`, `github.com/foo/bar`
- **Old version → New version** — look for `-` and `+` lines in version files
- **Which directories are affected** — which manifest files changed
- **Which language/ecosystem** — determines which playbook to follow in Step 4 and 5

---

## Step 2: Research Breaking Changes

For each upgraded package, search for breaking changes in the version range:

- Search for `<package> <old_version> to <new_version> breaking changes migration`
- Search for `<package> changelog <new_version>` or `<package> release notes`
- For major version bumps (e.g., 1.x.x → 2.x.x), always look for a migration guide
- For minor version bumps (e.g., 1.2.x → 1.3.x), always look for breaking changes in release notes

Summarize: list any renamed APIs, removed functions, changed signatures, new required configuration, or changed behavior.

If there are no breaking changes (patch bump with clean changelog), note that and proceed quickly to Step 4.

---

## Step 3: Analyze Codebase Usage

Search the codebase for usages of the upgraded package using patterns appropriate to the ecosystem:

- **Go**: grep for `"<package-path>"` in `*.go` files
- **npm/Node.js**: grep for `require('<package>')`, `from '<package>'` in `*.ts`, `*.tsx`, `*.js` files
- **Maven/Java**: grep for `<groupId>`, `<artifactId>`, or the class/package name in `*.java` files
- **Python**: grep for `import <package>` or `from <package>` in `*.py` files
- **Rust**: grep for the crate name in `*.rs` files

Focus on the specific APIs that changed. Identify which files need updating.

---

## Step 4: Adapt the Code

Apply the necessary changes based on the breaking changes you found:

- Rename renamed functions/types/methods
- Update changed function signatures or call sites
- Replace removed APIs with their equivalents
- Update configuration objects to match new schemas
- Add new required imports or remove obsolete ones

Make changes surgically — only what the version change requires. Don't refactor surrounding code.

After editing, run the post-update tidy/sync step for the ecosystem (see **Language Playbooks** below).

---

## Step 5: Verify Build and Tests

Run build and tests in each affected directory using the appropriate commands from the **Language Playbooks** below.

If tests fail:
1. Read the error output carefully — it usually points directly to what still needs changing.
2. Check if the failure is a compile error (API mismatch) or a test assertion (behavior change).
3. Fix the issue and re-run. If stuck, search for the specific error message + package name.

---

## Step 6: Report

When done, summarize:
- What package(s) were upgraded and by how much
- What breaking changes existed (or "none found" for clean bumps)
- What code was changed and why
- Build/test status: passing or any remaining issues

If you couldn't resolve a failure, explain what you tried and stop here.

---

## Step 7: Push branch

You must ask for confirmation to push the branch, if not confirmed stop here.

Push changes and verify the pipeline passes:

```bash
git push
```

Then poll for the new pipeline to complete:

```bash
MR=<mr-iid>

# Wait for pipeline to finish (poll every 30s)
while true; do
  STATUS=$(glab mr view $MR -F json | jq -r '.head_pipeline.status')
  echo "Pipeline status: $STATUS"
  [[ "$STATUS" != "running" && "$STATUS" != "pending" && "$STATUS" != "created" ]] && break
  sleep 30
done
echo "Final status: $STATUS"
```

If pipeline **succeeded** → proceed to Step 8.

If pipeline **failed** → fetch logs and go back to Step 4:

```bash
PIPELINE_ID=$(glab mr view $MR -F json | jq -r '.head_pipeline.id')

# Failed direct jobs
glab api "/projects/:id/pipelines/$PIPELINE_ID/jobs" | \
  jq '[.[] | select(.status == "failed") | {id, name, stage}]'

# Failed bridge jobs → child pipelines
glab api "/projects/:id/pipelines/$PIPELINE_ID/bridges" | \
  jq '[.[] | select(.status == "failed") | {name, child_id: .downstream_pipeline.id}]'

# For each failed child_id:
CHILD_ID=<child_id>
FAILED_JOB_ID=$(glab api "/projects/:id/pipelines/$CHILD_ID/jobs" | \
  jq -r '[.[] | select(.status == "failed")] | first | .id')

# Fetch logs
glab api "/projects/:id/jobs/$FAILED_JOB_ID/trace"
```

Analyze logs, fix the issue (Step 4), then repeat from top of Step 7.

---

## Step 8: Merge

You must ask for confirmation to merge the MR, if not confirmed stop here.

Before merging:
- Check that the MR build is successful.
- There must not be any open discussions.
- Add a comment to the MR telling what you did. Use the prefix text "Generated by Claude".
  - GitLab: `glab mr note <mr-id> --message "Generated by Claude: ..."`

then merge with: `glab mr merge <mr-id> --squash`

After each merge, wait 5 seconds before merging the next MR to let the platform recover:
```bash
sleep 5
```

If a merge fails due to conflicts, rebase the branch and retry once:
Rebase locally so conflicts can be resolved:
```bash
git fetch origin
git checkout <renovate-branch>
git rebase origin/<base-branch>
# resolve any conflicts, then:
git push --force-with-lease
```
After the push triggers a new pipeline and it passes, re-run the merge command.

If the retry also fails, leave the MR for now and move on.

---

## Language Playbooks

Each playbook is self-contained. Jump to the one matching the ecosystem detected in Step 1. When a project uses multiple ecosystems, apply each relevant playbook.

---

### Go

**Detect:** `go.mod` or `go.sum` changed.

**Post-update tidy** (run in each affected module directory after editing):
```bash
go mod tidy
```

**Verify:**
```bash
go build ./...
go test ./...
```

**Common patterns:**
- Major version import path changes: `github.com/foo/bar` → `github.com/foo/bar/v2` — update all import statements in affected `.go` files.
- Minor/patch: `go mod tidy` is usually all that's needed.

---

### Maven / Java

**Detect:** `pom.xml` changed.

**Post-update sync** (Maven resolves dependencies on the next build; no explicit sync needed):
```bash
# Optional: pre-download deps to check for resolution errors
mvn dependency:resolve -q
```

**Verify** (in the affected module directory, or root for full build):
```bash
mvn verify
```

**Lint only:**
```bash
mvn verify -Plint
```

**Common patterns:**
- Spring Boot / Spring Framework upgrades: check for deprecated `@Bean`, `SecurityFilterChain`, or property key changes.
- Jakarta EE namespace migration (`javax.*` → `jakarta.*`): search all `.java` files for old namespace and update imports.
- Major version bumps: check for removed APIs in the library's migration guide.
- `pom.xml` property version variables: Renovate typically updates the `<version>` inside `<dependency>` blocks — confirm the right property was updated if the project uses `<properties>`.

---

### npm / Node.js

**Detect:** `package.json`, `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml` changed.

**Post-update sync** (install to update lockfile and node_modules):
```bash
npm install       # or: yarn install / pnpm install
```

**Verify:**
```bash
npm run build     # if a build step exists
npm test          # or: npm run test / npx vitest run / npx jest
npm run lint      # if a lint step exists
```

**Common patterns:**
- Type-only changes (`@types/*`): search for type usages that match changed types, update annotations.
- CJS → ESM migration: check for `require()` usage that needs to become `import`.
- Major version bumps: check `peerDependencies` — other packages may need updating too.
- Minor/patch: `npm install` to sync lockfile, then run tests.
- **Peer dependency conflicts:** If `npm install` fails with peer dep errors, do not add `--legacy-peer-deps`. That flag masks real incompatibilities and can cause subtle runtime failures. Instead, identify which packages conflict and resolve them properly.

---

### Python

**Detect:** `requirements*.txt`, `pyproject.toml`, `poetry.lock`, or `setup.py` changed.

**Post-update sync:**
```bash
pip install -r requirements.txt    # or: pip install -e . / poetry install
```

**Verify:**
```bash
python -m pytest                   # or: python -m unittest discover
```

**Common patterns:**
- Major version bumps: check for renamed modules or removed functions in the changelog.
- Minor/patch: sync dependencies and run tests.

---

### Rust / Cargo

**Detect:** `Cargo.toml` or `Cargo.lock` changed.

**Post-update sync:**
```bash
cargo update      # syncs Cargo.lock to the new version pins
```

**Verify:**
```bash
cargo build
cargo test
```

**Common patterns:**
- Trait or API changes: compiler errors will point directly to the affected lines.
- Major version bumps: update the version in `Cargo.toml` and check for API changes.

---

### Ruby / Bundler

**Detect:** `Gemfile` or `Gemfile.lock` changed.

**Post-update sync:**
```bash
bundle install
```

**Verify:**
```bash
bundle exec rspec     # or: bundle exec rake test
```

---

## Adding Support for a New Ecosystem

To add a new language/ecosystem to this skill, add a new `###` subsection under **Language Playbooks** with:
1. **Detect:** — what file pattern signals this ecosystem
2. **Post-update sync** — command to sync/install after version bump
3. **Verify** — build and test commands
4. **Common patterns** — recurring issues specific to this ecosystem

---

## Quick Reference

**No code changes needed** (most minor/patch bumps):
- Run tests to confirm nothing broke

**Clean patch bump checklist:**
- Go: `go mod tidy` → `go test ./...`
- Maven: `mvn verify`
- npm: `npm install` → `npm test`
- Python: `pip install -r requirements.txt` → `python -m pytest`
- Rust: `cargo update` → `cargo test`

