diff --git a/nightlies/trigger_pipelines.py b/nightlies/trigger_pipelines.py
new file mode 100755
index 0000000000000000000000000000000000000000..4e1b10be43a3c3ba754816b7cfcd1e30549a6457
--- /dev/null
+++ b/nightlies/trigger_pipelines.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+"""
+Trigger Pipelines.
+You need to set the environment variable of
+  GITLAB_API_TOKEN to your private token
+
+Usage:
+  {0} <project_name>...
+  {0} -h | --help
+  {0} --version
+
+Options:
+  -h --help     Show this screen.
+  --version     Show version.
+
+"""
+
+import os
+import sys
+import subprocess
+import json
+import time
+from docopt import docopt
+
+
+PACKAGES_ID = {
+    'bob.extension': '1475',
+    'bob.blitz': '1390',
+    'bob.core': '1394',
+    'bob.ip.draw': '1491',
+    'bob.io.base': '1479',
+    'bob.sp': '1527',
+    'bob.math': '1540',
+    'bob.ap': '1377',
+    'bob.measure': '1521',
+    'bob.db.base': '1409',
+    'bob.io.image': '1481',
+    'bob.io.video': '1485',
+    'bob.io.matlab': '1483',
+    'bob.ip.base': '1487',
+    'bob.ip.color': '1488',
+    'bob.ip.gabor': '1497',
+    'bob.learn.activation': '1506',
+    'bob.learn.libsvm': '1512',
+    'bob.learn.boosting': '1509',
+    'bob.io.audio': '1477',
+    'bob.learn.linear': '1514',
+    'bob.learn.mlp': '1517',
+    'bob.db.wine': '1468',
+    'bob.db.mnist': '1440',
+    'bob.db.atnt': '1399',
+    'bob.ip.flandmark': '1495',
+    'bob.ip.facedetect': '1493',
+    'bob.ip.optflow.hornschunck': '1500',
+    'bob.ip.optflow.liu': '1503',
+    'bob.learn.em': '1510',
+    'bob.db.iris': '1431',
+}
+
+
+class Gitlab(object):
+    """A class that wraps Gitlab API using curl"""
+
+    def __init__(self, token):
+        super(Gitlab, self).__init__()
+        self.token = token
+        self.base_url = 'https://gitlab.idiap.ch/api/v3/'
+
+    def get_project(self, project_name, namespace='bob'):
+        cmd = ["curl", "--header",
+               "PRIVATE-TOKEN: {}".format(self.token),
+               self.base_url + "projects/{}%2F{}".format(
+                   namespace, project_name)]
+        pipeline = subprocess.check_output(cmd)
+        return json.loads(pipeline.decode())
+
+    def create_pipeline(self, project_id):
+        cmd = ["curl", "--request", "POST", "--header",
+               "PRIVATE-TOKEN: {}".format(self.token),
+               self.base_url + "projects/{}/pipeline?ref=master".format(
+                   project_id)]
+        pipeline = subprocess.check_output(cmd)
+        return json.loads(pipeline.decode())
+
+    def get_pipeline(self, project_id, pipeline_id):
+        cmd = ["curl", "--header",
+               "PRIVATE-TOKEN: {}".format(self.token),
+               self.base_url + "projects/{}/pipelines/{}".format(
+                   project_id, pipeline_id)]
+        pipeline = subprocess.check_output(cmd)
+        return json.loads(pipeline.decode())
+
+
+def main(packages_list):
+    gitlab = Gitlab(os.environ.get('GITLAB_API_TOKEN'))
+    for package in packages_list:
+        pid = PACKAGES_ID.get(package)
+        if pid is None:
+            pid = gitlab.get_project(package)['id']
+        print('Triggering a pipeline for {}'.format(package))
+        last_pipeline = gitlab.create_pipeline(pid)
+        while last_pipeline['status'] in ['pending', 'running']:
+            print('Pipeline {} for project {} is not finished. '
+                  'Sleeping for 30 seconds.'.format(
+                      last_pipeline['id'], package))
+            time.sleep(30)
+            last_pipeline = gitlab.get_pipeline(pid, last_pipeline['id'])
+        if not last_pipeline['status'] == 'passed':
+            print('Pipeline {} for project {} failed. Exiting ...'.format(
+                last_pipeline['id'], package))
+            return
+
+
+if __name__ == '__main__':
+    arguments = docopt(__doc__.format(sys.argv[0]), version='Nightlies 0.0.1')
+    print(arguments)
+    main(arguments['<project_name>'])