Skip to content

Commit 00673e9

Browse files
committed
chore: implement automated dependency management with Renovate
- Set up Renovate for automatic dependency updates - Configure smart grouping of related dependencies - Add automerge rules for safe updates (minor/patch for dev, patch for prod) - Create self-hosted Renovate workflow via GitHub Actions - Schedule updates for off-hours to minimize disruption - Add comprehensive documentation for dependency management
1 parent c0966c1 commit 00673e9

File tree

6 files changed

+459
-0
lines changed

6 files changed

+459
-0
lines changed

.github/renovate-automerge.json5

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
// Automerge configuration for Renovate
3+
"packageRules": [
4+
// Automerge for non-major devDependencies
5+
{
6+
"description": "Automatically merge minor and patch updates for dev dependencies",
7+
"matchDepTypes": ["devDependencies"],
8+
"matchUpdateTypes": ["minor", "patch"],
9+
"automerge": true,
10+
"platformAutomerge": true
11+
},
12+
13+
// Automerge for patch-only production dependencies
14+
{
15+
"description": "Automatically merge patch updates for production dependencies",
16+
"matchDepTypes": ["dependencies"],
17+
"matchUpdateTypes": ["patch"],
18+
"automerge": true,
19+
"platformAutomerge": true,
20+
"prCreation": "immediate"
21+
},
22+
23+
// Automerge GitHub Action updates
24+
{
25+
"description": "Automatically merge GitHub Actions",
26+
"matchManagers": ["github-actions"],
27+
"matchUpdateTypes": ["minor", "patch"],
28+
"automerge": true,
29+
"platformAutomerge": true
30+
},
31+
32+
// Skip certain dependency types or packages from automerge
33+
{
34+
"description": "Don't automerge major dependency updates",
35+
"matchUpdateTypes": ["major"],
36+
"automerge": false
37+
},
38+
39+
// Handle peer dependencies correctly
40+
{
41+
"description": "Widen ranges for peer dependencies",
42+
"matchDepTypes": ["peerDependencies"],
43+
"rangeStrategy": "widen"
44+
}
45+
],
46+
47+
// Avoid weekend PRs for major changes
48+
"major": {
49+
"schedule": ["after 10pm and before 5am every weekday"]
50+
},
51+
52+
// Additional automerge settings
53+
"transitiveRemediation": true,
54+
"minimumReleaseAge": "3 days"
55+
}

.github/renovate-groups.json5

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
{
2+
// Package grouping configuration for Renovate
3+
"packageRules": [
4+
// Group all non-major dependencies
5+
{
6+
"description": "Group all non-major dependencies together",
7+
"matchPackagePatterns": ["*"],
8+
"matchUpdateTypes": ["minor", "patch"],
9+
"groupName": "all non-major dependencies",
10+
"groupSlug": "all-minor-patch"
11+
},
12+
13+
// Group TypeScript ecosystem
14+
{
15+
"description": "Group TypeScript and related tooling",
16+
"matchPackagePatterns": [
17+
"^@tsconfig/",
18+
"^typescript",
19+
"^ts-",
20+
"^@types/"
21+
],
22+
"groupName": "typescript ecosystem",
23+
"groupSlug": "typescript"
24+
},
25+
26+
// Group formatting and linting tools
27+
{
28+
"description": "Group formatting and linting tools",
29+
"matchPackagePatterns": [
30+
"^@biomejs/",
31+
"^eslint",
32+
"^@eslint",
33+
"^prettier"
34+
],
35+
"groupName": "linting and formatting",
36+
"groupSlug": "linting-formatting"
37+
},
38+
39+
// Group testing tools
40+
{
41+
"description": "Group testing dependencies",
42+
"matchPackagePatterns": [
43+
"^vitest",
44+
"^@vitest/",
45+
"^jest",
46+
"^@jest/"
47+
],
48+
"groupName": "testing dependencies",
49+
"groupSlug": "testing"
50+
},
51+
52+
// Group monorepo tooling
53+
{
54+
"description": "Group monorepo tooling",
55+
"matchPackagePatterns": [
56+
"^@changesets/",
57+
"^turbo",
58+
"^lerna",
59+
"^nx"
60+
],
61+
"groupName": "monorepo tooling",
62+
"groupSlug": "monorepo-tools"
63+
},
64+
65+
// Group GitHub Actions
66+
{
67+
"description": "Group GitHub Actions",
68+
"matchManagers": ["github-actions"],
69+
"groupName": "GitHub Actions",
70+
"groupSlug": "github-actions"
71+
},
72+
73+
// Group internal workspace packages
74+
{
75+
"description": "Group internal workspace packages",
76+
"matchPackagePatterns": [
77+
"^@monorepo/"
78+
],
79+
"matchUpdateTypes": ["major", "minor", "patch"],
80+
"groupName": "internal packages",
81+
"groupSlug": "internal-deps"
82+
}
83+
]
84+
}

.github/workflows/renovate.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Renovate
2+
3+
on:
4+
# Schedule: run every day at 2am
5+
schedule:
6+
- cron: '0 2 * * *'
7+
8+
# Run on demand via workflow_dispatch
9+
workflow_dispatch:
10+
inputs:
11+
logLevel:
12+
description: 'Renovate log level'
13+
required: true
14+
default: 'info'
15+
type: choice
16+
options:
17+
- debug
18+
- info
19+
- warn
20+
- error
21+
dryRun:
22+
description: 'Dry run'
23+
type: boolean
24+
default: false
25+
26+
# Prevent multiple Renovate runs from happening simultaneously
27+
concurrency:
28+
group: renovate
29+
cancel-in-progress: false
30+
31+
jobs:
32+
renovate:
33+
name: Renovate
34+
runs-on: ubuntu-latest
35+
36+
# Allow renovate to create PRs
37+
permissions:
38+
contents: write
39+
pull-requests: write
40+
issues: write
41+
42+
steps:
43+
- name: Checkout
44+
uses: actions/checkout@v4
45+
46+
# Use custom docker-based renovate to run self-hosted
47+
- name: Self-hosted Renovate
48+
uses: renovatebot/github-action@v40.0.4
49+
with:
50+
configurationFile: renovate.json5
51+
token: ${{ secrets.GITHUB_TOKEN }}
52+
env:
53+
LOG_LEVEL: ${{ inputs.logLevel || 'info' }}
54+
DRY_RUN: ${{ inputs.dryRun == true && 'full' || '' }}
55+
RENOVATE_BASE_BRANCHES: 'main'
56+
RENOVATE_EXTENDS: 'config:recommended,group:allNonMajor'
57+
# Include local configuration files
58+
RENOVATE_CONFIG_FILE: 'renovate.json5'
59+
RENOVATE_EXTENDS_FROM: |
60+
.github/renovate-automerge.json5
61+
.github/renovate-groups.json5

docs/DEPENDENCY_MANAGEMENT.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Dependency Management
2+
3+
This project uses [Renovate](https://docs.renovatebot.com/) to automate dependency updates across the monorepo. This document describes how dependency updates are managed and how to work with the system.
4+
5+
## Overview
6+
7+
Renovate automatically:
8+
9+
1. Monitors all dependencies in the monorepo
10+
2. Creates pull requests for updates
11+
3. Groups related updates together to reduce PR noise
12+
4. Automatically merges safe updates
13+
5. Maintains a dependency dashboard
14+
15+
## Configuration Files
16+
17+
The Renovate configuration is split across several files:
18+
19+
- `renovate.json5` - Main configuration file
20+
- `.github/renovate-automerge.json5` - Auto-merge settings
21+
- `.github/renovate-groups.json5` - Package grouping settings
22+
- `.github/workflows/renovate.yml` - GitHub workflow for self-hosted Renovate
23+
24+
## Update Schedule
25+
26+
Renovate is configured to run:
27+
28+
- Daily at 2:00 AM UTC via GitHub Actions
29+
- Only creates PRs during off-hours (after 10pm and before 5am on weekdays, and on weekends)
30+
- Lock file maintenance on Monday mornings
31+
- Can be triggered manually via GitHub Actions workflow dispatch
32+
33+
## Update Strategy
34+
35+
The system follows these strategies:
36+
37+
1. **Minor and patch updates** are grouped together and auto-merged if tests pass
38+
2. **Dev dependencies** are automatically merged for minor and patch versions
39+
3. **Production dependencies** have stricter rules, with only patch versions auto-merged
40+
4. **Major updates** require manual review and approval
41+
5. **GitHub Actions** are automatically updated for minor and patch versions
42+
43+
## Package Grouping
44+
45+
Dependencies are grouped into logical categories:
46+
47+
- TypeScript ecosystem (TypeScript, tsconfig, type definitions)
48+
- Linting and formatting tools (Biome, ESLint, Prettier)
49+
- Testing tools (Vitest, Jest)
50+
- Monorepo tooling (Changesets, Turborepo)
51+
- Internal workspace packages
52+
53+
## Working with Renovate
54+
55+
### Dependency Dashboard
56+
57+
Renovate maintains a dependency dashboard as a pinned issue in the repository. This provides:
58+
59+
- Overview of all pending updates
60+
- PRs that need attention
61+
- Rejected/ignored updates
62+
- Upcoming major updates
63+
64+
### Manual Control
65+
66+
You can influence Renovate behavior:
67+
68+
- Add `renovate:disable` comment in a PR to prevent Renovate from rebasing it
69+
- Add specific packages to `ignoreDeps` in configuration to prevent updates
70+
- Use the dashboard to manually trigger specific updates
71+
72+
### Best Practices
73+
74+
1. **Review major updates carefully** - These can contain breaking changes
75+
2. **Don't modify package.json versions directly** - Let Renovate manage this
76+
3. **Use the dashboard** to monitor and manage update flow
77+
4. **Create changeset entries** for dependency updates that affect consumers
78+
79+
## Troubleshooting
80+
81+
If Renovate isn't working as expected:
82+
83+
1. Check the Renovate logs in GitHub Actions
84+
2. Verify configuration files are valid JSON5
85+
3. Look at the dependency dashboard for errors
86+
4. Run Renovate manually via workflow dispatch with debug logging
87+
88+
## Further Reading
89+
90+
- [Renovate Documentation](https://docs.renovatebot.com/)
91+
- [Renovate GitHub Action](https://github.com/renovatebot/github-action)
92+
- [Monorepo Support in Renovate](https://docs.renovatebot.com/getting-started/installing-onboarding/#monorepos)

renovate.json

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3+
"extends": [
4+
"config:recommended",
5+
":semanticCommits",
6+
"helpers:pinGitHubActionDigests"
7+
],
8+
"baseBranches": ["main"],
9+
"rangeStrategy": "bump",
10+
"dependencyDashboard": true,
11+
"schedule": ["after 10pm and before 5am every weekday", "every weekend"],
12+
"prConcurrentLimit": 5,
13+
"prHourlyLimit": 2,
14+
15+
"packageRules": [
16+
{
17+
"matchDepTypes": ["devDependencies"],
18+
"matchUpdateTypes": ["minor", "patch"],
19+
"automerge": true
20+
},
21+
{
22+
"matchPackagePatterns": ["*"],
23+
"matchUpdateTypes": ["minor", "patch"],
24+
"groupName": "all non-major dependencies",
25+
"groupSlug": "all-minor-patch"
26+
},
27+
{
28+
"matchPackagePatterns": ["^@biomejs/", "^typescript"],
29+
"groupName": "typescript and formatting dependencies",
30+
"groupSlug": "typescript-formatting"
31+
},
32+
{
33+
"matchPackagePatterns": ["^vitest", "^@vitest/"],
34+
"groupName": "testing dependencies",
35+
"groupSlug": "testing-deps"
36+
},
37+
{
38+
"matchPackagePatterns": ["^@changesets/", "turbo"],
39+
"groupName": "monorepo tooling",
40+
"groupSlug": "monorepo-tools"
41+
},
42+
{
43+
"matchDepTypes": ["peerDependencies"],
44+
"rangeStrategy": "widen"
45+
}
46+
],
47+
48+
"lockFileMaintenance": {
49+
"enabled": true,
50+
"schedule": ["before 5am on monday"]
51+
},
52+
53+
"ignoreDeps": [
54+
"pnpm"
55+
],
56+
57+
"commitMessagePrefix": "chore(deps):",
58+
"commitMessageAction": "update",
59+
"commitMessageTopic": "{{depName}}",
60+
"commitBodyTable": true,
61+
62+
"pnpmShrinkwrap": true,
63+
"npmrc": "@monorepo:registry=https://registry.npmjs.org/"
64+
}

0 commit comments

Comments
 (0)