Skip to content

Commit b599bcb

Browse files
fix: skip repo if no package manager found (#270)
* fix: skip repo if no package manager found * feat: add gradle and devcontainers support + tests * feat: add test for dependabot extra configuration at env level * fix: add registries key if existing configuration dependabot configuration exists
1 parent b467ec6 commit b599bcb

File tree

6 files changed

+101
-29
lines changed

6 files changed

+101
-29
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ maven:
160160
password: "${{secrets.password}}"
161161
```
162162
163-
The principal key of each configuration need to match the package managers that the [script is looking for](https://github.com/github/evergreen/blob/main/dependabot_file.py#L78).
163+
The principal key of each configuration need to match the package managers that the [script is looking for](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem).
164164
165165
The `dependabot.yaml` created file will look like the following with the `registries:` key added:
166166

dependabot_file.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ def make_dependabot_config(
5454
if extra_dependabot_config:
5555
ecosystem_config = extra_dependabot_config.get(ecosystem)
5656
if ecosystem_config:
57+
if "registries" not in dependabot_config:
58+
dependabot_config.update({"registries": {}})
5759
dependabot_config["registries"][ecosystem] = ecosystem_config
5860
dependabot_config["updates"][-1].update(
5961
{"registries": [SingleQuotedScalarString(ecosystem)]}
@@ -184,6 +186,7 @@ def build_dependabot_file(
184186
],
185187
"docker": ["Dockerfile"],
186188
"maven": ["pom.xml"],
189+
"gradle": ["build.gradle", "build.gradle.kts"],
187190
}
188191

189192
# Detect package managers where manifest files have known names
@@ -242,6 +245,23 @@ def build_dependabot_file(
242245
break
243246
except github3.exceptions.NotFoundError:
244247
pass
248+
if "devcontainers" not in exempt_ecosystems_list:
249+
try:
250+
for file in repo.directory_contents(".devcontainer"):
251+
if file[0] == "devcontainer.json":
252+
package_managers_found["devcontainers"] = True
253+
make_dependabot_config(
254+
"devcontainers",
255+
group_dependencies,
256+
schedule,
257+
schedule_day,
258+
labels,
259+
dependabot_file,
260+
extra_dependabot_config,
261+
)
262+
break
263+
except github3.exceptions.NotFoundError:
264+
pass
245265

246266
if any(package_managers_found.values()):
247267
return dependabot_file

env.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ def get_env_vars(
344344
labels_list = [label.lower().strip() for label in labels_str.split(",")]
345345

346346
dependabot_config_file = os.getenv("DEPENDABOT_CONFIG_FILE")
347+
if dependabot_config_file and not os.path.exists(dependabot_config_file):
348+
raise ValueError(
349+
f"No dependabot extra configuration found. Please create one in {dependabot_config_file}"
350+
)
347351

348352
return (
349353
organization,

evergreen.py

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
"""This file contains the main() and other functions needed to open an issue/PR dependabot is not enabled but could be"""
22

3-
import base64
43
import io
5-
import os
64
import sys
75
import uuid
86
from datetime import datetime
@@ -123,26 +121,15 @@ def main(): # pragma: no cover
123121
yaml = ruamel.yaml.YAML()
124122
yaml.preserve_quotes = True
125123
# If running locally on a computer the local file takes precedence over the one existent on the repository
126-
if os.path.exists(dependabot_config_file):
127-
try:
128-
with open(
129-
dependabot_config_file, "r", encoding="utf-8"
130-
) as extra_dependabot_config:
131-
extra_dependabot_config = yaml.load(extra_dependabot_config)
132-
except ruamel.yaml.YAMLError as e:
133-
print(f"YAML indentation error: {e}")
134-
continue
135-
else:
136-
try:
137-
extra_dependabot_config = check_existing_config(
138-
repo, dependabot_config_file
139-
).content
140-
extra_dependabot_config = yaml.load(
141-
base64.b64decode(extra_dependabot_config)
142-
)
143-
except ruamel.yaml.YAMLError as e:
144-
print(f"YAML indentation error: {e}")
145-
continue
124+
try:
125+
with open(
126+
dependabot_config_file, "r", encoding="utf-8"
127+
) as extra_dependabot_config:
128+
extra_dependabot_config = yaml.load(extra_dependabot_config)
129+
except ruamel.yaml.YAMLError as e:
130+
print(f"YAML indentation error: {e}")
131+
continue
132+
146133
else:
147134
# If no dependabot configuration file is present set the variable empty
148135
extra_dependabot_config = None
@@ -173,7 +160,7 @@ def main(): # pragma: no cover
173160
print("\tNo (new) compatible package manager found")
174161
continue
175162

176-
yaml.dump(dependabot_file, stream)
163+
dependabot_file = yaml.dump(dependabot_file, stream)
177164
dependabot_file = stream.getvalue()
178165

179166
# If dry_run is set, just print the dependabot file

test_dependabot_file.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ def test_build_dependabot_file_with_extra_dependabot_config_file(self):
205205

206206
# expected_result maintains existing ecosystem with custom configuration
207207
# and adds new ecosystem
208-
extra_dependabot_config = MagicMock()
209-
extra_dependabot_config.content = base64.b64encode(
208+
extra_dependabot_config = yaml.load(
210209
b"""
211210
npm:
212211
type: 'npm'
@@ -215,9 +214,6 @@ def test_build_dependabot_file_with_extra_dependabot_config_file(self):
215214
password: '${{secrets.password}}'
216215
"""
217216
)
218-
extra_dependabot_config = yaml.load(
219-
base64.b64decode(extra_dependabot_config.content)
220-
)
221217

222218
expected_result = yaml.load(
223219
b"""
@@ -448,6 +444,26 @@ def test_build_dependabot_file_with_maven(self):
448444
)
449445
self.assertEqual(result, expected_result)
450446

447+
def test_build_dependabot_file_with_gradle(self):
448+
"""Test that the dependabot.yml file is built correctly with gradle"""
449+
repo = MagicMock()
450+
repo.file_contents.side_effect = lambda filename: filename == "build.gradle"
451+
452+
expected_result = yaml.load(
453+
b"""
454+
version: 2
455+
updates:
456+
- package-ecosystem: 'gradle'
457+
directory: '/'
458+
schedule:
459+
interval: 'weekly'
460+
"""
461+
)
462+
result = build_dependabot_file(
463+
repo, False, [], {}, None, "weekly", "", [], None
464+
)
465+
self.assertEqual(result, expected_result)
466+
451467
def test_build_dependabot_file_with_terraform_with_files(self):
452468
"""Test that the dependabot.yml file is built correctly with Terraform"""
453469
repo = MagicMock()
@@ -498,6 +514,31 @@ def test_build_dependabot_file_with_terraform_without_files(self):
498514
)
499515
self.assertIsNone(result)
500516

517+
def test_build_dependabot_file_with_devcontainers(self):
518+
"""Test that the dependabot.yml file is built correctly with devcontainers"""
519+
repo = MagicMock()
520+
response = MagicMock()
521+
response.status_code = 404
522+
repo.file_contents.side_effect = github3.exceptions.NotFoundError(resp=response)
523+
repo.directory_contents.side_effect = lambda path: (
524+
[("devcontainer.json", None)] if path == ".devcontainer" else []
525+
)
526+
527+
expected_result = yaml.load(
528+
b"""
529+
version: 2
530+
updates:
531+
- package-ecosystem: 'devcontainers'
532+
directory: '/'
533+
schedule:
534+
interval: 'weekly'
535+
"""
536+
)
537+
result = build_dependabot_file(
538+
repo, False, [], None, None, "weekly", "", [], None
539+
)
540+
self.assertEqual(result, expected_result)
541+
501542
def test_build_dependabot_file_with_github_actions(self):
502543
"""Test that the dependabot.yml file is built correctly with GitHub Actions"""
503544
repo = MagicMock()

test_env.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,26 @@ def test_get_env_vars_project_id_not_a_number(self):
13011301
"PROJECT_ID environment variable is not numeric",
13021302
)
13031303

1304+
@patch.dict(
1305+
os.environ,
1306+
{
1307+
"ORGANIZATION": "my_organization",
1308+
"GH_TOKEN": "my_token",
1309+
"SCHEDULE": "weekly",
1310+
"DEPENDABOT_CONFIG_FILE": "config.yaml",
1311+
},
1312+
clear=True,
1313+
)
1314+
def test_get_env_vars_with_dependabot_config_file_set_but_not_found(self):
1315+
"""Test that no dependabot file configuration is present and the DEPENDABOT_CONFIG_FILE is set"""
1316+
with self.assertRaises(ValueError) as context_manager:
1317+
get_env_vars(True)
1318+
the_exception = context_manager.exception
1319+
self.assertEqual(
1320+
str(the_exception),
1321+
"No dependabot extra configuration found. Please create one in config.yaml",
1322+
)
1323+
13041324

13051325
if __name__ == "__main__":
13061326
unittest.main()

0 commit comments

Comments
 (0)