From d27991bf1be440c80ef7242f93ff9728a4222ca6 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 9 Jan 2024 21:10:35 +0100 Subject: [PATCH] FEAT: add option to remove requirements schedule trigger (#263) --- src/repoma/check_dev_files/__init__.py | 4 +- .../check_dev_files/update_pip_constraints.py | 60 +++++++++++++++---- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/repoma/check_dev_files/__init__.py b/src/repoma/check_dev_files/__init__.py index b98836ca..32b40264 100644 --- a/src/repoma/check_dev_files/__init__.py +++ b/src/repoma/check_dev_files/__init__.py @@ -90,7 +90,7 @@ def main(argv: Sequence[str] | None = None) -> int: if args.pin_requirements != "no": executor( update_pip_constraints.main, - cron_frequency=args.pin_requirements, + frequency=args.pin_requirements, ) executor(readthedocs.main, dev_python_version) executor(remove_deprecated_tools, args.keep_issue_templates) @@ -229,7 +229,7 @@ def _create_argparse() -> ArgumentParser: ) parser.add_argument( "--pin-requirements", - choices=["no", "biweekly", "monthly", "bimonthly", "quarterly", "biannually"], + choices=update_pip_constraints.Frequency.__args__, # type:ignore[attr-defined] default="no", help=( "Add a script to pin developer requirements to a constraint file." diff --git a/src/repoma/check_dev_files/update_pip_constraints.py b/src/repoma/check_dev_files/update_pip_constraints.py index 64c43d60..151f3fb1 100644 --- a/src/repoma/check_dev_files/update_pip_constraints.py +++ b/src/repoma/check_dev_files/update_pip_constraints.py @@ -5,13 +5,33 @@ - https://github.com/ComPWA/update-pre-commit """ +from __future__ import annotations + +import sys + from repoma.check_dev_files.github_workflows import remove_workflow, update_workflow from repoma.errors import PrecommitError from repoma.utilities import CONFIG_PATH, REPOMA_DIR from repoma.utilities.executor import Executor +from repoma.utilities.precommit import load_round_trip_precommit_config from repoma.utilities.yaml import create_prettier_round_trip_yaml -__CRON_SCHEDULES = { +if sys.version_info < (3, 8): + from typing_extensions import Literal +else: + from typing import Literal + + +Frequency = Literal[ + "no", + "biweekly", + "monthly", + "bimonthly", + "quarterly", + "biannually", + "outsource", +] +__CRON_SCHEDULES: dict[Frequency, str] = { "biweekly": "0 2 * * 1", "monthly": "0 3 7 */1 *", "bimonthly": "0 3 7 */2 *", @@ -20,11 +40,13 @@ } -def main(cron_frequency: str) -> None: +def main(frequency: Frequency) -> None: executor = Executor() + if frequency == "outsource": + executor(_check_precommit_schedule) executor(_remove_script, "pin_requirements.py") executor(_remove_script, "upgrade.sh") - executor(_update_requirement_workflow, cron_frequency) + executor(_update_requirement_workflow, frequency) executor.finalize() @@ -36,14 +58,17 @@ def _remove_script(script_name: str) -> None: raise PrecommitError(msg) -def _update_requirement_workflow(frequency: str) -> None: - def overwrite_workflow(workflow_file: str, cron_schedule: str) -> None: +def _update_requirement_workflow(frequency: Frequency) -> None: + def overwrite_workflow(workflow_file: str) -> None: expected_workflow_path = ( REPOMA_DIR / CONFIG_PATH.github_workflow_dir / workflow_file ) yaml = create_prettier_round_trip_yaml() expected_data = yaml.load(expected_workflow_path) - expected_data["on"]["schedule"][0]["cron"] = cron_schedule + if frequency == "outsource": + del expected_data["on"]["schedule"] + else: + expected_data["on"]["schedule"][0]["cron"] = _to_cron_schedule(frequency) workflow_path = CONFIG_PATH.github_workflow_dir / workflow_file if not workflow_path.exists(): update_workflow(yaml, expected_data, workflow_path) @@ -52,15 +77,28 @@ def overwrite_workflow(workflow_file: str, cron_schedule: str) -> None: update_workflow(yaml, expected_data, workflow_path) executor = Executor() - executor(overwrite_workflow, "requirements.yml", _to_cron_schedule(frequency)) + executor(overwrite_workflow, "requirements.yml") executor(remove_workflow, "requirements-cron.yml") executor(remove_workflow, "requirements-pr.yml") executor.finalize() -def _to_cron_schedule(frequency: str) -> str: - schedule = __CRON_SCHEDULES.get(frequency) - if schedule is None: +def _to_cron_schedule(frequency: Frequency) -> str: + if frequency not in __CRON_SCHEDULES: msg = f'No cron schedule defined for frequency "{frequency}"' raise PrecommitError(msg) - return schedule + return __CRON_SCHEDULES[frequency] + + +def _check_precommit_schedule() -> None: + msg = ( + "Cannot outsource pip constraints updates, because autoupdate_schedule has not" + f" been set under the ci key in {CONFIG_PATH.precommit}. See" + " https://pre-commit.ci/#configuration-autoupdate_schedule." + ) + if not CONFIG_PATH.precommit.exists(): + raise PrecommitError(msg) + config, _ = load_round_trip_precommit_config() + schedule = config.get("ci", {}).get("autoupdate_schedule") + if schedule is None: + raise PrecommitError(msg)