diff --git a/README.md b/README.md index f7f7bf1..ab15bfd 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ This action can be configured to authenticate with GitHub App Installation or Pe | `FILTER_VISIBILITY` | False | "public,private,internal" | Use this flag to filter repositories in scope by their visibility (`public`, `private`, `internal`). By default all repository are targeted. ex: to ignore public repositories set this value to `private,internal`. | | `BATCH_SIZE` | False | None | Set this to define the maximum amount of eligible repositories for every run. This is useful if you are targeting large organizations and you don't want to flood repositories with pull requests / issues. ex: if you want to target 20 repositories per time, set this to 20. | | `ENABLE_SECURITY_UPDATES` | False | true | If set to true, Evergreen will enable [Dependabot security updates](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates) on target repositories. Note that the GitHub token needs to have the `administration:write` permission on every repository in scope to successfully enable security updates. | -| `EXEMPT_ECOSYSTEMS` | False | "" | A list of [package ecosystems](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem) to exempt from the generated dependabot configuration. To ignore ecosystems set this to one or more of `bundler`,`cargo`, `composer`, `pip`, `docker`, `npm`, `gomod`, `hex`, `nuget`, `github-actions` and `terraform`. ex: if you don't want Dependabot to update Dockerfiles and Github Actions you can set this to `docker,github-actions`. | +| `EXEMPT_ECOSYSTEMS` | False | "" | A list of [package ecosystems](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem) to exempt from the generated dependabot configuration. To ignore ecosystems set this to one or more of `bundler`,`cargo`, `composer`, `pip`, `docker`, `npm`, `gomod`, `mix`, `nuget`, `github-actions` and `terraform`. ex: if you don't want Dependabot to update Dockerfiles and Github Actions you can set this to `docker,github-actions`. | ### Example workflows diff --git a/dependabot_file.py b/dependabot_file.py index 6a92bac..9edbc4d 100644 --- a/dependabot_file.py +++ b/dependabot_file.py @@ -45,16 +45,20 @@ def build_dependabot_file( Returns: str: the dependabot.yml file for the repo """ - compatible_package_manager_found = False - bundler_found = False - npm_found = False - pip_found = False - cargo_found = False - gomod_found = False - composer_found = False - hex_found = False - nuget_found = False - docker_found = False + package_managers_found = { + "bundler": False, + "npm": False, + "pip": False, + "cargo": False, + "gomod": False, + "composer": False, + "mix": False, + "nuget": False, + "docker": False, + "terraform": False, + "github-actions": False, + } + if existing_config: dependabot_file = existing_config.decoded.decode("utf-8") else: @@ -65,254 +69,67 @@ def build_dependabot_file( add_existing_ecosystem_to_exempt_list(exempt_ecosystems, existing_config) - try: - if ( - repo.file_contents("Gemfile") - and not bundler_found - and "bundler" not in exempt_ecosystems - ): - compatible_package_manager_found = True - bundler_found = True - dependabot_file += make_dependabot_config("bundler", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("Gemfile.lock") - and not bundler_found - and "bundler" not in exempt_ecosystems - ): - compatible_package_manager_found = True - bundler_found = True - dependabot_file += make_dependabot_config("bundler", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - try: - if ( - repo.file_contents("package.json") - and not npm_found - and "npm" not in exempt_ecosystems - ): - compatible_package_manager_found = True - npm_found = True - dependabot_file += make_dependabot_config("npm", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("package-lock.json") - and not npm_found - and "npm" not in exempt_ecosystems - ): - compatible_package_manager_found = True - npm_found = True - dependabot_file += make_dependabot_config("npm", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("yarn.lock") - and not npm_found - and "npm" not in exempt_ecosystems - ): - compatible_package_manager_found = True - npm_found = True - dependabot_file += make_dependabot_config("npm", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - try: - if ( - repo.file_contents("requirements.txt") - and not pip_found - and "pip" not in exempt_ecosystems - ): - compatible_package_manager_found = True - pip_found = True - dependabot_file += make_dependabot_config("pip", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("Pipfile") - and not pip_found - and "pip" not in exempt_ecosystems - ): - compatible_package_manager_found = True - pip_found = True - dependabot_file += make_dependabot_config("pip", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("Pipfile.lock") - and not pip_found - and "pip" not in exempt_ecosystems - ): - compatible_package_manager_found = True - pip_found = True - dependabot_file += make_dependabot_config("pip", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("pyproject.toml") - and not pip_found - and "pip" not in exempt_ecosystems - ): - compatible_package_manager_found = True - pip_found = True - dependabot_file += make_dependabot_config("pip", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("poetry.lock") - and not pip_found - and "pip" not in exempt_ecosystems - ): - compatible_package_manager_found = True - pip_found = True - dependabot_file += make_dependabot_config("pip", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - try: - if ( - repo.file_contents("Cargo.toml") - and not cargo_found - and "cargo" not in exempt_ecosystems - ): - compatible_package_manager_found = True - cargo_found = True - dependabot_file += make_dependabot_config("cargo", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("Cargo.lock") - and not cargo_found - and "cargo" not in exempt_ecosystems - ): - compatible_package_manager_found = True - cargo_found = True - dependabot_file += make_dependabot_config("cargo", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - try: - if ( - repo.file_contents("go.mod") - and not gomod_found - and "gomod" not in exempt_ecosystems - ): - compatible_package_manager_found = True - gomod_found = True - dependabot_file += make_dependabot_config("gomod", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - try: - if ( - repo.file_contents("composer.json") - and not composer_found - and "composer" not in exempt_ecosystems - ): - compatible_package_manager_found = True - composer_found = True - dependabot_file += make_dependabot_config("composer", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("composer.lock") - and not composer_found - and "composer" not in exempt_ecosystems - ): - compatible_package_manager_found = True - composer_found = True - dependabot_file += make_dependabot_config("composer", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - try: - if ( - repo.file_contents("mix.exs") - and not hex_found - and "hex" not in exempt_ecosystems - ): - compatible_package_manager_found = True - hex_found = True - dependabot_file += make_dependabot_config("mix", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if ( - repo.file_contents("mix.lock") - and not hex_found - and "hex" not in exempt_ecosystems - ): - compatible_package_manager_found = True - hex_found = True - dependabot_file += make_dependabot_config("mix", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - if "github-actions" not in exempt_ecosystems: - try: - for file in repo.directory_contents(".github/workflows"): - if file[0].endswith(".yml") or file[0].endswith(".yaml"): - compatible_package_manager_found = True + package_managers = { + "bundler": ["Gemfile", "Gemfile.lock"], + "npm": ["package.json", "package-lock.json", "yarn.lock"], + "pip": [ + "requirements.txt", + "Pipfile", + "Pipfile.lock", + "pyproject.toml", + "poetry.lock", + ], + "cargo": ["Cargo.toml", "Cargo.lock"], + "gomod": ["go.mod"], + "composer": ["composer.json", "composer.lock"], + "mix": ["mix.exs", "mix.lock"], + "nuget": [ + ".nuspec", + ".csproj", + ], + "docker": ["Dockerfile"], + } + + # Detect package managers where manifest files have known names + for manager, manifest_files in package_managers.items(): + if manager in exempt_ecosystems: + continue + for file in manifest_files: + try: + if repo.file_contents(file): + package_managers_found[manager] = True dependabot_file += make_dependabot_config( - "github-actions", group_dependencies + manager, group_dependencies ) break - except github3.exceptions.NotFoundError: - pass - - if "docker" not in exempt_ecosystems: - try: - if repo.file_contents("Dockerfile") and not docker_found: - compatible_package_manager_found = True - docker_found = True - dependabot_file += make_dependabot_config("docker", group_dependencies) - except github3.exceptions.NotFoundError: - pass - - if "nuget" not in exempt_ecosystems: - try: - if repo.file_contents(".nuspec") and not nuget_found: - compatible_package_manager_found = True - nuget_found = True - dependabot_file += make_dependabot_config("nuget", group_dependencies) - except github3.exceptions.NotFoundError: - pass - try: - if repo.file_contents(".csproj") and not nuget_found: - compatible_package_manager_found = True - nuget_found = True - dependabot_file += make_dependabot_config("nuget", group_dependencies) - except github3.exceptions.NotFoundError: - pass + except github3.exceptions.NotFoundError: + pass + # detect package managers with variable file names if "terraform" not in exempt_ecosystems: try: - # detect if the repo has a any terraform files - terraform_files = False for file in repo.directory_contents("/"): if file[0].endswith(".tf"): - terraform_files = True + package_managers_found["terraform"] = True + dependabot_file += make_dependabot_config( + "terraform", group_dependencies + ) + break + except github3.exceptions.NotFoundError: + pass + if "github-actions" not in exempt_ecosystems: + try: + for file in repo.directory_contents(".github/workflows"): + if file[0].endswith(".yml") or file[0].endswith(".yaml"): + package_managers_found["github-actions"] = True + dependabot_file += make_dependabot_config( + "github-actions", group_dependencies + ) break - if terraform_files: - compatible_package_manager_found = True - dependabot_file += make_dependabot_config( - "terraform", group_dependencies - ) except github3.exceptions.NotFoundError: pass - if compatible_package_manager_found: + if any(package_managers_found.values()): return dependabot_file return None