From c88ace3f9921b9dc1a1ecfb2c8955115c71e0356 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 17:59:30 +0200 Subject: [PATCH 01/10] ci: switch renovate config to json5 Renovate reads renovate.json5 with the same precedence as renovate.json. JSON5 allows comments, which the following commits use to record why each setting is there. Signed-off-by: Roberto Giovanardi --- renovate.json | 5 ----- renovate.json5 | 10 ++++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 renovate.json create mode 100644 renovate.json5 diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 2f329a5..0000000 --- a/renovate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:recommended"], - "reviewers": ["larsewi", "olehermanse"] -} diff --git a/renovate.json5 b/renovate.json5 new file mode 100644 index 0000000..ebf1c58 --- /dev/null +++ b/renovate.json5 @@ -0,0 +1,10 @@ +// Repository-level Renovate configuration. +// Global (self-hosted) settings are in .github/renovate-config.js, +// the runner workflow is .github/workflows/renovate.yml. +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + + // There is no CODEOWNERS file in this repo, so reviewers are named here. + "reviewers": ["larsewi", "olehermanse"] +} From 7811d6c730480be335b24837f5cc4e5b70820794 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:01:33 +0200 Subject: [PATCH 02/10] ci: bump python dependency floors instead of ignoring them Every dependency in pyproject.toml is a ">=" floor. Any newer release already satisfies it, so the default rangeStrategy ("auto", which resolves to "replace" for pep621) looks the new version up and then correctly decides there is nothing to replace. Result: Renovate has never opened a single python dependency PR. PR #221 bumped cf-remote and cfbs by hand. rangeStrategy "bump" raises the floor and updates uv.lock. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index ebf1c58..34c6be0 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -1,10 +1,24 @@ -// Repository-level Renovate configuration. // Global (self-hosted) settings are in .github/renovate-config.js, // the runner workflow is .github/workflows/renovate.yml. { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:recommended"], + "reviewers": ["larsewi", "olehermanse"], - // There is no CODEOWNERS file in this repo, so reviewers are named here. - "reviewers": ["larsewi", "olehermanse"] + "packageRules": [ + // pyproject.toml uses ">=" floors, which newer releases already satisfy, + // so the default rangeStrategy proposes nothing. "bump" raises the floor. + { + "matchManagers": ["pep621"], + "rangeStrategy": "bump" + }, + + // Support floor, not a dependency. "bump" would raise it to ">=3.14.7" + // and drop 3.10 - 3.13, which make-check.yml still tests. + { + "matchManagers": ["pep621"], + "matchDepTypes": ["requires-python"], + "enabled": false + } + ] } From 4e3881fbd1929b85d920abe4161dda81d4975d12 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:02:41 +0200 Subject: [PATCH 03/10] fix: update transitive dependencies in uv.lock lockFileMaintenance is off by default, so packages that only appear in uv.lock have not been updated since dependabot was removed. That config had package-ecosystem "uv", which is where the idna, urllib3 and requests bumps came from. uv.lock is what actually gets installed: both coverage.yml and pypi-publish.yml run "uv lock --check". Runs weekly rather than on every daily run, since it regenerates the whole lock file rather than bumping one package. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index 34c6be0..3eebdd5 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -5,6 +5,13 @@ "extends": ["config:recommended"], "reviewers": ["larsewi", "olehermanse"], + // Transitive deps only exist in uv.lock, so nothing in pyproject.toml + // reaches them. Replaces dependabot's "uv" ecosystem. + "lockFileMaintenance": { + "enabled": true, + "schedule": ["before 5am on monday"] + }, + "packageRules": [ // pyproject.toml uses ">=" floors, which newer releases already satisfy, // so the default rangeStrategy proposes nothing. "bump" raises the floor. From a3c6b94d4beebe8152031fc67af93147fec51bb6 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:03:47 +0200 Subject: [PATCH 04/10] ci: open security dependency PRs immediately Security fixes bypass the normal flow and get a "security" label so they are visible in the PR list without opening the dependency dashboard. osvVulnerabilityAlerts is enabled alongside GitHub's own alerts: this is a self-hosted run using a PAT, and OSV lookups do not depend on that token being able to read the repository's vulnerability alerts API. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index 3eebdd5..86bf977 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -12,6 +12,15 @@ "schedule": ["before 5am on monday"] }, + // osvVulnerabilityAlerts does not depend on the PAT being able to read + // GitHub's own alerts API. + "vulnerabilityAlerts": { + "enabled": true, + "schedule": ["at any time"], + "labels": ["security"] + }, + "osvVulnerabilityAlerts": true, + "packageRules": [ // pyproject.toml uses ">=" floors, which newer releases already satisfy, // so the default rangeStrategy proposes nothing. "bump" raises the floor. From c6c4e31749c386cd53329fb4a1b599b36e1ade09 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:04:57 +0200 Subject: [PATCH 05/10] ci: adjust renovate PR limits and rebase policy renovate.yml is on a daily cron, so the default prHourlyLimit of 2 acts as a daily limit of 2: a backlog of six grouped PRs would take three days to appear. Set it to 0 (unlimited) and let prConcurrentLimit cap the review queue instead. rebaseWhen "conflicted" replaces the default "auto", which rebases every open Renovate PR whenever main moves and restarts a make-check matrix run per PR. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index 86bf977..abdc16d 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -5,6 +5,14 @@ "extends": ["config:recommended"], "reviewers": ["larsewi", "olehermanse"], + // Rebasing on every push to main would restart a pipeline per open PR. + "rebaseWhen": "conflicted", + + // The workflow runs once a day, so an hourly limit would act as a daily + // limit. Let the concurrent limit do the throttling. + "prHourlyLimit": 0, + "prConcurrentLimit": 5, + // Transitive deps only exist in uv.lock, so nothing in pyproject.toml // reaches them. Replaces dependabot's "uv" ecosystem. "lockFileMaintenance": { From 9aaad1f33a9b8dae65991551b5ce1b4733fe34b5 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:05:48 +0200 Subject: [PATCH 06/10] chore: pin renovate to the main branch Renovate does not read maintenance branches out of git, they have to be listed. No effect today since main is the default branch, but it means a maintenance branch cut later gets dependency PRs by adding one line rather than by someone noticing it never got any. Trade-off: renaming the default branch now requires updating this list. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index abdc16d..2333b79 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -5,6 +5,10 @@ "extends": ["config:recommended"], "reviewers": ["larsewi", "olehermanse"], + // Renovate does not infer maintenance branches from git, they have to be + // named here. + "baseBranchPatterns": ["main"], + // Rebasing on every push to main would restart a pipeline per open PR. "rebaseWhen": "conflicted", From 782fd8d32361730ebbce126326ee434183a3263e Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:07:05 +0200 Subject: [PATCH 07/10] ci: group python dependency updates Without grouping, rangeStrategy "bump" opens one PR per package: nine on the current tree. Three groups instead: cfengine-deps cf-remote, cfbs, tree-sitter-cfengine python-deps third-party runtime and build-system deps python-dev-deps the dev dependency-group CFEngine's own packages are split out because bumping them is a product decision, not a routine third-party bump. Their rule sits after the python-dependencies rule since packageRules are last-match-wins. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index 2333b79..288ea48 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -41,6 +41,29 @@ "rangeStrategy": "bump" }, + { + "matchManagers": ["pep621"], + "matchDepTypes": ["project.dependencies", "build-system.requires"], + "groupName": "python-dependencies", + "groupSlug": "python-deps" + }, + { + "matchManagers": ["pep621"], + "matchDepTypes": ["dependency-groups"], + "groupName": "python-dev-dependencies", + "groupSlug": "python-dev-deps" + }, + + // Bumping CFEngine's own packages is a product decision. Must stay after + // the python-dependencies rule above: packageRules are last-match-wins. + { + "matchManagers": ["pep621"], + "matchDepTypes": ["project.dependencies"], + "matchPackageNames": ["cf-remote", "cfbs", "tree-sitter-cfengine"], + "groupName": "cfengine-dependencies", + "groupSlug": "cfengine-deps" + }, + // Support floor, not a dependency. "bump" would raise it to ">=3.14.7" // and drop 3.10 - 3.13, which make-check.yml still tests. { From c1e3707a7962c4b8826450803c3ba8eb9922fe09 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:08:43 +0200 Subject: [PATCH 08/10] ci: group non-major github actions updates Git history shows a steady stream of one-action-per-PR bumps: patch and digest updates into a single PR. Majors stay separate, so an actions/download-artifact v8 -> v9 style change still gets its own review. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index 288ea48..1eb1252 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -64,6 +64,14 @@ "groupSlug": "cfengine-deps" }, + // Majors stay separate so they get a real review. + { + "matchManagers": ["github-actions"], + "matchUpdateTypes": ["minor", "patch", "digest"], + "groupName": "github-actions", + "groupSlug": "github-actions" + }, + // Support floor, not a dependency. "bump" would raise it to ">=3.14.7" // and drop 3.10 - 3.13, which make-check.yml still tests. { From 448d0fc82fcae658d33202e82dbbc5bc00c6be96 Mon Sep 17 00:00:00 2001 From: Roberto Giovanardi Date: Wed, 26 Aug 2026 18:13:32 +0200 Subject: [PATCH 09/10] ci: group python version bumps into one PR The python version is pinned in six places: .python-version, requires-python, the make-check matrix, two setup-python steps, and the classifiers. Renovate only reaches .python-version and the setup-python steps, so left ungrouped a 3.15 release opens three PRs that each leave the repo half-migrated. Signed-off-by: Roberto Giovanardi --- renovate.json5 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/renovate.json5 b/renovate.json5 index 1eb1252..7bfe7c0 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -72,6 +72,14 @@ "groupSlug": "github-actions" }, + // The python version is also pinned in the make-check matrix and in the + // classifiers, which Renovate cannot reach. One PR, not three. + { + "matchDepNames": ["python"], + "groupName": "python-version", + "groupSlug": "python-version" + }, + // Support floor, not a dependency. "bump" would raise it to ">=3.14.7" // and drop 3.10 - 3.13, which make-check.yml still tests. { From d9c3fa3595920cbf0477a3292827ed48214b0468 Mon Sep 17 00:00:00 2001 From: Ole Herman Schumacher Elgesem Date: Wed, 26 Aug 2026 19:06:34 +0200 Subject: [PATCH 10/10] renovate.json5: Reformatted with prettier / CFEngine CLI Signed-off-by: Ole Herman Schumacher Elgesem --- renovate.json5 | 86 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 7bfe7c0..70a2b40 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -1,91 +1,91 @@ // Global (self-hosted) settings are in .github/renovate-config.js, // the runner workflow is .github/workflows/renovate.yml. { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:recommended"], - "reviewers": ["larsewi", "olehermanse"], + $schema: "https://docs.renovatebot.com/renovate-schema.json", + extends: ["config:recommended"], + reviewers: ["larsewi", "olehermanse"], // Renovate does not infer maintenance branches from git, they have to be // named here. - "baseBranchPatterns": ["main"], + baseBranchPatterns: ["main"], // Rebasing on every push to main would restart a pipeline per open PR. - "rebaseWhen": "conflicted", + rebaseWhen: "conflicted", // The workflow runs once a day, so an hourly limit would act as a daily // limit. Let the concurrent limit do the throttling. - "prHourlyLimit": 0, - "prConcurrentLimit": 5, + prHourlyLimit: 0, + prConcurrentLimit: 5, // Transitive deps only exist in uv.lock, so nothing in pyproject.toml // reaches them. Replaces dependabot's "uv" ecosystem. - "lockFileMaintenance": { - "enabled": true, - "schedule": ["before 5am on monday"] + lockFileMaintenance: { + enabled: true, + schedule: ["before 5am on monday"], }, // osvVulnerabilityAlerts does not depend on the PAT being able to read // GitHub's own alerts API. - "vulnerabilityAlerts": { - "enabled": true, - "schedule": ["at any time"], - "labels": ["security"] + vulnerabilityAlerts: { + enabled: true, + schedule: ["at any time"], + labels: ["security"], }, - "osvVulnerabilityAlerts": true, + osvVulnerabilityAlerts: true, - "packageRules": [ + packageRules: [ // pyproject.toml uses ">=" floors, which newer releases already satisfy, // so the default rangeStrategy proposes nothing. "bump" raises the floor. { - "matchManagers": ["pep621"], - "rangeStrategy": "bump" + matchManagers: ["pep621"], + rangeStrategy: "bump", }, { - "matchManagers": ["pep621"], - "matchDepTypes": ["project.dependencies", "build-system.requires"], - "groupName": "python-dependencies", - "groupSlug": "python-deps" + matchManagers: ["pep621"], + matchDepTypes: ["project.dependencies", "build-system.requires"], + groupName: "python-dependencies", + groupSlug: "python-deps", }, { - "matchManagers": ["pep621"], - "matchDepTypes": ["dependency-groups"], - "groupName": "python-dev-dependencies", - "groupSlug": "python-dev-deps" + matchManagers: ["pep621"], + matchDepTypes: ["dependency-groups"], + groupName: "python-dev-dependencies", + groupSlug: "python-dev-deps", }, // Bumping CFEngine's own packages is a product decision. Must stay after // the python-dependencies rule above: packageRules are last-match-wins. { - "matchManagers": ["pep621"], - "matchDepTypes": ["project.dependencies"], - "matchPackageNames": ["cf-remote", "cfbs", "tree-sitter-cfengine"], - "groupName": "cfengine-dependencies", - "groupSlug": "cfengine-deps" + matchManagers: ["pep621"], + matchDepTypes: ["project.dependencies"], + matchPackageNames: ["cf-remote", "cfbs", "tree-sitter-cfengine"], + groupName: "cfengine-dependencies", + groupSlug: "cfengine-deps", }, // Majors stay separate so they get a real review. { - "matchManagers": ["github-actions"], - "matchUpdateTypes": ["minor", "patch", "digest"], - "groupName": "github-actions", - "groupSlug": "github-actions" + matchManagers: ["github-actions"], + matchUpdateTypes: ["minor", "patch", "digest"], + groupName: "github-actions", + groupSlug: "github-actions", }, // The python version is also pinned in the make-check matrix and in the // classifiers, which Renovate cannot reach. One PR, not three. { - "matchDepNames": ["python"], - "groupName": "python-version", - "groupSlug": "python-version" + matchDepNames: ["python"], + groupName: "python-version", + groupSlug: "python-version", }, // Support floor, not a dependency. "bump" would raise it to ">=3.14.7" // and drop 3.10 - 3.13, which make-check.yml still tests. { - "matchManagers": ["pep621"], - "matchDepTypes": ["requires-python"], - "enabled": false - } - ] + matchManagers: ["pep621"], + matchDepTypes: ["requires-python"], + enabled: false, + }, + ], }