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