From fce7ad8b92ae0425bf5431f8be59d4a8c5053cd2 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 26 Aug 2026 20:44:04 -0400 Subject: [PATCH 01/15] Switch dependency updates from Dependabot to Renovate Commits the renovate.json5 that supersedes Renovate's onboarding proposal (#485), aligned with the docsy repo's config: 7-day minimumReleaseAge, npm + github-actions managers only, hugo-extended and theme-managed assets excluded (same carve-outs dependabot.yml held). Repo-level security alerts are unaffected: grouped security PRs never depended on dependabot.yml. Config validated with renovate-config-validator --strict (44.35.2). --- .github/dependabot.yml | 32 -------------------------------- renovate.json5 | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 32 deletions(-) delete mode 100644 .github/dependabot.yml create mode 100644 renovate.json5 diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 2264c39b03..0000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: 2 -updates: - - package-ecosystem: npm - directory: '/' - schedule: - interval: daily - time: '20:00' - open-pull-requests-limit: 10 - # Let new releases age before they enter update PRs; security updates - # bypass the cooldown. - cooldown: - default-days: 7 - ignore: - # Coupled to the version-pinned allowScripts approval; updated manually - # via update:hugo + approve:hugo (see CONTRIBUTING.md). Scoped so - # security updates still open PRs. - - dependency-name: hugo-extended - update-types: - - 'version-update:semver-major' - - 'version-update:semver-minor' - - 'version-update:semver-patch' - # Theme-managed (packages/hugoautogen is regenerated from the Docsy - # theme, reverting any bump): updates route through the theme. - - dependency-name: bootstrap - - dependency-name: '@fortawesome/fontawesome-free' - - package-ecosystem: github-actions - directory: '/' - schedule: - interval: daily - time: '20:00' - cooldown: - default-days: 7 diff --git a/renovate.json5 b/renovate.json5 new file mode 100644 index 0000000000..15d4b60015 --- /dev/null +++ b/renovate.json5 @@ -0,0 +1,42 @@ +{ + $schema: 'https://docs.renovatebot.com/renovate-schema.json', + extends: ['config:best-practices'], + // config:best-practices pulls in security:minimumReleaseAgeNpm: its 3-day npm + // rule would override the global minimumReleaseAge below. Its age exemptions + // for update types without release timestamps (pin, replacement, rollback, + // among others) are deliberately not restored: such PRs never satisfy the age + // check and need manual age validation at review, as they already do for + // every other datasource. + // + // IMPORTANT: an upstream rename of the preset silently re-admits it. + ignorePresets: ['security:minimumReleaseAgeNpm'], + timezone: 'America/Toronto', + schedule: ['before 6am on monday'], + labels: ['dependencies'], + // Deliberately out: gomod (the Docsy theme pin; updated via + // `npm run update:docsy:mod`, release-driven) and docker (best-effort setup; + // its Hugo and Dart Sass pins are bumped manually alongside hugo-extended + // and sass-embedded, see CONTRIBUTING.md). + enabledManagers: ['npm', 'github-actions'], + // Deliberately datasource-wide: applies to every datasource this config may + // grow to manage. Security updates keep Renovate's documented bypass of the + // age check. + minimumReleaseAge: '7 days', + internalChecksFilter: 'strict', + packageRules: [ + { + // hugo-extended is intentionally pinned, coupled to the version-pinned + // allowScripts approval; updated manually via `npm run update:hugo` + + // `npm run approve:hugo` (see CONTRIBUTING.md). Security fixes still + // arrive: repo-level Dependabot alerts are config-file-independent. + matchPackageNames: ['hugo-extended'], + enabled: false, + }, + { + // Theme-managed (packages/hugoautogen is regenerated from the Docsy + // theme, reverting any bump): updates route through the theme. + matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], + enabled: false, + }, + ], +} From 2dc923207422b820d813c051d30d2613d34cfb78 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 26 Aug 2026 21:11:20 -0400 Subject: [PATCH 02/15] renovate.json5: adversarial round-1 fixes - disable lockFileMaintenance (via config:best-practices): a weekly full lock re-resolve pulls in-range latests UNGATED by minimumReleaseAge - hugo-extended comment: enabled:false silences Renovate security bumps too; name the actual net (repo-level Dependabot security updates + fail-closed installs), not 'alerts' - age-exemptions comment: drop the claims about PR-time review that internalChecksFilter:strict invalidates --- renovate.json5 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 15d4b60015..37add3efb5 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -4,12 +4,16 @@ // config:best-practices pulls in security:minimumReleaseAgeNpm: its 3-day npm // rule would override the global minimumReleaseAge below. Its age exemptions // for update types without release timestamps (pin, replacement, rollback, - // among others) are deliberately not restored: such PRs never satisfy the age - // check and need manual age validation at review, as they already do for - // every other datasource. + // among others) are deliberately not restored: validate the age of such + // updates manually when they surface. // // IMPORTANT: an upstream rename of the preset silently re-admits it. ignorePresets: ['security:minimumReleaseAgeNpm'], + // Also from config:best-practices (:maintainLockFilesWeekly), and unwanted + // here: a full lock re-resolve pulls the latest in-range releases into the + // lock UNGATED by minimumReleaseAge, defeating the cooldown. In-range + // freshness arrives cooldown-gated through regular update PRs instead. + lockFileMaintenance: { enabled: false }, timezone: 'America/Toronto', schedule: ['before 6am on monday'], labels: ['dependencies'], @@ -27,8 +31,10 @@ { // hugo-extended is intentionally pinned, coupled to the version-pinned // allowScripts approval; updated manually via `npm run update:hugo` + - // `npm run approve:hugo` (see CONTRIBUTING.md). Security fixes still - // arrive: repo-level Dependabot alerts are config-file-independent. + // `npm run approve:hugo` (see CONTRIBUTING.md). This silences Renovate + // for it entirely, security bumps included; security coverage stays with + // GitHub's repo-level Dependabot security updates (independent of any + // dependabot.yml), and an unapproved bump fails installs closed. matchPackageNames: ['hugo-extended'], enabled: false, }, From 8945a8b950889d77447bbf4bf9b61592a3454ef2 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 26 Aug 2026 21:29:42 -0400 Subject: [PATCH 03/15] renovate.json5: adversarial round-2 fixes - vulnerabilityAlerts off: Dependabot security updates own vuln PRs; Renovate's are immediate, unscheduled, age-exempt duplicates - configMigration off: migration PRs may rewrite JSON5 to JSON and drop the comments this file keeps its policy in - schedule widens to all Monday: a narrow window can miss the hosted scheduler's daily visit on a not-yet-activated repo, never bootstrapping - lockFileMaintenance comment: correct rationale (lock churn + the ETARGET age-gate fallback; v44 gates the normal path with --before) - bootstrap/FA rule comment: names the Dependabot-security-PR behavior the retired unscoped ignore used to suppress - age-exemptions comment: pending-on-dashboard, not PR-time review --- renovate.json5 | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 37add3efb5..e22cb6cde0 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -4,18 +4,34 @@ // config:best-practices pulls in security:minimumReleaseAgeNpm: its 3-day npm // rule would override the global minimumReleaseAge below. Its age exemptions // for update types without release timestamps (pin, replacement, rollback, - // among others) are deliberately not restored: validate the age of such - // updates manually when they surface. + // among others) are deliberately not restored: strict internal checks hold + // such updates as pending on the Dependency Dashboard (no PR); validate age + // manually before force-creating one from there. // // IMPORTANT: an upstream rename of the preset silently re-admits it. ignorePresets: ['security:minimumReleaseAgeNpm'], // Also from config:best-practices (:maintainLockFilesWeekly), and unwanted - // here: a full lock re-resolve pulls the latest in-range releases into the - // lock UNGATED by minimumReleaseAge, defeating the cooldown. In-range - // freshness arrives cooldown-gated through regular update PRs instead. + // here: weekly wholesale re-resolves churn a committed, reviewed lockfile + // this repo treats as an artifact, and the npm ETARGET fallback (a retry + // without --before when the lock already holds a too-new version) can slip + // past the age gate. Transitive security fixes route through Dependabot + // security updates instead. lockFileMaintenance: { enabled: false }, + // GitHub's repo-level Dependabot security updates own vulnerability PRs + // (they operate without any dependabot.yml); left on, Renovate would + // duplicate them -- its alert-driven PRs are immediate, unscheduled, and + // exempt from minimumReleaseAge. + vulnerabilityAlerts: { enabled: false }, + // Config-migration PRs may rewrite JSON5 to JSON, dropping comments -- and + // this file's policy lives in its comments. Migrate manually on Renovate + // majors instead. + configMigration: false, timezone: 'America/Toronto', - schedule: ['before 6am on monday'], + // Full-day window, not docsy root's 'before 6am on monday': on Mend's hosted + // scheduler, a not-yet-activated repo (no merged Renovate PR) is visited + // daily at an hour we don't control; a narrow window can miss every visit + // and never bootstrap. Tightening back is a post-activation option. + schedule: ['on monday'], labels: ['dependencies'], // Deliberately out: gomod (the Docsy theme pin; updated via // `npm run update:docsy:mod`, release-driven) and docker (best-effort setup; @@ -40,7 +56,11 @@ }, { // Theme-managed (packages/hugoautogen is regenerated from the Docsy - // theme, reverting any bump): updates route through the theme. + // theme, reverting any bump): updates route through the theme. Unlike + // the retired dependabot.yml ignore, this doesn't reach Dependabot + // security updates: an alert-driven PR may still bump these directly -- + // close it and route the fix through a theme update (the is:clean gate + // flags the manifest drift). matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], enabled: false, }, From c7be24021c40411e500ff0af26cfadf50dbb418d Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 26 Aug 2026 21:33:01 -0400 Subject: [PATCH 04/15] renovate.json5: dashes + comments review pass Colon/semicolon constructs replace the spaced-dash asides; drop the stale claim that security updates bypass the age gate (Renovate raises no security PRs here since vulnerabilityAlerts went off). --- renovate.json5 | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index e22cb6cde0..fec442114a 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -11,20 +11,19 @@ // IMPORTANT: an upstream rename of the preset silently re-admits it. ignorePresets: ['security:minimumReleaseAgeNpm'], // Also from config:best-practices (:maintainLockFilesWeekly), and unwanted - // here: weekly wholesale re-resolves churn a committed, reviewed lockfile - // this repo treats as an artifact, and the npm ETARGET fallback (a retry - // without --before when the lock already holds a too-new version) can slip - // past the age gate. Transitive security fixes route through Dependabot - // security updates instead. + // here: weekly wholesale re-resolves churn a committed, reviewed lockfile, + // and the npm ETARGET fallback (a retry without --before when the lock + // already holds a too-new version) can slip past the age gate. Transitive + // security fixes route through Dependabot security updates instead. lockFileMaintenance: { enabled: false }, // GitHub's repo-level Dependabot security updates own vulnerability PRs // (they operate without any dependabot.yml); left on, Renovate would - // duplicate them -- its alert-driven PRs are immediate, unscheduled, and + // duplicate them: its alert-driven PRs are immediate, unscheduled, and // exempt from minimumReleaseAge. vulnerabilityAlerts: { enabled: false }, - // Config-migration PRs may rewrite JSON5 to JSON, dropping comments -- and - // this file's policy lives in its comments. Migrate manually on Renovate - // majors instead. + // Config-migration PRs may rewrite JSON5 to JSON, dropping comments; this + // file's policy lives in its comments. Migrate manually on Renovate majors + // instead. configMigration: false, timezone: 'America/Toronto', // Full-day window, not docsy root's 'before 6am on monday': on Mend's hosted @@ -39,8 +38,7 @@ // and sass-embedded, see CONTRIBUTING.md). enabledManagers: ['npm', 'github-actions'], // Deliberately datasource-wide: applies to every datasource this config may - // grow to manage. Security updates keep Renovate's documented bypass of the - // age check. + // grow to manage. minimumReleaseAge: '7 days', internalChecksFilter: 'strict', packageRules: [ @@ -48,9 +46,9 @@ // hugo-extended is intentionally pinned, coupled to the version-pinned // allowScripts approval; updated manually via `npm run update:hugo` + // `npm run approve:hugo` (see CONTRIBUTING.md). This silences Renovate - // for it entirely, security bumps included; security coverage stays with - // GitHub's repo-level Dependabot security updates (independent of any - // dependabot.yml), and an unapproved bump fails installs closed. + // for it entirely, security bumps included; the Dependabot security + // updates noted above cover it, and an unapproved bump fails installs + // closed. matchPackageNames: ['hugo-extended'], enabled: false, }, @@ -58,7 +56,7 @@ // Theme-managed (packages/hugoautogen is regenerated from the Docsy // theme, reverting any bump): updates route through the theme. Unlike // the retired dependabot.yml ignore, this doesn't reach Dependabot - // security updates: an alert-driven PR may still bump these directly -- + // security updates: an alert-driven PR may still bump these directly; // close it and route the fix through a theme update (the is:clean gate // flags the manifest drift). matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], From ab38b84be7c1c4f01edea5f067ce662597087b58 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 07:28:23 -0400 Subject: [PATCH 05/15] renovate.json5: DRY-lean trim; align hugo-extended rule with docsy#2747 - comments keep only what Renovate config can't say: CONTRIBUTING's maintainer notes own the update flows (linked, not restated); drop the internalChecksFilter override (documented default) and the minimumReleaseAge comment (spoke only of hypothetical growth) - hugo-extended rule scoped to matchUpdateTypes major/minor/patch (the docsy#2747 shape): the manual policy covers version bumps, not the security lane --- renovate.json5 | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index fec442114a..925b8457b4 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -3,10 +3,9 @@ extends: ['config:best-practices'], // config:best-practices pulls in security:minimumReleaseAgeNpm: its 3-day npm // rule would override the global minimumReleaseAge below. Its age exemptions - // for update types without release timestamps (pin, replacement, rollback, - // among others) are deliberately not restored: strict internal checks hold - // such updates as pending on the Dependency Dashboard (no PR); validate age - // manually before force-creating one from there. + // for timestamp-less update types are deliberately not restored: those + // updates sit pending on the Dependency Dashboard; age-check manually before + // force-creating a PR. // // IMPORTANT: an upstream rename of the preset silently re-admits it. ignorePresets: ['security:minimumReleaseAgeNpm'], @@ -18,8 +17,7 @@ lockFileMaintenance: { enabled: false }, // GitHub's repo-level Dependabot security updates own vulnerability PRs // (they operate without any dependabot.yml); left on, Renovate would - // duplicate them: its alert-driven PRs are immediate, unscheduled, and - // exempt from minimumReleaseAge. + // duplicate them: its alert-driven PRs are schedule- and age-exempt. vulnerabilityAlerts: { enabled: false }, // Config-migration PRs may rewrite JSON5 to JSON, dropping comments; this // file's policy lives in its comments. Migrate manually on Renovate majors @@ -29,36 +27,27 @@ // Full-day window, not docsy root's 'before 6am on monday': on Mend's hosted // scheduler, a not-yet-activated repo (no merged Renovate PR) is visited // daily at an hour we don't control; a narrow window can miss every visit - // and never bootstrap. Tightening back is a post-activation option. + // and never bootstrap. schedule: ['on monday'], labels: ['dependencies'], - // Deliberately out: gomod (the Docsy theme pin; updated via - // `npm run update:docsy:mod`, release-driven) and docker (best-effort setup; - // its Hugo and Dart Sass pins are bumped manually alongside hugo-extended - // and sass-embedded, see CONTRIBUTING.md). + // Deliberately out: gomod (the Docsy theme pin, release-driven) and docker + // (best-effort setup; its pins are bumped manually, see CONTRIBUTING.md). enabledManagers: ['npm', 'github-actions'], - // Deliberately datasource-wide: applies to every datasource this config may - // grow to manage. minimumReleaseAge: '7 days', - internalChecksFilter: 'strict', packageRules: [ { - // hugo-extended is intentionally pinned, coupled to the version-pinned - // allowScripts approval; updated manually via `npm run update:hugo` + - // `npm run approve:hugo` (see CONTRIBUTING.md). This silences Renovate - // for it entirely, security bumps included; the Dependabot security - // updates noted above cover it, and an unapproved bump fails installs - // closed. + // hugo-extended version bumps are manual; flow + security-update paths: + // CONTRIBUTING.md's maintainer notes. matchPackageNames: ['hugo-extended'], + matchUpdateTypes: ['major', 'minor', 'patch'], enabled: false, }, { // Theme-managed (packages/hugoautogen is regenerated from the Docsy - // theme, reverting any bump): updates route through the theme. Unlike - // the retired dependabot.yml ignore, this doesn't reach Dependabot - // security updates: an alert-driven PR may still bump these directly; - // close it and route the fix through a theme update (the is:clean gate - // flags the manifest drift). + // theme, reverting any bump): updates route through the theme. This + // doesn't constrain Dependabot security updates: an alert-driven PR may + // still bump these directly; close it and route the fix through a theme + // update. matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], enabled: false, }, From f6ec7f5721ebf3bf7fc454b2d5ddf4b04f6abee5 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 07:49:08 -0400 Subject: [PATCH 06/15] renovate.json5: leave vulnerabilityAlerts at its default (on) Owner call: an in-config, platform-independent advisory path (repo-level Dependabot security-update settings are admin-side and org-specific); the rare duplicate security PR is accepted. lockFileMaintenance comment now names the alert-driven pair as the transitive-fix path. --- renovate.json5 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 925b8457b4..5157db1b4b 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -13,12 +13,10 @@ // here: weekly wholesale re-resolves churn a committed, reviewed lockfile, // and the npm ETARGET fallback (a retry without --before when the lock // already holds a too-new version) can slip past the age gate. Transitive - // security fixes route through Dependabot security updates instead. + // security fixes arrive alert-driven instead: Renovate's vulnerabilityAlerts + // (left at its default, on) plus GitHub's repo-level Dependabot security + // updates; the rare duplicate PR is accepted. lockFileMaintenance: { enabled: false }, - // GitHub's repo-level Dependabot security updates own vulnerability PRs - // (they operate without any dependabot.yml); left on, Renovate would - // duplicate them: its alert-driven PRs are schedule- and age-exempt. - vulnerabilityAlerts: { enabled: false }, // Config-migration PRs may rewrite JSON5 to JSON, dropping comments; this // file's policy lives in its comments. Migrate manually on Renovate majors // instead. From 4be731ac6c8b9e916a83ca34dc5a4009bba37b22 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 07:59:51 -0400 Subject: [PATCH 07/15] renovate.json5: schedule on sunday; trim two comments Full-day Sunday window (PRs batch for Monday review); drop the unverifiable hosted-scheduler theory and the misplaced bot catalog in the lockFileMaintenance tail. --- renovate.json5 | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 5157db1b4b..8fe756c522 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -13,20 +13,14 @@ // here: weekly wholesale re-resolves churn a committed, reviewed lockfile, // and the npm ETARGET fallback (a retry without --before when the lock // already holds a too-new version) can slip past the age gate. Transitive - // security fixes arrive alert-driven instead: Renovate's vulnerabilityAlerts - // (left at its default, on) plus GitHub's repo-level Dependabot security - // updates; the rare duplicate PR is accepted. + // security fixes arrive alert-driven instead. lockFileMaintenance: { enabled: false }, // Config-migration PRs may rewrite JSON5 to JSON, dropping comments; this // file's policy lives in its comments. Migrate manually on Renovate majors // instead. configMigration: false, timezone: 'America/Toronto', - // Full-day window, not docsy root's 'before 6am on monday': on Mend's hosted - // scheduler, a not-yet-activated repo (no merged Renovate PR) is visited - // daily at an hour we don't control; a narrow window can miss every visit - // and never bootstrap. - schedule: ['on monday'], + schedule: ['on sunday'], labels: ['dependencies'], // Deliberately out: gomod (the Docsy theme pin, release-driven) and docker // (best-effort setup; its pins are bumped manually, see CONTRIBUTING.md). From 6ea989140fe3cafe736b65024fe6addd38aec31b Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 08:07:08 -0400 Subject: [PATCH 08/15] Add cSpell ignore terms to Renovate config --- renovate.json5 | 1 + 1 file changed, 1 insertion(+) diff --git a/renovate.json5 b/renovate.json5 index 8fe756c522..2e01e0240b 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -44,4 +44,5 @@ enabled: false, }, ], +// cSpell:ignore gomod hugo hugoautogen fortawesome fontawesome sunday etarget } From e9c54677f9d410ae5ba8074792030c31fddcea7a Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 08:16:01 -0400 Subject: [PATCH 09/15] renovate.json5: cron schedule syntax 'on sunday' rides the deprecated @breejs/later parser, slated for removal in a future major; with configMigration off, majors are manual, so don't commit a known migration. --- renovate.json5 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 2e01e0240b..5161066d62 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -20,7 +20,8 @@ // instead. configMigration: false, timezone: 'America/Toronto', - schedule: ['on sunday'], + // Any time Sunday: version PRs batch for Monday review. + schedule: ['* * * * 0'], labels: ['dependencies'], // Deliberately out: gomod (the Docsy theme pin, release-driven) and docker // (best-effort setup; its pins are bumped manually, see CONTRIBUTING.md). @@ -44,5 +45,5 @@ enabled: false, }, ], -// cSpell:ignore gomod hugo hugoautogen fortawesome fontawesome sunday etarget + // cSpell:ignore gomod hugo hugoautogen fortawesome fontawesome sunday etarget } From 4b9a2c0b170ca27167d15301b5827063ee8255b2 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 08:49:35 -0400 Subject: [PATCH 10/15] Trim --- renovate.json5 | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 5161066d62..48de398155 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -1,49 +1,26 @@ { $schema: 'https://docs.renovatebot.com/renovate-schema.json', extends: ['config:best-practices'], - // config:best-practices pulls in security:minimumReleaseAgeNpm: its 3-day npm - // rule would override the global minimumReleaseAge below. Its age exemptions - // for timestamp-less update types are deliberately not restored: those - // updates sit pending on the Dependency Dashboard; age-check manually before - // force-creating a PR. - // - // IMPORTANT: an upstream rename of the preset silently re-admits it. + // For details about this repo's settings, see CONTRIBUTING.md ignorePresets: ['security:minimumReleaseAgeNpm'], - // Also from config:best-practices (:maintainLockFilesWeekly), and unwanted - // here: weekly wholesale re-resolves churn a committed, reviewed lockfile, - // and the npm ETARGET fallback (a retry without --before when the lock - // already holds a too-new version) can slip past the age gate. Transitive - // security fixes arrive alert-driven instead. - lockFileMaintenance: { enabled: false }, - // Config-migration PRs may rewrite JSON5 to JSON, dropping comments; this - // file's policy lives in its comments. Migrate manually on Renovate majors - // instead. - configMigration: false, - timezone: 'America/Toronto', - // Any time Sunday: version PRs batch for Monday review. - schedule: ['* * * * 0'], + lockFileMaintenance: { enabled: false }, // done manually + timezone: 'America/Montreal', + schedule: ['* * * * 0'], // Sunday labels: ['dependencies'], - // Deliberately out: gomod (the Docsy theme pin, release-driven) and docker - // (best-effort setup; its pins are bumped manually, see CONTRIBUTING.md). - enabledManagers: ['npm', 'github-actions'], + enabledManagers: ['npm', 'github-actions'], // gomod is manually updated. minimumReleaseAge: '7 days', packageRules: [ { - // hugo-extended version bumps are manual; flow + security-update paths: - // CONTRIBUTING.md's maintainer notes. matchPackageNames: ['hugo-extended'], matchUpdateTypes: ['major', 'minor', 'patch'], - enabled: false, + enabled: false, // manual updates only }, { // Theme-managed (packages/hugoautogen is regenerated from the Docsy - // theme, reverting any bump): updates route through the theme. This - // doesn't constrain Dependabot security updates: an alert-driven PR may - // still bump these directly; close it and route the fix through a theme - // update. + // theme, reverting any bump): updates route through the theme. matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], enabled: false, }, ], - // cSpell:ignore gomod hugo hugoautogen fortawesome fontawesome sunday etarget + // cSpell:ignore gomod hugo hugoautogen fortawesome fontawesome } From 7e2e0502566e0f5a5cfad34e81f8337bb3fcb4de Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 08:59:51 -0400 Subject: [PATCH 11/15] Move Renovate settings rationale to CONTRIBUTING; simplify the config Owner pass: config comments shrink to pointers and one-liners; CONTRIBUTING's new Dependency updates section owns the whys (cooldown preset exclusion + rename caution, lock maintenance, manager whitelist, package-rule carve-outs, the security-PR posture). Also: timezone America/Montreal, hugo-extended rule unscoped (matchUpdateTypes had no effect: security fixes arrive as version bumps and matched anyway), configMigration left at default (owner accepts catching a rewrite). --- CONTRIBUTING.md | 20 ++++++++++++++++++++ renovate.json5 | 13 +++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7666acfb84..21c502d8b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,26 @@ This project follows ## Maintainer notes +### Dependency updates + +Renovate opens version-update PRs, batched weekly, under `renovate.json5`. +Settings rationale: + +- `ignorePresets`: the preset's 3-day npm cooldown would override this repo's + 7-day `minimumReleaseAge`. Caution: this exclusion silently stops working if + the preset is renamed upstream. +- `lockFileMaintenance` off: wholesale lock re-resolves would churn the + committed lockfile; transitive security fixes arrive alert-driven instead. +- `enabledManagers` (whitelist): gomod (the Docsy theme pin) and the Docker pins + are updated manually; see [Upgrade Docsy](#upgrade-docsy) and + [Update Hugo](#update-hugo). +- Package rules: `hugo-extended` is version-pinned and coupled to its + `allowScripts` approval (see [Update Hugo](#update-hugo)); bootstrap and Font + Awesome updates route through the theme. + +Renovate's vulnerability-alert PRs stay on (immediate, cooldown-exempt), beside +GitHub's Dependabot security updates; a rare duplicate PR is accepted. + ### Deploy logs The site deploys on Netlify: logs are in the project's [Netlify diff --git a/renovate.json5 b/renovate.json5 index 48de398155..5d7d307395 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -1,23 +1,24 @@ { $schema: 'https://docs.renovatebot.com/renovate-schema.json', extends: ['config:best-practices'], - // For details about this repo's settings, see CONTRIBUTING.md + // For details about this repo's settings, see + // CONTRIBUTING.md#dependency-updates ignorePresets: ['security:minimumReleaseAgeNpm'], lockFileMaintenance: { enabled: false }, // done manually timezone: 'America/Montreal', schedule: ['* * * * 0'], // Sunday labels: ['dependencies'], - enabledManagers: ['npm', 'github-actions'], // gomod is manually updated. + // Whitelist: all other managers are off (gomod, docker: manual updates). + enabledManagers: ['npm', 'github-actions'], minimumReleaseAge: '7 days', packageRules: [ { matchPackageNames: ['hugo-extended'], - matchUpdateTypes: ['major', 'minor', 'patch'], - enabled: false, // manual updates only + enabled: false, // Manually updated to match Docsy requirements }, { - // Theme-managed (packages/hugoautogen is regenerated from the Docsy - // theme, reverting any bump): updates route through the theme. + // Updates through Docsy (packages/hugoautogen is regenerated from the Docsy + // theme, reverting any bump). matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], enabled: false, }, From 4838945e14ab6751d309430327e03126e1c00b62 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 09:18:05 -0400 Subject: [PATCH 12/15] Renovate config: gomod blocklist; align comments with CONTRIBUTING - gomod: {enabled: false} replaces the enabledManagers whitelist; the docker managers turn on as a result (best-effort setup, accepted) - each rule keeps a one-liner; CONTRIBUTING's Dependency updates section owns the rationale (hugoautogen-regeneration mechanism moved there) --- CONTRIBUTING.md | 12 ++++++------ renovate.json5 | 6 ++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21c502d8b2..b5a99b0c87 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,20 +31,20 @@ This project follows ### Dependency updates -Renovate opens version-update PRs, batched weekly, under `renovate.json5`. -Settings rationale: +Renovate opens version-update PRs, batched weekly, configured in +`renovate.json5`. Settings rationale: - `ignorePresets`: the preset's 3-day npm cooldown would override this repo's 7-day `minimumReleaseAge`. Caution: this exclusion silently stops working if the preset is renamed upstream. - `lockFileMaintenance` off: wholesale lock re-resolves would churn the committed lockfile; transitive security fixes arrive alert-driven instead. -- `enabledManagers` (whitelist): gomod (the Docsy theme pin) and the Docker pins - are updated manually; see [Upgrade Docsy](#upgrade-docsy) and - [Update Hugo](#update-hugo). +- `gomod` off: the Docsy theme pin is updated manually; see + [Upgrade Docsy](#upgrade-docsy). - Package rules: `hugo-extended` is version-pinned and coupled to its `allowScripts` approval (see [Update Hugo](#update-hugo)); bootstrap and Font - Awesome updates route through the theme. + Awesome updates route through the theme (`packages/hugoautogen` is regenerated + from the theme, reverting any direct bump). Renovate's vulnerability-alert PRs stay on (immediate, cooldown-exempt), beside GitHub's Dependabot security updates; a rare duplicate PR is accepted. diff --git a/renovate.json5 b/renovate.json5 index 5d7d307395..904fe51211 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -8,8 +8,7 @@ timezone: 'America/Montreal', schedule: ['* * * * 0'], // Sunday labels: ['dependencies'], - // Whitelist: all other managers are off (gomod, docker: manual updates). - enabledManagers: ['npm', 'github-actions'], + gomod: { enabled: false }, minimumReleaseAge: '7 days', packageRules: [ { @@ -17,8 +16,7 @@ enabled: false, // Manually updated to match Docsy requirements }, { - // Updates through Docsy (packages/hugoautogen is regenerated from the Docsy - // theme, reverting any bump). + // Updates through Docsy. matchPackageNames: ['bootstrap', '@fortawesome/fontawesome-free'], enabled: false, }, From d3eb0042124e29f0f51d16f2c66f48ce86b6b188 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 09:35:39 -0400 Subject: [PATCH 13/15] CONTRIBUTING: Docker Hugo pin is Renovate-proposed now The Dockerfile manager took over base-image bumps when the manager whitelist became a gomod blocklist; DART_SASS_VERSION stays manual. --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b5a99b0c87..62e7954cb5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,8 +90,9 @@ new version is approved. The approval gates the install script only (the hugo binary self-installs at first use), so don't run builds between the two steps. Automated update PRs skip hugo-extended version bumps for the same reason, except security updates, which fail CI until approved via `approve:hugo`. The -Docker flow pins Hugo and Dart Sass independently in the Dockerfile: bump those -alongside Hugo and `sass-embedded` updates. +Dockerfile (best-effort, unsupported) pins Hugo and Dart Sass independently: +Renovate proposes base-image (Hugo) bumps; bump `DART_SASS_VERSION` manually +alongside `sass-embedded` updates. ### Develop against a local Docsy From ee2e24c400a02ac985e497592ee6a319c0acb3ef Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 09:39:27 -0400 Subject: [PATCH 14/15] renovate.json5: drop the lockFileMaintenance one-liner 'done manually' contradicted CONTRIBUTING (re-resolves are avoided, not done by hand); the header pointer owns the rationale. --- renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renovate.json5 b/renovate.json5 index 904fe51211..5dd328af60 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -4,7 +4,7 @@ // For details about this repo's settings, see // CONTRIBUTING.md#dependency-updates ignorePresets: ['security:minimumReleaseAgeNpm'], - lockFileMaintenance: { enabled: false }, // done manually + lockFileMaintenance: { enabled: false }, timezone: 'America/Montreal', schedule: ['* * * * 0'], // Sunday labels: ['dependencies'], From 8eb1a61238c0d76894e51d623029ac199e628d25 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Aug 2026 10:00:51 -0400 Subject: [PATCH 15/15] CONTRIBUTING: true up the Renovate manager surface Adversarial round 3: name the blocklist consequence (all detected managers active, Docker included -- tag bumps and digest pins); restore the bootstrap/FA security-PR guidance lost in the comment trims; 'created on Sundays' over 'batched weekly'; drop a stale cSpell word. --- CONTRIBUTING.md | 13 ++++++++----- renovate.json5 | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 62e7954cb5..4fb85ae2be 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ This project follows ### Dependency updates -Renovate opens version-update PRs, batched weekly, configured in +Renovate opens version-update PRs, created on Sundays, configured in `renovate.json5`. Settings rationale: - `ignorePresets`: the preset's 3-day npm cooldown would override this repo's @@ -40,11 +40,14 @@ Renovate opens version-update PRs, batched weekly, configured in - `lockFileMaintenance` off: wholesale lock re-resolves would churn the committed lockfile; transitive security fixes arrive alert-driven instead. - `gomod` off: the Docsy theme pin is updated manually; see - [Upgrade Docsy](#upgrade-docsy). + [Upgrade Docsy](#upgrade-docsy). All other detected managers are active, + including Docker (base-image updates: tag bumps and digest pins; see + [Update Hugo](#update-hugo)). - Package rules: `hugo-extended` is version-pinned and coupled to its `allowScripts` approval (see [Update Hugo](#update-hugo)); bootstrap and Font Awesome updates route through the theme (`packages/hugoautogen` is regenerated - from the theme, reverting any direct bump). + from the theme, reverting any direct bump). A Dependabot security PR may still + bump these directly: close it and route the fix through a theme update. Renovate's vulnerability-alert PRs stay on (immediate, cooldown-exempt), beside GitHub's Dependabot security updates; a rare duplicate PR is accepted. @@ -91,8 +94,8 @@ binary self-installs at first use), so don't run builds between the two steps. Automated update PRs skip hugo-extended version bumps for the same reason, except security updates, which fail CI until approved via `approve:hugo`. The Dockerfile (best-effort, unsupported) pins Hugo and Dart Sass independently: -Renovate proposes base-image (Hugo) bumps; bump `DART_SASS_VERSION` manually -alongside `sass-embedded` updates. +Renovate proposes base-image updates (tag bumps and digest pins); bump +`DART_SASS_VERSION` manually alongside `sass-embedded` updates. ### Develop against a local Docsy diff --git a/renovate.json5 b/renovate.json5 index 5dd328af60..95f6dd202f 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -21,5 +21,5 @@ enabled: false, }, ], - // cSpell:ignore gomod hugo hugoautogen fortawesome fontawesome + // cSpell:ignore gomod hugo fortawesome fontawesome }