For private repositories, as well as projects where we still cannot use Travis, we rent (from ProcoliX) an externally-hosted Jenkins machine. We build the ROOT matrix using a Docker image ready with the Developer Toolset (v2), cmake, and Anaconda installed. The build is triggered whenever there is a push in the conda recipes repository (configurable). The following is used to run the ROOT builds:

docker run --rm -i -e CONDA_PY -e ROOT -e MYUID=1001 -v $PWD:/code nlesc/slc6-devtoolset-anaconda /code/

where is an executable which contains the conda build and upload commands, and CONDA_PY {2.7,3.4} and ROOT {5,6} are environment variables configured in the Jenkins build matrix. The setup is shown in the figure below:

Development and production ROOT packages

The github repository has two branches: master and upload. This is to avoid overwriting ROOT packages on the Anaconda cloud before testing them with pax. The basic Jenkins/Travis tests cover creating simple ROOT files and compiling STL dictionaries before uploading to Anaconda Cloud; however, there may be a need to do additional tests before deciding to put these ROOT packages in production. As mentioned, Anaconda provides the possibility to put different labels on packages (which would hide them from users who are only subscribed to the main channel), but one cannot upload two packages with the same "build string", with different labels. For this reason, the ROOT recipes in the master branch are just slightly different: they have "_test" appended to the build string (see meta.yaml).

$ git diff upload master root5/meta.yaml
diff --git a/root5/meta.yaml b/root5/meta.yaml
index ddcd544..9048370 100644
--- a/root5/meta.yaml
+++ b/root5/meta.yaml
@@ -12,9 +12,9 @@ source:
-    string: py{{ environ.get('PY_VER','') }}_clang503 # [osx]
-    string: py{{ environ.get('PY_VER','') }}_gcc4.8.2 # [linux]
+    string: py{{ environ.get('PY_VER','') }}_clang503_test # [osx]
+    string: py{{ environ.get('PY_VER','') }}_gcc4.8.2_test # [linux]
     detect_binary_files_with_prefix: True

In addition, the of the master branch uploads them to the dev channel instead of the main one.

$ git diff upload master
diff --git a/ b/
index 925ef7f..d1c2144 100755
--- a/
+++ b/
@@ -8,9 +8,9 @@ else
-        echo "Uploading to Anaconda cloud...."
+        echo "Uploading to Anaconda cloud, dev channel...."
-        anaconda -v -t $ANACONDA_TOKEN upload $PWD/conda-bld/*/root-$ROOT*.tar.bz2 --force
+        anaconda -v -t $ANACONDA_TOKEN upload $PWD/conda-bld/*/root-$ROOT*.tar.bz2 --force --channel dev

The Jenkins job sends a mail to committers with a compressed build log when the build fails or is unstable. When you have verified that the ROOT binaries from the dev channel are good, you can commit the recipe changes in the upload branch. This will overwrite the existing ROOT binaries in the main channel on the cloud.