Skip to content

Commit

Permalink
feat: add ability to set dependabot schedule and schedule day via env…
Browse files Browse the repository at this point in the history
…ironment variables

Closes #217

- [x] new environment variables: SCHEDULE, SCHEDULE_DAY
- [x] update README with new environment variable information
- [x] passing specs

Signed-off-by: jmeridth <jmeridth@gmail.com>
  • Loading branch information
jmeridth committed Sep 12, 2024
1 parent ab5f7e7 commit 220a0b6
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 32 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ This action can be configured to authenticate with GitHub App Installation or Pe
| `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`, `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`. |
| `REPO_SPECIFIC_EXEMPTIONS` | False | "" | A list of repositories that should be exempt from specific package ecosystems similar to EXEMPT_ECOSYSTEMS but those apply to all repositories. ex: `org1/repo1:docker,github-actions;org1/repo2:pip` would set exempt_ecosystems for `org1/repo1` to be `['docker', 'github-actions']`, and for `org1/repo2` it would be `['pip']`, while for every other repository evaluated, it would be set by the env variable `EXEMPT_ECOSYSTEMS`. NOTE: If you want specific exemptions to be added on top of the already specified global exemptions, you need to add the global exemptions to each repo specific exemption. |
| `SCHEDULE` | False | 'weekly' | Schedule interval by which to check for dependency updates via Dependabot. Allowed values are 'daily', 'weekly', or 'monthly' |
| `SCHEDULE_DAY` | False | '' | Scheduled day by which to check for dependency updates via Dependabot. Allowed values are days of the week full names (i.e., 'monday') |

### Example workflows

Expand Down
28 changes: 23 additions & 5 deletions dependabot_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,33 @@
import yaml


def make_dependabot_config(ecosystem, group_dependencies, indent) -> str:
def make_dependabot_config(
ecosystem, group_dependencies, indent, schedule, schedule_day
) -> str:
"""
Make the dependabot configuration for a specific package ecosystem
Args:
ecosystem: the package ecosystem to make the dependabot configuration for
group_dependencies: whether to group dependencies in the dependabot.yml file
indent: the number of spaces to indent the dependabot configuration ex: " "
schedule: the schedule to run dependabot ex: "daily"
schedule_day: the day of the week to run dependabot ex: "monday" if schedule is "daily"
Returns:
str: the dependabot configuration for the package ecosystem
"""
schedule_day_line = ""
if schedule_day:
schedule_day_line += f"""
{indent}{indent}{indent}day: '{schedule_day}'"""

dependabot_config = f"""{indent}- package-ecosystem: '{ecosystem}'
{indent}{indent}directory: '/'
{indent}{indent}schedule:
{indent}{indent}{indent}interval: 'weekly'
{indent}{indent}{indent}interval: '{schedule}'{schedule_day_line}
"""

if group_dependencies:
dependabot_config += f"""{indent}{indent}groups:
{indent}{indent}{indent}production-dependencies:
Expand All @@ -37,6 +47,8 @@ def build_dependabot_file(
exempt_ecosystems,
repo_specific_exemptions,
existing_config,
schedule,
schedule_day,
) -> str | None:
"""
Build the dependabot.yml file for a repo based on the repo contents
Expand All @@ -47,6 +59,8 @@ def build_dependabot_file(
exempt_ecosystems: the list of ecosystems to ignore
repo_specific_exemptions: the list of ecosystems to ignore for a specific repo
existing_config: the existing dependabot configuration file or None if it doesn't exist
schedule: the schedule to run dependabot ex: "daily"
schedule_day: the day of the week to run dependabot ex: "monday" if schedule is "daily"
Returns:
str: the dependabot.yml file for the repo
Expand Down Expand Up @@ -126,7 +140,7 @@ def build_dependabot_file(
if repo.file_contents(file):
package_managers_found[manager] = True
dependabot_file += make_dependabot_config(
manager, group_dependencies, indent
manager, group_dependencies, indent, schedule, schedule_day
)
break
except github3.exceptions.NotFoundError:
Expand All @@ -139,7 +153,7 @@ def build_dependabot_file(
if file[0].endswith(".tf"):
package_managers_found["terraform"] = True
dependabot_file += make_dependabot_config(
"terraform", group_dependencies, indent
"terraform", group_dependencies, indent, schedule, schedule_day
)
break
except github3.exceptions.NotFoundError:
Expand All @@ -150,7 +164,11 @@ def build_dependabot_file(
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, indent
"github-actions",
group_dependencies,
indent,
schedule,
schedule_day,
)
break
except github3.exceptions.NotFoundError:
Expand Down
40 changes: 39 additions & 1 deletion env.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ def parse_repo_specific_exemptions(repo_specific_exemptions_str: str) -> dict:
return exemptions_dict


def get_env_vars(test: bool = False) -> tuple[
def get_env_vars(
test: bool = False,
) -> tuple[
str | None,
list[str],
int | None,
Expand All @@ -113,6 +115,8 @@ def get_env_vars(test: bool = False) -> tuple[
list[str],
bool | None,
dict,
str,
str,
]:
"""
Get the environment variables for use in the action.
Expand Down Expand Up @@ -142,6 +146,8 @@ def get_env_vars(test: bool = False) -> tuple[
exempt_ecosystems_list (list[str]): A list of package ecosystems to exempt from the action
update_existing (bool): Whether to update existing dependabot configuration files
repo_specific_exemptions (dict): A dictionary of per repository ecosystem exemptions
schedule (str): The schedule to run the action on
schedule_day (str): The day of the week to run the action on if schedule is daily
"""

if not test:
Expand Down Expand Up @@ -288,6 +294,36 @@ def get_env_vars(test: bool = False) -> tuple[
repo_specific_exemptions_str
)

schedule = os.getenv("SCHEDULE", "").strip().lower()
if schedule and schedule not in ["daily", "weekly", "monthly"]:
raise ValueError(
"SCHEDULE environment variable not 'daily', 'weekly', or 'monthly'"
)
if not schedule:
schedule = "weekly"
schedule_day = os.getenv("SCHEDULE_DAY", "").strip().lower()
if schedule != "weekly" and schedule_day:
raise ValueError(
"SCHEDULE_DAY environment variable not needed when SCHEDULE is not 'weekly'"
)
if (
schedule == "weekly"
and schedule_day
and schedule_day
not in [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
]
):
raise ValueError(
"SCHEDULE_DAY environment variable not 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', or 'sunday'"
)

return (
organization,
repositories_list,
Expand All @@ -311,4 +347,6 @@ def get_env_vars(test: bool = False) -> tuple[
exempt_ecosystems_list,
update_existing,
repo_specific_exemptions,
schedule,
schedule_day,
)
4 changes: 4 additions & 0 deletions evergreen.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def main(): # pragma: no cover
exempt_ecosystems,
update_existing,
repo_specific_exemptions,
schedule,
schedule_day,
) = env.get_env_vars()

# Auth to GitHub.com or GHE
Expand Down Expand Up @@ -110,6 +112,8 @@ def main(): # pragma: no cover
exempt_ecosystems,
repo_specific_exemptions,
existing_config,
schedule,
schedule_day,
)

if dependabot_file is None:
Expand Down
Loading

0 comments on commit 220a0b6

Please sign in to comment.