Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: schedule and schedule day environment variables #222

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 "weekly"

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
Loading