diff --git a/dependabot_file.py b/dependabot_file.py index f69251a..8e8c814 100644 --- a/dependabot_file.py +++ b/dependabot_file.py @@ -28,6 +28,29 @@ ) VALID_COOLDOWN_DAYS_KEYS = frozenset(COOLDOWN_DAYS_KEYS_ORDERED) VALID_COOLDOWN_KEYS = VALID_COOLDOWN_DAYS_KEYS | {"include", "exclude"} +SEMVER_COOLDOWN_ECOSYSTEMS = frozenset( + { + "bundler", + "bun", + "cargo", + "composer", + "conda", + "dotnet-sdk", + "elm", + "gomod", + "gradle", + "julia", + "maven", + "mix", + "npm", + "nuget", + "pip", + "pub", + "rust-toolchain", + "swift", + "uv", + } +) MAX_COOLDOWN_LIST_ITEMS = 150 MIN_COOLDOWN_DAYS = 1 MAX_COOLDOWN_DAYS = 90 @@ -171,14 +194,17 @@ def make_dependabot_config( if cooldown: cooldown_config = {} for key in COOLDOWN_DAYS_KEYS_ORDERED: - if key in cooldown: + if key in cooldown and ( + key == "default-days" or ecosystem in SEMVER_COOLDOWN_ECOSYSTEMS + ): cooldown_config[key] = cooldown[key] - for list_key in ("include", "exclude"): - if list_key in cooldown: - cooldown_config[list_key] = [ - SingleQuotedScalarString(item) for item in cooldown[list_key] - ] - dependabot_config["updates"][-1].update({"cooldown": cooldown_config}) + if cooldown_config: + for list_key in ("include", "exclude"): + if list_key in cooldown: + cooldown_config[list_key] = [ + SingleQuotedScalarString(item) for item in cooldown[list_key] + ] + dependabot_config["updates"][-1].update({"cooldown": cooldown_config}) def build_dependabot_file( diff --git a/test_dependabot_file.py b/test_dependabot_file.py index 218be0a..f3f5285 100644 --- a/test_dependabot_file.py +++ b/test_dependabot_file.py @@ -862,8 +862,8 @@ def test_build_dependabot_file_with_cooldown_default_days_only(self): ) self.assertEqual(result, expected_result) - def test_build_dependabot_file_with_cooldown_all_params(self): - """Test that cooldown with all semver day parameters is added correctly""" + def test_build_dependabot_file_filters_unsupported_semver_cooldown_params(self): + """Test that ecosystems without SemVer cooldown support only get default-days""" repo = MagicMock() repo.get_contents.side_effect = lambda filename: filename == "Dockerfile" or [] @@ -882,15 +882,92 @@ def test_build_dependabot_file_with_cooldown_all_params(self): interval: 'weekly' cooldown: default-days: 3 - semver-major-days: 7 - semver-minor-days: 3 - semver-patch-days: 1 """) result = build_dependabot_file( repo, False, [], {}, None, "weekly", "", [], None, cooldown ) self.assertEqual(result, expected_result) + def test_build_dependabot_file_filters_github_actions_semver_cooldown_params(self): + """Test that GitHub Actions keeps general cooldown fields but not SemVer fields""" + repo = MagicMock() + workflow_file = MagicMock() + workflow_file.name = "test.yml" + + def get_contents(path): + if path == "package.json": + return True + if path == ".github/workflows": + return [workflow_file] + return [] + + repo.get_contents.side_effect = get_contents + cooldown = { + "default-days": 7, + "semver-major-days": 14, + "semver-minor-days": 7, + "semver-patch-days": 3, + "exclude": ["critical-package"], + } + expected_result = yaml.load(b""" +version: 2 +updates: + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'weekly' + cooldown: + default-days: 7 + semver-major-days: 14 + semver-minor-days: 7 + semver-patch-days: 3 + exclude: + - 'critical-package' + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' + cooldown: + default-days: 7 + exclude: + - 'critical-package' +""") + + result = build_dependabot_file( + repo, False, [], {}, None, "weekly", "", [], None, cooldown + ) + + self.assertEqual(result, expected_result) + + def test_build_dependabot_file_omits_unsupported_semver_only_cooldown(self): + """Test that GitHub Actions omits cooldown when no supported day field remains""" + repo = MagicMock() + workflow_file = MagicMock() + workflow_file.name = "test.yml" + repo.get_contents.side_effect = lambda path: ( + [workflow_file] if path == ".github/workflows" else [] + ) + cooldown = { + "semver-major-days": 14, + "semver-minor-days": 7, + "semver-patch-days": 3, + "exclude": ["critical-package"], + } + expected_result = yaml.load(b""" +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' +""") + + result = build_dependabot_file( + repo, False, [], {}, None, "weekly", "", [], None, cooldown + ) + + self.assertEqual(result, expected_result) + def test_build_dependabot_file_with_cooldown_include_exclude(self): """Test that cooldown with include/exclude lists is added correctly""" repo = MagicMock()