From ccb3c705707944fc093ccc9e5588e42cbc323ea0 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Sun, 14 Feb 2021 14:24:28 +0100 Subject: [PATCH] Allow running marge-bot as a single CLI job --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ marge/app.py | 6 ++++++ marge/bot.py | 5 ++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f1b4043..89e76b9b 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,9 @@ optional arguments: [env var: MARGE_SOURCE_BRANCH_REGEXP] (default: .*) --debug Debug logging (includes all HTTP requests etc). [env var: MARGE_DEBUG] (default: False) + --cli Run marge-bot as a single CLI command, not as a long-running service. + This may be used to run marge-bot in scheduled CI pipelines or cronjobs. + [env var: MARGE_CLI] (default: False) ``` Here is a config file example ```yaml @@ -299,6 +302,43 @@ configs: name: marge_bot_config ``` +### Running marge-bot in CI + +You can also run marge-bot directly in your existing CI via scheduled pipelines +if you'd like to avoid setting up any additional infrastructure. + +This way, you can inject secrets for marge-bot's credentials at runtime +inside the ephemeral container for each run by adding them to protected CI/CD +variables in a dedicated marge-bot runner project, as well as store execution +logs as artifacts for evidence. + +You can also configure multiple setups in different CI schedules by supplying +`MARGE_*` environment variables per-schedule, such as running a different set +of projects or settings at different times. + +Note that in this case, marge-bot will be slower than when run as a service, +depending on the frequency of your pipeline schedules. + +Create a marge-bot runner project, and add the variables `MARGE_AUTH_TOKEN` +(of type Variable) and `MARGE_SSH_KEY_FILE` (of type File) in your CI/CD +Variables settings. + +Then add a scheduled pipeline run to your project with the following minimal +`.gitlab-ci.yml` config: + +```yaml +run: + image: + name: smarkets/marge-bot:latest + entrypoint: [""] + only: + - schedules + variables: + MARGE_CLI: "true" + MARGE_GITLAB_URL: "$CI_SERVER_URL" + script: marge.app +``` + ### Running marge-bot as a plain python app #### Installing marge-bot with nix diff --git a/marge/app.py b/marge/app.py index d30092fd..675b44b3 100644 --- a/marge/app.py +++ b/marge/app.py @@ -224,6 +224,11 @@ def regexp(str_regex): action='store_true', help='Skip CI when updating individual MRs when using batches' ) + parser.add_argument( + '--cli', + action='store_true', + help='Run marge-bot as a single CLI command, not a service' + ) config = parser.parse_args(args) if config.use_merge_strategy and config.batch: @@ -327,6 +332,7 @@ def main(args=None): skip_ci_batches=options.skip_ci_batches, ), batch=options.batch, + cli=options.cli, ) marge_bot = bot.Bot(api=api, config=config) diff --git a/marge/bot.py b/marge/bot.py index 9f8acb1a..f5f3de91 100644 --- a/marge/bot.py +++ b/marge/bot.py @@ -59,6 +59,9 @@ def _run(self, repo_manager): time_to_sleep_between_projects_in_secs, projects, ) + if self._config.cli: + return + big_sleep = max(0, min_time_to_sleep_after_iterating_all_projects_in_secs - time_to_sleep_between_projects_in_secs * len(projects)) @@ -187,7 +190,7 @@ def _get_single_job(self, project, merge_request, repo, options): class BotConfig(namedtuple('BotConfig', 'user ssh_key_file project_regexp merge_order merge_opts git_timeout ' + - 'git_reference_repo branch_regexp source_branch_regexp batch')): + 'git_reference_repo branch_regexp source_branch_regexp batch cli')): pass