From cd7241032f36992aaacdbc79ea4c65e6ab84697c Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.dos.anjos@gmail.com> Date: Thu, 14 Feb 2019 21:41:04 +0100 Subject: [PATCH] [scripts][commitfile] Refinements to allow direct commits to master, build skips with auto-merge --- bob/devtools/release.py | 27 ++++++++++++++++++++------- bob/devtools/scripts/commitfile.py | 29 ++++++++++++++++++----------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/bob/devtools/release.py b/bob/devtools/release.py index d760e2c2..0e45b949 100644 --- a/bob/devtools/release.py +++ b/bob/devtools/release.py @@ -233,7 +233,7 @@ def update_files_with_mr(gitpkg, files_dict, message, branch, automerge, """Update (via a commit) files of a given gitlab package, through an MR This function can update a file in a gitlab package, but will do this - through a formal merge request. + through a formal merge request. You can auto-merge this request Args: @@ -261,13 +261,14 @@ def update_files_with_mr(gitpkg, files_dict, message, branch, automerge, update_action['content'] = files_dict[filename] data['actions'].append(update_action) - logger.debug("Committing changes in files (%s) to new branch '%s'", + logger.debug("Committing changes in files (%s) to branch '%s'", ', '.join(files_dict.keys()), branch) if not dry_run: commit = gitpkg.commits.create(data) + logger.info('Created commit %s at %s (branch=%s)', + commit.short_id, gitpkg.attributes['path_with_namespace'], branch) logger.debug("Creating merge request %s -> master", branch) - logger.debug("Set merge-when-pipeline-succeeds = %s", automerge) if not dry_run: mr = gitpkg.mergerequests.create({ 'source_branch': branch, @@ -276,8 +277,17 @@ def update_files_with_mr(gitpkg, files_dict, message, branch, automerge, 'remove_source_branch': True, 'assignee_id': user_id, }) - time.sleep(0.5) # to avoid the MR to be merged automatically - bug? - mr.merge(merge_when_pipeline_succeeds=automerge) + logger.info('Created merge-request !%d (%s -> %s) at %s', mr.iid, + branch, 'master', gitpkg.attributes['path_with_namespace']) + + if automerge: + if '[ci skip]' in message.lower() or '[skip ci]' in message.lower(): + logger.info('Merging !%d immediately - CI was skipped', mr.iid) + mr.merge() + else: + logger.info('Auto-merging !%d only if pipeline succeeds', mr.iid) + time.sleep(0.5) # to avoid the MR to be merged automatically - bug? + mr.merge(merge_when_pipeline_succeeds=True) def update_files_at_master(gitpkg, files_dict, message, dry_run): @@ -305,9 +315,12 @@ def update_files_at_master(gitpkg, files_dict, message, dry_run): update_action['content'] = files_dict[filename] data['actions'].append(update_action) - logger.debug("Committing changes in files: %s", ', '.join(files_dict.keys())) + logger.debug("Committing changes in files (%s) to branch 'master'", + ', '.join(files_dict.keys())) if not dry_run: - gitpkg.commits.create(data) + commit = gitpkg.commits.create(data) + logger.info('Created commit %s at %s (branch=%s)', + commit.short_id, gitpkg.attributes['path_with_namespace'], 'master') def get_last_pipeline(gitpkg): diff --git a/bob/devtools/scripts/commitfile.py b/bob/devtools/scripts/commitfile.py index b0218247..9edcab34 100644 --- a/bob/devtools/scripts/commitfile.py +++ b/bob/devtools/scripts/commitfile.py @@ -5,7 +5,8 @@ import os import click from . import bdt -from ..release import get_gitlab_instance, update_files_with_mr +from ..release import get_gitlab_instance, update_files_with_mr, \ + update_files_at_master from ..log import verbosity_option, get_logger logger = get_logger(__name__) @@ -14,18 +15,18 @@ logger = get_logger(__name__) @click.command(epilog=''' Examples: - 1. Replaces the README.rst file on the package bob/bob.extension, through a merge-request, using the contents of the local file with the same name: + 1. Replaces the README.rst file on the package bob/bob.extension, through a direct commit to the master branch, using the contents of the local file with the same name: $ bdt commitfile -vv bob/bob.extension README.rst - 2. Replaces the README.rst file on the package beat/beat.core, specifying a commit/merge-request message: + 2. Replaces the README.rst file on the package beat/beat.core, specifying a commit message: \b $ bdt commitfile -vv --message="[readme] Update [ci skip]" beat/beat.core README.rst - 3. Replaces the file conda/meta.yaml on the package bob/bob.blitz through a merge request, specifying a commit/merge-request message, using the contents of the local file new.yaml, set merge-when-pipeline-succeeds, and the name of the branch to be creatd: + 3. Replaces the file conda/meta.yaml on the package bob/bob.blitz through a merge request through a new branch called "conda-changes", specifying a commit/merge-request message, using the contents of the local file new.yaml, and setting the merge-request property "merge-when-pipeline-succeeds": \b $ bdt commitfile -vv bob/bob.blitz --path=conda/meta.yaml --branch=conda-changes --auto-merge new.yaml @@ -38,8 +39,12 @@ Examples: help='Message to set for this commit',) @click.option('-p', '--path', help='Which path to replace on the remote package',) -@click.option('-b', '--branch', - help='Name of the branch to create for this MR',) +@click.option('-b', '--branch', default='master', + help='Name of the branch to create for this commit. If the branch ' \ + 'name is not "master", then create a new branch and propose the ' \ + 'merge through a proper merge-request. Otherwise, the default ' \ + 'behaviour is to commit directly to the master branch ' \ + '[default: %(default)s',) @click.option('-a', '--auto-merge/--no-auto-merge', default=False, help='If set, then the created merge request will be merged when ' \ 'a potentially associated pipeline succeeds') @@ -50,7 +55,7 @@ Examples: @verbosity_option() @bdt.raise_on_error def commitfile(package, message, file, path, branch, auto_merge, dry_run): - """Changes a file on a given package, directly on the master branch + """Changes a file on a given package, directly on master or through MR """ if '/' not in package: @@ -62,7 +67,7 @@ def commitfile(package, message, file, path, branch, auto_merge, dry_run): # we lookup the gitlab package once use_package = gl.projects.get(package) - logger.info('Found gitlab project %s (id=%d)', + logger.debug('Found gitlab project %s (id=%d)', use_package.attributes['path_with_namespace'], use_package.id) # if we are in a dry-run mode, let's let it be known @@ -77,10 +82,12 @@ def commitfile(package, message, file, path, branch, auto_merge, dry_run): contents = f.read() components = os.path.splitext(path)[0].split(os.sep) - branch = branch or 'update-%s' % components[-1].lower() message = message or ("%s update" % \ ''.join(['[%s]' % k.lower() for k in components])) # commit and push changes - update_files_with_mr(use_package, {path: contents}, message, branch, - auto_merge, dry_run, user_id) + if branch == 'master': + update_files_at_master(use_package, {path: contents}, message, dry_run) + else: + update_files_with_mr(use_package, {path: contents}, message, branch, + auto_merge, dry_run, user_id) -- GitLab