From d76f1d3d49aa4eb7ed8e8c1e73b6b13fa683c53c Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Sat, 7 Mar 2026 20:03:31 +0200 Subject: [PATCH] chore: overhaul renovate preset config, docs, and tooling - Switch schema to renovate-global-schema.json - Remove redundant/deprecated settings and presets - Add Makefile custom manager for tool version tracking - Add package groups: illuminate, semantic-release, stylelint, tailwind, vite, vue, development tools - Add check-jsonschema pre-commit hook - Add .gitignore and CLAUDE.md - Rewrite README with comprehensive preset documentation --- .gitignore | 1 + .pre-commit-config.yaml | 12 ++- CLAUDE.md | 40 +++++++++ README.md | 188 ++++++++++++++++++++++++++++++++++++---- default.json | 108 +++++++++++++++-------- 5 files changed, 291 insertions(+), 58 deletions(-) create mode 100644 .gitignore create mode 100644 CLAUDE.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34c4fbb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.claude/settings.local.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 357243a..6e7820c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,8 +16,18 @@ repos: - id: trailing-whitespace - repo: https://github.com/renovatebot/pre-commit-hooks - rev: 43.58.0 + rev: 43.59.2 hooks: - id: renovate-config-validator files: default.json args: [--strict] + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.37.0 + hooks: + - id: check-jsonschema + name: check-renovate-preset + files: default.json + args: + - --schemafile + - https://docs.renovatebot.com/renovate-global-schema.json diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1126d92 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,40 @@ +# CLAUDE.md + +## Project overview + +Shared [Renovate](https://github.com/renovatebot/renovate) preset configuration for repositories managed by ivuorinen. Other repos consume this preset via `"extends": ["github>ivuorinen/renovate-config"]` in their Renovate config. + +## Repository structure + +``` +default.json # The shared Renovate preset (this is the main artifact) +.github/renovate.json # This repo's own Renovate config (self-referencing) +.pre-commit-config.yaml # Pre-commit hooks including config validation +.editorconfig # Editor conventions +LICENSE # MIT +README.md # Usage instructions +``` + +## Validation + +Run the pre-commit hook to validate `default.json`: + +```sh +pre-commit run --all-files +``` + +This runs two validators against `default.json`: `renovate-config-validator --strict` (Renovate's own validator) and `check-renovate` (JSON Schema validation via [check-jsonschema](https://github.com/python-jsonschema/check-jsonschema)). The hooks also enforce JSON formatting (`pretty-format-json --autofix --no-ensure-ascii`), trailing whitespace removal, and other checks. + +## How default.json works + +- Extends `config:recommended` and several Renovate built-in presets +- Defines `packageRules` for automerge (minor/patch), labeling by update type and datasource, and grouping (devDependencies, eslint, phpstan) +- Includes a `customManagers` regex manager for Dockerfile ENV/FROM version extraction +- Configures semantic commits (`chore(deps):` scope), squash automerge strategy, and non-office-hours schedule (Europe/Helsinki) +- Sets `postUpdateOptions` for lock file deduplication across bundler, composer, go, npm, pnpm, and yarn + +## Conventions + +- 2-space indentation, UTF-8, LF line endings, final newline (per `.editorconfig`) +- JSON keys in `default.json` are sorted alphabetically +- No build system, no tests, no application code diff --git a/README.md b/README.md index cadf79c..a025831 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,13 @@ -# Renovate configs +# Renovate Config -[Renovate](https://github.com/renovatebot/renovate) is a tool for automating -dependency updates. This repository contains my personal -Renovate configuration. +Shared [Renovate](https://github.com/renovatebot/renovate) preset configuration +for repositories managed by **ivuorinen**. Other repos consume this preset via +their Renovate config, so changes here propagate automatically to every +repository that extends it. -This configuration and Renovate creates a single issue in the repository for -tracking all dependency updates. Renovate will automatically update the -issue with new updates and you can force creation and rerunning of the -Renovate bot by checking list items in the issue. +## Usage -Updates to the configuration are automatically applied to all repositories -that use this configuration. If you want to use this configuration in your -projects you can do so by extending this configuration in your own -in `.github/renovate.json` file. - -Please see Renovate configuration documentation to see how you can -extend this configuration to suit your needs. - -## Basic usage: - -Create a file to `.github/renovate.json` with the following content: +Create `.github/renovate.json` in your repository: ```json { @@ -28,6 +16,168 @@ Create a file to `.github/renovate.json` with the following content: } ``` +See [Renovate Docs: Shareable Config Presets](https://docs.renovatebot.com/config-presets/) +for more on how shared presets work. + +## Extends + +This preset inherits from the following built-in Renovate presets: + +| Preset | Description | +|--------|-------------| +| `config:recommended` | Renovate's recommended base configuration | +| `:enableVulnerabilityAlerts` | Create PRs for known security vulnerabilities | +| `:labels(dependencies)` | Add `dependencies` label to all PRs | +| `:preserveSemverRanges` | Keep existing semver range syntax when updating | +| `:semanticCommits` | Use conventional commit messages (`chore(deps):`) | +| `:timezone(Europe/Helsinki)` | Schedule evaluation in Europe/Helsinki timezone | +| `docker:enableMajor` | Enable major version updates for Docker | +| `helpers:pinGitHubActionDigests` | Pin GitHub Actions to full SHA digests | +| `security:minimumReleaseAgeNpm` | Require a minimum release age for npm packages | +| `schedule:nonOfficeHours` | Run Renovate outside office hours | + +## Key settings + +| Setting | Value | Description | +|---------|-------|-------------| +| `assigneesFromCodeOwners` | `true` | Assign PRs to CODEOWNERS | +| `automergeStrategy` | `squash` | Squash-merge automerged PRs | +| `commitBody` | `Signed-off-by: {{{gitAuthor}}}` | DCO sign-off in commit body | +| `commitMessageAction` | `update` | Use "update" as the commit action verb | +| `commitMessageExtra` | `({{currentVersion}} -> {{newVersion}})` | Show version range in commits | +| `dependencyDashboardLabels` | `["no-stale"]` | Prevent stale-bot from closing the dashboard | +| `dependencyDashboardOSVVulnerabilitySummary` | `unresolved` | Show unresolved OSV vulnerabilities | +| `dependencyDashboardTitle` | `Renovate Dashboard` | Custom dashboard issue title | +| `onboardingConfigFileName` | `.github/renovate.json` | Default onboarding config path | +| `prHourlyLimit` | `5` | Max 5 PRs created per hour | +| `reviewersFromCodeOwners` | `true` | Request reviews from CODEOWNERS | +| `separateMultipleMajor` | `true` | Create separate PRs for each major version bump | + +## Custom managers + +### Dockerfile + +Extracts versions from `ENV` variables and `FROM` lines in Dockerfiles using +[regex manager](https://docs.renovatebot.com/modules/manager/regex/). + +**Patterns matched:** + +```dockerfile +# ENV with inline datasource comment +ENV TOOL_VERSION=1.2.3 # github-releases/owner/repo + +# Standard FROM line +FROM node:20-alpine +``` + +Regex (applied with `matchStringsStrategy: "any"`): + +``` +ENV [A-Z]+_VERSION=(?.*) # (?.*?)/(?.*?)(\&versioning=(?.*))?\s +FROM (?\S*):(?\S*) +``` + +### Makefile + +Tracks tool versions in Makefiles via `# renovate:` comments using +[regex manager](https://docs.renovatebot.com/modules/manager/regex/). + +Files matched: `Makefile`, `*.mk` + +**Pattern matched:** + +```makefile +# renovate: datasource=go depName=github.com/goreleaser/goreleaser/v2 +GORELEASER_VERSION := v2.14.1 +``` + +Regex: + +``` +#\s*renovate:\s*datasource=(?\S+)\s+depName=(?\S+)\n[A-Z_]+\s*:?=\s*(?v?\d+\.\d+\.\d+\S*) +``` + +The `datasource` and `depName` are captured from the comment, and +`currentValue` from the variable assignment. Uses `semver` versioning. + +## Package rules + +### Automerge and labeling + +| Rule | Matches | Effect | +|------|---------|--------| +| Major commit prefix | `matchUpdateTypes: ["major"]` | `chore(deps)!:` prefix, `type/major` label | +| Automerge non-major | `matchUpdateTypes: ["minor", "patch", "digest"]` | Automerge via branch strategy | +| Minor label | `matchUpdateTypes: ["minor"]` | `type/minor` label | +| Patch label | `matchUpdateTypes: ["patch"]` | `type/patch` label | +| Digest label | `matchUpdateTypes: ["digest"]` | `type/digest` label | + +### Datasource labels and commit topics + +| Datasource / Manager | Label | Commit topic | +|-----------------------|-------|--------------| +| `docker` | `renovate/container` | `image {{depName}}` | +| `helm` | `renovate/helm` | `chart {{depName}}` | +| `galaxy`, `galaxy-collection` | `renovate/ansible` | - | +| `terraform-provider` | `renovate/terraform` | - | +| `github-releases`, `github-tags` | `renovate/github-release` | - | +| `github-actions` (manager) | `renovate/github-action` | scope: `actions` | +| `pypi` | `renovate/pip` | - | + +### Dependency groups + +Related packages are grouped into single PRs: + +| Group name | Match criteria | +|------------|----------------| +| devDependencies (non-major) | `matchDepTypes: ["devDependencies"]`, minor/patch only | +| development tools | `matchFileNames: ["Makefile", "**/*.mk"]`, custom.regex manager | +| eslint | Package names matching `/eslint/` | +| illuminate | Package names matching `/illuminate/` | +| phpstan | Package names matching `/phpstan/` or `/larastan/` | +| semantic-release | Package names matching `/semantic-release/` | +| stylelint | Package names matching `/stylelint/` | +| tailwind | Package names matching `/tailwind/` | +| vite | Package names matching `/vite/` | +| vue | Package names matching `/vue/` | + +## Post-update options + +Lock file maintenance after dependency updates: + +| Option | Description | +|--------|-------------| +| `bundlerConservative` | Conservative Bundler updates | +| `composerWithAll` | Run `composer update` with `--with-all-dependencies` | +| `gomodUpdateImportPaths` | Update Go import paths on major updates | +| `npmDedupe` | Run `npm dedupe` after updates | +| `pnpmDedupe` | Run `pnpm dedupe` after updates | +| `yarnDedupeHighest` | Run `yarn dedupe --strategy highest` after updates | + +## Other configuration + +| Setting | Value | Description | +|---------|-------|-------------| +| `digest.enabled` | `false` | Digest-only updates disabled | +| `git-submodules.enabled` | `true` | Track git submodule updates | +| `pre-commit.enabled` | `true` | Update pre-commit hook versions | +| `ignorePaths` | `**/*.sops.*`, `**/.archive/**`, `**/testdata/**` | Skip encrypted, archived, and test fixture files | + +## Validation + +Run the pre-commit hooks to validate `default.json`: + +```sh +pre-commit run --all-files +``` + +This executes: + +- **`pretty-format-json`** -- ensures consistent JSON formatting +- **`renovate-config-validator --strict`** -- Renovate's own config validation +- **`check-renovate`** -- JSON Schema validation against `renovate-global-schema.json` +- Standard checks (trailing whitespace, end-of-file fixer, etc.) + ## License [MIT](LICENSE) diff --git a/default.json b/default.json index 5b71c57..656f539 100644 --- a/default.json +++ b/default.json @@ -1,13 +1,10 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "$schema": "https://docs.renovatebot.com/renovate-global-schema.json", "assigneesFromCodeOwners": true, "automergeStrategy": "squash", "commitBody": "Signed-off-by: {{{gitAuthor}}}", "commitMessageAction": "update", "commitMessageExtra": " ({{currentVersion}} → {{newVersion}})", - "commitMessageSuffix": "", - "commitMessageTopic": "{{depName}}", - "configMigration": true, "customManagers": [ { "customType": "regex", @@ -24,6 +21,21 @@ "FROM (?\\S*):(?\\S*)" ], "matchStringsStrategy": "any" + }, + { + "customType": "regex", + "description": [ + "Track tool versions in Makefiles via '# renovate: datasource=X depName=Y' comments. ", + "See https://docs.renovatebot.com/configuration-options/#matchstringsstrategy" + ], + "managerFilePatterns": [ + "^Makefile$", + ".*\\.mk$" + ], + "matchStrings": [ + "#\\s*renovate:\\s*datasource=(?\\S+)\\s+depName=(?\\S+)\\n[A-Z_]+\\s*:?=\\s*(?v?\\d+\\.\\d+\\.\\d+\\S*)" + ], + "versioningTemplate": "semver" } ], "dependencyDashboardLabels": [ @@ -39,17 +51,13 @@ "config:recommended", ":enableVulnerabilityAlerts", ":labels(dependencies)", - ":maintainLockFilesWeekly", ":preserveSemverRanges", ":semanticCommits", ":timezone(Europe/Helsinki)", "docker:enableMajor", - "group:recommended", "helpers:pinGitHubActionDigests", - "npm:unpublishSafe", - "replacements:all", - "schedule:nonOfficeHours", - "workarounds:all" + "security:minimumReleaseAgeNpm", + "schedule:nonOfficeHours" ], "git-submodules": { "enabled": true, @@ -63,18 +71,13 @@ "**/.archive/**", "**/testdata/**" ], - "lockFileMaintenance": { - "enabled": true, - "extends": [ - "group:all" - ] - }, "onboardingConfigFileName": ".github/renovate.json", - "osvVulnerabilityAlerts": true, "packageRules": [ { "commitMessagePrefix": "chore(deps)!: ", - "commitMessageTopic": "{{depName}}", + "labels": [ + "type/major" + ], "matchUpdateTypes": [ "major" ] @@ -100,14 +103,6 @@ "docker" ] }, - { - "labels": [ - "type/major" - ], - "matchUpdateTypes": [ - "major" - ] - }, { "labels": [ "type/minor" @@ -180,7 +175,8 @@ ], "matchManagers": [ "github-actions" - ] + ], + "semanticCommitScope": "actions" }, { "addLabels": [ @@ -200,24 +196,69 @@ "minor" ] }, + { + "groupName": "development tools", + "matchFileNames": [ + "Makefile", + "**/*.mk" + ], + "matchManagers": [ + "custom.regex" + ] + }, { "groupName": "eslint", "matchPackageNames": [ "/eslint/" ] }, + { + "groupName": "illuminate", + "matchPackageNames": [ + "/illuminate/" + ] + }, { "groupName": "phpstan", "matchPackageNames": [ "/phpstan/", "/larastan/" ] + }, + { + "groupName": "semantic-release", + "matchPackageNames": [ + "/semantic-release/" + ] + }, + { + "groupName": "stylelint", + "matchPackageNames": [ + "/stylelint/" + ] + }, + { + "groupName": "tailwind", + "matchPackageNames": [ + "/tailwind/" + ] + }, + { + "groupName": "vite", + "matchPackageNames": [ + "/vite/" + ] + }, + { + "groupName": "vue", + "matchPackageNames": [ + "/vue/" + ] } ], "postUpdateOptions": [ "bundlerConservative", "composerWithAll", - "dotnetWorkloadRestore", "gomodUpdateImportPaths", "npmDedupe", "pnpmDedupe", @@ -227,7 +268,6 @@ "pre-commit": { "enabled": true }, - "pruneStaleBranches": true, "renovate-config-presets": { "managerFilePatterns": [ "renovate.json", @@ -243,13 +283,5 @@ ] }, "reviewersFromCodeOwners": true, - "semanticCommitScope": "deps", - "semanticCommitType": "chore", - "semanticCommits": "enabled", - "separateMajorMinor": true, - "separateMinorPatch": false, - "separateMultipleMajor": true, - "vulnerabilityAlerts": { - "enabled": true - } + "separateMultipleMajor": true }