From c16097d8d33a176dc52d7c1a0981402da99424bf Mon Sep 17 00:00:00 2001
From: Amir MOHAMMADI <amir.mohammadi@idiap.ch>
Date: Wed, 11 Nov 2020 16:05:03 +0100
Subject: [PATCH] Add an alternative command to nightlies This is like
 nightlies with resume. You can avoid rebuilding all packages.

---
 bob/devtools/scripts/alternative_nightlies.py | 75 +++++++++++++++++++
 conda/meta.yaml                               |  1 +
 setup.py                                      |  1 +
 3 files changed, 77 insertions(+)
 create mode 100644 bob/devtools/scripts/alternative_nightlies.py

diff --git a/bob/devtools/scripts/alternative_nightlies.py b/bob/devtools/scripts/alternative_nightlies.py
new file mode 100644
index 00000000..3726479b
--- /dev/null
+++ b/bob/devtools/scripts/alternative_nightlies.py
@@ -0,0 +1,75 @@
+import click
+
+from ..log import verbosity_option
+from . import bdt
+
+
+@click.command(
+    epilog="""
+Examples:
+
+  1. Runs an alternate to nightly builds following a list of packages in a file:
+
+     $ bdt gitlab alt-nightlies -vv order.txt
+
+  2. Provide a list of key value pairs of arguments to be used as variables in the CI
+
+     $ bdt gitlab alt-nightlies -vv order.txt NOSE_EVAL_ATTR "not slow"
+"""
+)
+@click.argument(
+    "order",
+    required=True,
+    type=click.Path(file_okay=True, dir_okay=False, exists=True),
+    nargs=1,
+)
+@click.argument(
+    "variables", nargs=-1,
+)
+@verbosity_option()
+@bdt.raise_on_error
+def alt_nightlies(order, variables):
+    """Alternative nightlies.
+    This command should be run locally and not in Gitlab CI.
+    It will trigger a pipeline for each package in the order file
+    """
+    if not variables:
+        variables = []
+    final_variables = []
+    for i, v in enumerate(variables):
+        if i % 2 == 1:
+            continue
+        final_variables.append({"key": v, "value": variables[i + 1]})
+
+    import time
+
+    from ..ci import read_packages
+    from ..log import get_logger
+    from ..release import get_gitlab_instance
+
+    logger = get_logger(__name__)
+
+    gl = get_gitlab_instance()
+    packages = read_packages(order)
+
+    for n, (package, branch) in enumerate(packages):
+
+        # trigger a pipeline for package and branch
+        project = gl.projects.get(package)
+        logger.info(
+            f"Creating a pipeline for {package} branch {branch} with variables {final_variables}"
+        )
+        pipeline = project.pipelines.create(
+            {"ref": branch, "variables": final_variables}
+        )
+
+        # wait for it to finish
+        while pipeline.status in ("pending", "running"):
+            time.sleep(3)
+            pipeline.refresh()
+            continue
+
+        if pipeline.status == "success":
+            continue
+
+        raise RuntimeError(f"Pipeline {pipeline.web_url} {pipeline.status}")
diff --git a/conda/meta.yaml b/conda/meta.yaml
index de3486a1..fdb621e6 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -109,6 +109,7 @@ test:
     - bdt gitlab badges --help
     - bdt sphinx --help
     - bdt sphinx migrate-autodoc-flags --help
+    - bdt gitlab alt-nightlies --help
     - sphinx-build -aEW ${PREFIX}/share/doc/{{ name }}/doc sphinx
     {% if not os.path.exists('sphinx') %}
     - if [ -n "${CI_PROJECT_DIR}" ]; then mv sphinx "${CI_PROJECT_DIR}/"; fi
diff --git a/setup.py b/setup.py
index 5a9eb12b..9bf5e1f6 100644
--- a/setup.py
+++ b/setup.py
@@ -68,6 +68,7 @@ setup(
             "get-pipelines = bob.devtools.scripts.pipelines:get_pipelines",
             "graph = bob.devtools.scripts.graph:graph",
             "update-bob = bob.devtools.scripts.update_bob:update_bob",
+            "alt-nightlies = bob.devtools.scripts.alternative_nightlies:alt_nightlies",
         ],
         "bdt.ci.cli": [
             "base-build = bob.devtools.scripts.ci:base_build",
-- 
GitLab