diff --git a/conda/batch-update-bob.sh b/conda/batch-update-conda-forge.sh
similarity index 92%
rename from conda/batch-update-bob.sh
rename to conda/batch-update-conda-forge.sh
index 6a2261a150bb37ad997e2671368b81b11cc2bf00..6e9c349cf05b3c547bd21a17c96612acffd6d9bf 100755
--- a/conda/batch-update-bob.sh
+++ b/conda/batch-update-conda-forge.sh
@@ -27,11 +27,14 @@ case $1 in
 	7)
 		packages=("bob.learn.em" "bob.db.iris")
 		;;
+	8)
+		packages=("bob")
+		;;
 esac
 
 
 for pkg in "${packages[@]}"
 do
 	gh re --fork $pkg-feedstock --user conda-forge --organization bioidiap || true
-	python update_feedstock.py $pkg
+	python ../gitlab/update_feedstock.py $pkg
 done
diff --git a/conda/update_feedstock.py b/conda/update_feedstock.py
deleted file mode 100755
index 1357ba390afa24573f9be367407c580ab4b2c2ce..0000000000000000000000000000000000000000
--- a/conda/update_feedstock.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python
-
-import hashlib
-import urllib.request
-import requests
-import json
-try:
-    from packaging.version import parse
-except ImportError:
-    from pip._vendor.packaging.version import parse
-import re
-import tempfile
-import shutil
-import os
-import subprocess
-
-URL_PATTERN = 'https://pypi.python.org/pypi/{package}/json'
-
-
-def run_commands(*calls):
-  """runs the given commands."""
-  # get all calls
-  for call in calls:
-    if True or False:
-      print(' - ' + ' '.join(call))
-    if not False:
-      # execute call
-      if subprocess.call(call):
-        # call failed (has non-zero exit status)
-        raise ValueError("Command '%s' failed; stopping" % ' '.join(call))
-
-
-def get_version(package, url_pattern=URL_PATTERN):
-  """Return version of package on pypi.python.org using json."""
-  # reader = codecs.getreader("utf-8")
-  req = requests.get(url_pattern.format(package=package))
-  version = parse('0')
-  if req.status_code == requests.codes.ok:
-    # j = json.loads(req.text.encode(req.encoding))
-    j = json.loads(req.text)
-    if 'releases' in j:
-      releases = j['releases']
-      for release in releases:
-        ver = parse(release)
-        if not ver.is_prerelease:
-          version = max(version, ver)
-  return str(version)
-
-
-def get_remote_md5_sum(url, max_file_size=100 * 1024 * 1024):
-  remote = urllib.request.urlopen(url)
-  hash = hashlib.md5()
-
-  total_read = 0
-  while True:
-    data = remote.read(4096)
-    total_read += 4096
-
-    if not data or total_read > max_file_size:
-      break
-
-    hash.update(data)
-
-  return hash.hexdigest()
-
-
-def main(package):
-  stable_version = get_version(package)
-  print('latest stable version for {} is {}'.format(package, stable_version))
-  url = 'https://pypi.io/packages/source/{0}/{1}/{1}-{2}.zip'.format(package[0], package, stable_version)
-  try:
-    md5 = get_remote_md5_sum(url)
-  except Exception:
-      raise
-  temp_dir = tempfile.mkdtemp()
-  try:
-    print("\nClonning the feedstock")
-    feedstock = os.path.join(temp_dir, '{}-feedstock'.format(package))
-    try:
-      run_commands(['git', 'clone', 'git@github.com:conda-forge/{}-feedstock.git'.format(package), feedstock])
-    except ValueError:
-      print("\nThe feedstock does not exist on conda-forge. Exiting ...")
-      raise
-    os.chdir(feedstock)
-    run_commands(['git', 'remote', 'add', 'bioidiap', 'git@github.com:bioidiap/{}-feedstock.git'.format(package)],
-                 # ['git', 'fetch', '--all'],
-                 ['git', 'checkout', '-b', stable_version])
-    # update meta.yaml
-    with open('recipe/meta.yaml') as f:
-      doc = f.read()
-    if package == 'bob.math':
-      build_number = '200'
-    else:
-      build_number = '0'
-    doc = re.sub(r'\{\s?%\s?set\s?version\s?=\s?".*"\s?%\s?\}', '{% set version = "' + str(stable_version) + '" %}', doc, count=1)
-    doc = re.sub(r'\s+number\:\s?[0-9]+', '\n  number: ' + build_number, doc, count=1)
-    doc = re.sub(r'\{\s?%\s?set\s?build_number\s?=\s?"[0-9]+"\s?%\s?\}', '{% set build_number = "' + build_number + '" %}', doc, count=1)
-    doc = re.sub(r'\s+md5\:.*', '\n  md5: {}'.format(md5), doc, count=1)
-    doc = re.sub(r'\s+url\:.*', '\n  url: {}'.format(url.replace(stable_version, '{{ version }}')), doc, count=1)
-    doc = re.sub(r'\s+home\:.*', '\n  home: https://www.idiap.ch/software/bob/', doc, count=1)
-    with open('recipe/meta.yaml', 'w') as f:
-      f.write(doc)
-    run_commands(['conda-smithy', 'rerender'],
-                 ['git', '--no-pager', 'diff'],
-                 ['git', 'add', '-A'],
-                 ['git', 'commit', '-am', 'Update to version {}'.format(stable_version)],
-                 ['git', 'push', '--force', '--set-upstream', 'bioidiap', stable_version],
-                 ['hub', 'pull-request', '--browse', '-b', 'conda-forge:master', '-h', 'bioidiap:{}'.format(stable_version), '-m', 'Update to version {}'.format(stable_version)])
-    print('\nPlease create the pull request in the webpage that was openned.')
-  finally:
-    shutil.rmtree(temp_dir)
-
-
-if __name__ == '__main__':
-  import sys
-  main(*sys.argv[1:])
diff --git a/gitlab/deploy.sh b/gitlab/deploy.sh
index 9ad085cfd97b999ab6e4692d50a82b2db69cce1d..34b1ca2372e35333c200e5188de5c57fd133f73c 100755
--- a/gitlab/deploy.sh
+++ b/gitlab/deploy.sh
@@ -20,3 +20,40 @@ if [ -d sphinx ]; then
 fi
 
 unlock_pypirc
+
+condaforge_packages=("bob" \
+"bob.extension" \
+"bob.blitz" \
+"bob.core" \
+"bob.ip.draw" \
+"bob.io.base" \
+"bob.sp" \
+"bob.math" \
+"bob.ap" \
+"bob.measure" \
+"bob.db.base" \
+"bob.io.image" \
+"bob.io.video" \
+"bob.io.matlab" \
+"bob.ip.base" \
+"bob.ip.color" \
+"bob.ip.gabor" \
+"bob.learn.activation" \
+"bob.learn.libsvm" \
+"bob.learn.boosting" \
+"bob.io.audio" \
+"bob.learn.linear" \
+"bob.learn.mlp" \
+"bob.db.wine" \
+"bob.db.mnist" \
+"bob.db.atnt" \
+"bob.ip.flandmark" \
+"bob.ip.facedetect" \
+"bob.ip.optflow.hornschunck" \
+"bob.ip.optflow.liu" \
+"bob.learn.em" \
+"bob.db.iris")
+
+if contains_element ${CI_PROJECT_NAME}  "${condaforge_packages[@]}"; then
+  run_cmd ${CONDA_FOLDER}/bin/python _ci/update_feedstock.py ${CI_PROJECT_NAME}
+fi
diff --git a/gitlab/functions.sh b/gitlab/functions.sh
index ea4640d903728b71eb493dd16ae4d0c6f55ca758..e82893c3b1e9213ea7a833b1d4e9be1cf14325d4 100644
--- a/gitlab/functions.sh
+++ b/gitlab/functions.sh
@@ -246,3 +246,10 @@ if [ -z "${CI_BUILD_TAG}" ]; then
 else
   log_info "Building tag, not setting BOB_DOCUMENTATION_SERVER"
 fi
+
+# taken from here: https://stackoverflow.com/questions/3685970/check-if-an-array-contains-a-value
+contains_element () {
+  local e
+  for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
+  return 1
+}
diff --git a/gitlab/install.sh b/gitlab/install.sh
index 07c0cb52c931836d4800d3a402adf71dbf25c8d8..8adb34b7f3cebf8ad4ab118feaefe90726231282 100755
--- a/gitlab/install.sh
+++ b/gitlab/install.sh
@@ -57,3 +57,4 @@ for stage in "build" "test" "docs" "wheels" "deploy"; do
   get_exec ${1} ${stage}.sh
   get_exec ${1} after_${stage}.sh
 done
+get_exec ${1} update_feedstock.py
diff --git a/gitlab/update_feedstock.py b/gitlab/update_feedstock.py
new file mode 100755
index 0000000000000000000000000000000000000000..a0c1df579858dcae6ab0521d0a8ebc2d08ebfeae
--- /dev/null
+++ b/gitlab/update_feedstock.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+
+import hashlib
+try:
+  from urllib2 import urlopen
+except ImportError:
+  from urllib.request import urlopen
+import requests
+import json
+try:
+    from packaging.version import parse
+except ImportError:
+    from pip._vendor.packaging.version import parse
+import re
+import tempfile
+import shutil
+import os
+import subprocess
+
+URL_PATTERN = 'https://pypi.python.org/pypi/{package}/json'
+
+
+def run_commands(*calls):
+  """runs the given commands."""
+  # get all calls
+  for call in calls:
+    print(' - ' + ' '.join(call))
+    # execute call
+    if subprocess.call(call):
+      # call failed (has non-zero exit status)
+      raise ValueError("Command '%s' failed; stopping" % ' '.join(call))
+
+
+def get_version(package, url_pattern=URL_PATTERN):
+  """Return version of package on pypi.python.org using json."""
+  req = requests.get(url_pattern.format(package=package))
+  version = parse('0')
+  if req.status_code == requests.codes.ok:
+    j = json.loads(req.text)
+    if 'releases' in j:
+      releases = j['releases']
+      for release in releases:
+        ver = parse(release)
+        if not ver.is_prerelease:
+          version = max(version, ver)
+  return str(version)
+
+
+def get_remote_md5_sum(url, max_file_size=100 * 1024 * 1024):
+  remote = urlopen(url)
+  hash = hashlib.md5()
+
+  total_read = 0
+  while True:
+    data = remote.read(4096)
+    total_read += 4096
+
+    if not data or total_read > max_file_size:
+      break
+    hash.update(data)
+
+  return hash.hexdigest()
+
+
+def main(package, direct_push=False):
+  stable_version = get_version(package)
+  print('latest stable version for {} is {}'.format(package, stable_version))
+  url = 'https://pypi.io/packages/source/{0}/{1}/{1}-{2}.zip'.format(
+    package[0], package, stable_version)
+  try:
+    md5 = get_remote_md5_sum(url)
+  except Exception:
+      raise
+  temp_dir = tempfile.mkdtemp()
+  try:
+    print("\nClonning the feedstock")
+    feedstock = os.path.join(temp_dir, '{}-feedstock'.format(package))
+    try:
+      run_commands(
+        ['git', 'clone',
+         'git@github.com:conda-forge/{}-feedstock.git'.format(package),
+         feedstock])
+    except ValueError:
+      print("\nThe feedstock does not exist on conda-forge. Exiting ...")
+      raise
+    os.chdir(feedstock)
+    if not direct_push:
+      run_commands(
+        ['git', 'remote', 'add', 'bioidiap',
+         'git@github.com:bioidiap/{}-feedstock.git'.format(package)],
+        ['git', 'checkout', '-b', stable_version])
+    # update meta.yaml
+    with open('recipe/meta.yaml') as f:
+      doc = f.read()
+    if package == 'bob.math':
+      build_number = '200'
+    else:
+      build_number = '0'
+    doc = re.sub(r'\{\s?%\s?set\s?version\s?=\s?".*"\s?%\s?\}',
+                 '{% set version = "' + str(stable_version) + '" %}',
+                 doc, count=1)
+    doc = re.sub(r'\s+number\:\s?[0-9]+', '\n  number: ' + build_number, doc,
+                 count=1)
+    doc = re.sub(r'\{\s?%\s?set\s?build_number\s?=\s?"[0-9]+"\s?%\s?\}',
+                 '{% set build_number = "' + build_number + '" %}',
+                 doc, count=1)
+    doc = re.sub(r'\s+md5\:.*', '\n  md5: {}'.format(md5), doc, count=1)
+    doc = re.sub(r'\s+url\:.*',
+                 '\n  url: {}'.format(
+                  url.replace(stable_version, '{{ version }}')),
+                 doc, count=1)
+    doc = re.sub(r'\s+home\:.*',
+                 '\n  home: https://www.idiap.ch/software/bob/',
+                 doc, count=1)
+
+    if package == 'bob':
+      requrl = 'https://gitlab.idiap.ch/bob/bob/raw/master/requirements.txt'
+      remote = requests.get(requrl)
+      req = remote.content.decode()
+      req = '\n    - '.join(req.replace('== ', '==').strip().split('\n'))
+      be_id = doc.find('bob.extension')
+      te_id = doc.find('test:\n', be_id)
+      template = '''{req}
+
+  run:
+    - python
+    - {req}
+
+'''.format(req=req)
+      doc = doc[:be_id] + template + doc[te_id:]
+
+    with open('recipe/meta.yaml', 'w') as f:
+      f.write(doc)
+
+    run_commands(['conda-smithy', 'rerender'],
+                 ['git', '--no-pager', 'diff'],
+                 ['git', 'add', '-A'])
+    try:
+      run_commands(['git', 'commit', '-am',
+                    'Fix badges [skip ci]'])
+                    # 'Update to version {}'.format(stable_version)])
+    except ValueError:
+      print('Feedstock is already uptodate, skipping.')
+      return
+    if direct_push:
+      print(feedstock)
+      try:
+        answer = raw_input('Would you like to push directly to master?').lower()
+      except Exception:
+        answer = input('Would you like to push directly to master?').lower()
+      if answer.startswith('y') or answer == '':
+        run_commands(['git', 'push'])
+        print('See the changes at:\n'
+              'https://github.com/conda-forge/'
+              '{}-feedstock/commits/master\n\n'.format(package))
+    else:
+      run_commands(['git', 'push', '--force', '--set-upstream',
+                    'bioidiap', stable_version],
+                   ['hub', 'pull-request', '-b', 'conda-forge:master',
+                    '-h', 'bioidiap:{}'.format(stable_version),
+                    '-m', 'Update to version {}'.format(stable_version)])
+  finally:
+    shutil.rmtree(temp_dir)
+
+
+if __name__ == '__main__':
+  import sys
+  pkg = sys.argv[1]
+  main(pkg)
diff --git a/install/install-conda.sh b/install/install-conda.sh
index 80d6fb064fd47ad9f44ac1ba49aeb8c2e0143dbe..f87a79302be69274c281de0afc80eab1ba7f055e 100755
--- a/install/install-conda.sh
+++ b/install/install-conda.sh
@@ -34,3 +34,8 @@ fi
 
 echo "[>>] Updating conda in the root environment..."
 ${CONDA} update --yes -n root conda
+
+echo "[>>] Installing conda-smithy..."
+${CONDA} install --yes -n root conda-smithy
+
+echo "You need to manually install https://hub.github.com/ too ..."