From 23fb7e0c7906ede8ab7739b20d9387df8124b09c Mon Sep 17 00:00:00 2001 From: haelyra <49814733+haelyra@users.noreply.github.com> Date: Thu, 3 Sep 2026 14:59:01 -0400 Subject: [PATCH] ci: avoid redundant Python dependency floors --- .github/dependabot.yml | 2 + tests/ci/dependabot-config.test.js | 62 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tests/ci/dependabot-config.test.js diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5a63d1db0..0621cc6a3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -46,6 +46,7 @@ updates: schedule: interval: "weekly" day: "monday" + versioning-strategy: "increase-if-necessary" labels: - "dependencies" - "python" @@ -66,6 +67,7 @@ updates: schedule: interval: "weekly" day: "monday" + versioning-strategy: "increase-if-necessary" labels: - "dependencies" - "python" diff --git a/tests/ci/dependabot-config.test.js b/tests/ci/dependabot-config.test.js new file mode 100644 index 000000000..e9b076287 --- /dev/null +++ b/tests/ci/dependabot-config.test.js @@ -0,0 +1,62 @@ +#!/usr/bin/env node +/** + * Validate that Dependabot keeps useful Python security coverage without + * raising already-compatible minimum versions every week. + */ + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const yaml = require('js-yaml'); + +const CONFIG_PATH = path.join(__dirname, '..', '..', '.github', 'dependabot.yml'); + +function test(name, fn) { + try { + fn(); + console.log(` ✓ ${name}`); + return true; + } catch (error) { + console.log(` ✗ ${name}`); + console.log(` Error: ${error.message}`); + return false; + } +} + +function run() { + console.log('\n=== Testing Dependabot configuration ===\n'); + + const config = yaml.load(fs.readFileSync(CONFIG_PATH, 'utf8')); + const pipUpdates = config.updates.filter(update => update['package-ecosystem'] === 'pip'); + let passed = 0; + let failed = 0; + + if (test('keeps both Python manifests under Dependabot coverage', () => { + assert.deepStrictEqual( + pipUpdates.map(update => update.directory).sort(), + ['/', '/skills/skill-comply'], + ); + })) passed++; else failed++; + + if (test('does not raise already-compatible Python minimum versions', () => { + for (const update of pipUpdates) { + assert.strictEqual(update['versioning-strategy'], 'increase-if-necessary'); + } + })) passed++; else failed++; + + if (test('retains grouped Python security updates', () => { + for (const update of pipUpdates) { + assert.ok(update.groups); + assert.ok( + Object.values(update.groups).some(group => group['applies-to'] === 'security-updates'), + `missing security-update group for ${update.directory}`, + ); + } + })) passed++; else failed++; + + console.log(`\nPassed: ${passed}`); + console.log(`Failed: ${failed}`); + process.exit(failed > 0 ? 1 : 0); +} + +run();