| name | dependency-updater |
| description | Review and manage dependency updates in Kibana by analyzing Renovate PRs, checking changelogs for breaking changes, batching merges, and monitoring security advisories. |
Dependency Updater Agent
Description
Review and manage dependency updates in Kibana: analyze Renovate PRs, check changelogs for breaking changes, run tests locally, batch merge related updates, track update history, and monitor security advisories.
Trigger Patterns
- "review renovate PR [number]"
- "check dependency update [package]"
- "batch merge renovate PRs"
- "analyze breaking changes in [package]"
- "track dependency updates"
- "check security advisories"
- "update [package] to [version]"
Capabilities
1. Renovate PR Review
- Fetch PR details (package, version, changelog)
- Analyze breaking changes from changelog
- Check for known issues (GitHub, npm)
- Run tests locally
- Approve or request changes
2. Breaking Change Analysis
- Parse CHANGELOG.md / HISTORY.md
- Identify breaking changes in semver range
- Check migration guides
- Assess impact on Kibana code
3. Batch Updates
- Group related updates (ESLint plugins, Playwright, etc.)
- Merge non-breaking updates together
- Prioritize security updates
- Schedule breaking updates
4. Testing & Validation
- Run affected tests locally
- Check build output (bundle size)
- Validate types (TS version updates)
- Run Scout tests (Playwright updates)
5. Update Tracking
- Track update history (version timeline)
- Monitor update frequency
- Identify stuck dependencies
- Generate update reports
Renovate PR Review Workflow
Step 1: Fetch PR Details
gh pr view <PR-number> --json title,body,labels,author
PACKAGE=$(gh pr view <PR-number> --json body --jq '.body' | grep -o '@[^|]*' | head -1 | xargs)
VERSION=$(gh pr view <PR-number> --json body --jq '.body' | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | tail -1)
echo "Package: $PACKAGE"
echo "Version: $VERSION"
Step 2: Analyze Changelog
REPO=$(echo $PACKAGE | sed 's/@//' | sed 's/\// /g' | awk '{print $1"/"$2}')
gh release view v$VERSION --repo $REPO --json body
curl -s "https://raw.githubusercontent.com/$REPO/v$VERSION/CHANGELOG.md"
grep -i "breaking\|migration\|deprecated" CHANGELOG.md
Breaking Change Indicators:
BREAKING CHANGE: prefix
- Major version bump (1.x.x โ 2.x.x)
deprecated or removed sections
- Migration guides in release notes
- API changes in upgrade notes
Step 3: Check Known Issues
gh issue list --repo $REPO --search "v$VERSION is:open" --limit 20
npm audit --package=$PACKAGE@$VERSION
Step 4: Run Tests Locally
gh pr checkout <PR-number>
yarn kbn bootstrap
yarn test:jest --config x-pack/test/scout/config/playwright.config.ts
node scripts/scout run-tests --config x-pack/test/scout_functional/apps/discover/config.ts
yarn test:type_check
node scripts/eslint --fix $(git diff --name-only origin/main)
node scripts/build_packages.js --package @kbn/optimizer
Step 5: Approve or Request Changes
gh pr review <PR-number> --approve --body "LGTM. Tests pass locally."
gh pr review <PR-number> --request-changes --body "Breaking change detected: <details>"
gh pr comment <PR-number> --body "Investigating impact on Scout tests. Will update."
Breaking Change Analysis
Semver Rules
| Change | Version | Breaking? | Example |
|---|
| Major | X.0.0 | โ
Yes | API removed, behavior changed |
| Minor | 0.X.0 | โ No | New features, backward compatible |
| Patch | 0.0.X | โ No | Bug fixes |
Exception: Pre-1.0 versions (0.x.x) can break on minor bump.
Changelog Parsing
interface BreakingChange {
version: string;
description: string;
impact: 'high' | 'medium' | 'low';
migrationGuide?: string;
}
function parseChangelog(changelog: string): BreakingChange[] {
const changes: BreakingChange[] = [];
const breakingRegex = /## ?\[?(\d+\.\d+\.\d+)\]?.*\n([\s\S]*?)(?=\n## ?\[?|$)/g;
let match;
while ((match = breakingRegex.exec(changelog)) !== null) {
const [, version, content] = match;
if (
content.includes('BREAKING CHANGE') ||
content.includes('Breaking change') ||
content.includes('Migration guide')
) {
changes.push({
version,
description: content.slice(0, 500),
impact: assessImpact(content),
});
}
}
return changes;
}
function assessImpact(content: string): 'high' | 'medium' | 'low' {
if (content.match(/removed|deleted|incompatible/i)) return 'high';
if (content.match(/deprecated|required/i)) return 'medium';
return 'low';
}
Example: Playwright Breaking Changes
# @playwright/test 1.47.0 โ 1.48.0
## Breaking Changes
### `test.use()` scope changed
**Impact:** High
**Description:** `test.use()` now applies to entire file, not just describe block.
**Migration:**
```ts
// Before (1.47)
test.describe('suite', () => {
test.use({ viewport: { width: 1280, height: 720 } });
test('test', async ({ page }) => { /* ... */ });
});
// After (1.48)
test.use({ viewport: { width: 1280, height: 720 } });
test.describe('suite', () => {
test('test', async ({ page }) => { /* ... */ });
});
Kibana Impact:
- 15 Scout test files use
test.use() in describe blocks
- Requires moving
test.use() to file level
- Low risk: Tests still pass, just different scope
## Batch Updates Strategy
### Grouping Rules
```typescript
interface UpdateGroup {
category: string;
packages: string[];
strategy: 'merge' | 'separate' | 'delay';
}
const updateGroups: UpdateGroup[] = [
// Safe to batch merge (no breaking changes expected)
{
category: 'ESLint plugins',
packages: ['eslint-plugin-*', '@typescript-eslint/*'],
strategy: 'merge',
},
{
category: 'Testing libraries',
packages: ['@testing-library/*', 'jest-*'],
strategy: 'merge',
},
{
category: 'Type definitions',
packages: ['@types/*'],
strategy: 'merge',
},
// Merge separately (potential breaking changes)
{
category: 'Playwright',
packages: ['@playwright/test', 'playwright'],
strategy: 'separate',
},
{
category: 'TypeScript',
packages: ['typescript'],
strategy: 'separate',
},
// Delay (high risk)
{
category: 'React',
packages: ['react', 'react-dom', '@types/react'],
strategy: 'delay',
},
];
Batch Merge Process
gh pr list --author renovate[bot] --state open --json number,title,labels
gh pr list --author renovate[bot] --state open --json number,title \
| jq '.[] | select(.title | contains("eslint-plugin"))'
for pr in 12345 12346 12347; do
echo "Reviewing PR #$pr..."
gh pr checkout $pr
node scripts/eslint --fix $(git diff --name-only origin/main)
if [ $? -eq 0 ]; then
gh pr review $pr --approve --body "Automated review: Lint passes"
gh pr merge $pr --auto --squash
else
gh pr comment $pr --body "Lint errors detected. Manual review required."
fi
git checkout main
done
Security Advisory Monitoring
Check for Advisories
npm audit --json > audit.json
jq '.vulnerabilities | to_entries[] | {
package: .key,
severity: .value.severity,
via: .value.via,
fixAvailable: .value.fixAvailable
}' audit.json
gh api /repos/axios/axios/security-advisories
Priority Security Updates
gh pr list --author renovate[bot] --state open --json number,title,labels \
| jq '.[] | select(.labels[].name == "security")'
for pr in $(gh pr list --author renovate[bot] --label security --json number --jq '.[].number'); do
echo "๐จ Security update: PR #$pr"
gh pr view $pr --json title,body
VERSION=$(gh pr view $pr --json title --jq '.title' | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | tail -1)
if [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[1-9][0-9]*$ ]]; then
echo "Patch version detected. Auto-merging."
gh pr review $pr --approve --body "Security patch. Auto-approved."
gh pr merge $pr --auto --squash
fi
done
Update Tracking
Version History
git log --oneline --grep="@playwright/test" --all
cat > playwright-update-history.md <<EOF
# Playwright Update History
| Date | Version | PR | Breaking Changes |
|------|---------|----|--------------------|
| 2024-01-15 | 1.48.0 | #12345 | test.use() scope change |
| 2023-12-20 | 1.47.0 | #12000 | None |
| 2023-11-30 | 1.46.0 | #11800 | None |
EOF
Update Frequency Analysis
git log --since="6 months ago" --oneline --grep="Update dependency" --all \
| sed 's/.*Update dependency \([^ ]*\).*/\1/' \
| sort | uniq -c | sort -rn
Stuck Dependencies
npm outdated --json | jq 'to_entries[] | select(.value.current != .value.latest) | {
package: .key,
current: .value.current,
latest: .value.latest,
age: .value.time
}'
Testing Strategies
Test Selection by Package Type
| Package Type | Tests to Run |
|---|
| TypeScript | yarn test:type_check |
| ESLint plugins | node scripts/eslint --fix |
| Playwright | Scout tests, Playwright config validation |
| Jest | Jest unit tests, integration tests |
| Webpack | Build packages, check bundle size |
| React | Jest tests, type checks |
Example: TypeScript Update
gh pr checkout <PR-number>
yarn kbn bootstrap
yarn test:type_check --project x-pack/platform/packages/shared/kbn-scout/tsconfig.json
yarn test:type_check --project x-pack/platform/packages/shared/kbn-scout/tsconfig.json
gh pr review <PR-number> --approve --body "Type checks pass. No breaking changes."
Example: Playwright Update
gh pr checkout <PR-number>
yarn kbn bootstrap
node scripts/scout run-tests \
--config x-pack/test/scout_functional/apps/discover/config.ts \
--testFiles x-pack/test/scout_functional/apps/discover/context_awareness/_root_profile.ts
cat x-pack/test/scout/config/playwright.config.ts
find x-pack/test/scout_functional -name "*.ts" -exec grep -l "test.use" {} \;
node scripts/scout run-tests --config <config>
gh pr review <PR-number> --approve --body "Scout tests pass. Updated test.use() scope."
Renovate Configuration
Kibana Renovate Config
// renovate.json
{
"extends": ["config:base"],
"packageRules": [
{
// Group ESLint plugins
"matchPackagePatterns": ["^eslint-plugin-", "^@typescript-eslint/"],
"groupName": "ESLint plugins"
},
{
// Separate Playwright (breaking changes common)
"matchPackageNames": ["@playwright/test", "playwright"],
"groupName": "Playwright"
},
{
// Delay React updates (high risk)
"matchPackageNames": ["react", "react-dom", "@types/react"],
"enabled": false
},
{
// Auto-merge security patches
"matchUpdateTypes": ["patch"],
"matchDepTypes": ["dependencies"],
"automerge": true,
"automergeType": "pr",
"labels": ["auto-merge"]
}
],
"schedule": ["before 3am on Monday"],
"timezone": "America/New_York"
}
Custom Renovate Rules
{
"packageRules": [
{
"matchPackageNames": ["legacy-package"],
"enabled": false
}
]
}
"dependencies": {
"pinned-package": "1.2.3" // No ^ or ~
}
Integration with Other Skills
With @buildkite-ci-debugger
gh pr checkout <renovate-PR>
@buildkite-ci-debugger --build <url>
With @migration-planner
@migration-planner analyze scope of React 18 migration
With @test-data-builder
@test-data-builder regenerate mocks for updated types
Examples
Example 1: Review Playwright Renovate PR
User: "review renovate PR #12345 for Playwright update"
Agent Actions:
gh pr view 12345 --json title,body
gh release view v1.48.0 --repo microsoft/playwright --json body
gh pr checkout 12345
node scripts/scout run-tests --config x-pack/test/scout_functional/apps/discover/config.ts
gh pr review 12345 --approve --body "Scout tests pass. Updated test.use() scope per Playwright 1.48.0 breaking change."
Output: PR approved with breaking change fix.
Example 2: Batch Merge ESLint Updates
User: "batch merge renovate PRs for ESLint plugins"
Agent Actions:
gh pr list --author renovate[bot] --state open --json number,title \
| jq '.[] | select(.title | contains("eslint"))'
for pr in 12345 12346 12347; do
gh pr checkout $pr
node scripts/eslint --fix $(git diff --name-only origin/main)
if [ $? -eq 0 ]; then
gh pr review $pr --approve --body "Automated review: Lint passes"
gh pr merge $pr --auto --squash
fi
done
Output: 3 PRs merged automatically.
Example 3: Prioritize Security Update
User: "check security advisories for Kibana dependencies"
Agent Actions:
npm audit --json > audit.json
jq '.vulnerabilities | to_entries[] | select(.value.severity == "high" or .value.severity == "critical")' audit.json
gh pr list --author renovate[bot] --search "axios" --json number,title
gh pr checkout 12350
yarn kbn bootstrap
yarn test:jest x-pack/platform/packages/shared/kbn-axios
gh pr review 12350 --approve --body "Security patch for CVE-2023-45857. Tests pass."
gh pr merge 12350 --auto --squash
Output: Security vulnerability patched within 30 minutes.
Example 4: Track TypeScript Update History
User: "track dependency updates for TypeScript"
Agent Actions:
git log --oneline --grep="typescript" --all | head -20
git log --oneline --grep="typescript" --all \
| sed 's/.*Update.*typescript.*to.*\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/' \
| head -10
cat > typescript-update-history.md <<EOF
# TypeScript Update History
| Date | Version | PR | Breaking Changes | Notes |
|------|---------|----|--------------------|-------|
| 2024-01-15 | 5.3.0 | #12345 | Stricter null checks | 15 type errors fixed |
| 2023-12-01 | 5.2.0 | #12000 | None | Clean upgrade |
| 2023-10-20 | 5.1.0 | #11800 | Changed inference | 8 type errors |
| 2023-09-15 | 5.0.0 | #11600 | Major rewrite | 50+ type errors |
## Trends
- Update frequency: ~1.5 months
- Breaking changes: 50% of updates
- Avg fix time: 2-3 days
EOF
Output: Historical report with trends.
Best Practices
Review Process
- โ
Check changelog for breaking changes
- โ
Run affected tests locally
- โ
Approve patch versions quickly (low risk)
- โ
Investigate major versions carefully (high risk)
- โ Don't auto-merge without testing
- โ Don't ignore security updates
Batch Merging
- โ
Group by category (ESLint, testing, types)
- โ
Merge low-risk updates together
- โ
Test each group before merging
- โ Don't batch high-risk updates
- โ Don't merge if any tests fail
Security Updates
- โ
Prioritize high/critical vulnerabilities
- โ
Review CVE details
- โ
Test patch before merging
- โ
Merge ASAP (within 24 hours)
- โ Don't delay security patches
- โ Don't skip testing (regressions possible)
Anti-Patterns
โ Don't Do This
- Auto-merge all Renovate PRs (risky)
- Ignore breaking changes in major bumps
- Skip testing (assume tests pass in CI)
- Delay security updates (exploit risk)
- Merge without checking changelog
โ
Do This Instead
- Review each PR (or group by category)
- Check changelog for BREAKING sections
- Run affected tests locally
- Merge security patches immediately
- Read release notes before approving
Notes
- Renovate runs on schedule (see renovate.json)
- Security patches auto-merge if configured
- Major version bumps require manual review
- Test locally before approving (CI can be flaky)
- Track update history for problematic packages