From 3e4e7d393859c42fa1248e3493415848e5cbde66 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Tue, 6 Jun 2017 22:52:44 +0100 Subject: [PATCH] Newfangled experimental CI build specification. Not sure if it works --- .gitlab-ci.yml | 318 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 306 insertions(+), 12 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3d4d50520..9e3b11d59 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,17 +1,311 @@ -test:2.7: - image: fsleyes-py27 +########################################################################### +# This file defines the build process for fslpy, as hosted at: +# +# https://git.fmrib.ox.ac.uk/fsl/fslpy +# +# The build pipeline comprises four stages: +# +# 1. test: Unit tests +# +# 2. doc: Building API documentation +# +# 3. build: Building source distributions and wheels +# +# 4. deploy: Uploading the build outputs to pypi, and the documentation +# to a hosting server. +# +# The test stage is executed on all branches of upstream and fork +# repositories. +# +# The doc stage, and the deploy-doc job, is executed on all branches of the +# upstream repository. +# +# The build stage, and the remaining jobs in the deploy stage, are only +# executed on the upstream repository, and only for release tags. +# +# The deploy stages are manually instantiated. +########################################################################### + + +stages: + - test + - doc + - build + - deploy + + +############################################################################### +# A number of variables must be set for the jobs to work. The following +# variables are implicitly defined in any gitlab CI job: +# +# - CI_PROJECT_PATH - gitlab namespace/project +# - CI_COMMIT_REF_NAME - branch name, provided by gitlab +# - CI_COMMIT_TAG - present if build is running on a tag +# +# These variables must be explicitly set as "secret" variables: +# +# - SSH_PRIVATE_KEY_GIT - private key for git login to remote host +# +# - SSH_PRIVATE_KEY_DOC_DEPLOY - private key for rsyncing documentation +# to remote host +# +# - SSH_SERVER_HOSTKEYS - List of trusted SSH hosts +# +# - TWINE_PASSWORD: - Password to use when uploading to pypi +############################################################################### + + +variables: + UPSTREAM_PROJECT: "fsl/fslpy" + UPSTREAM_URL: "git@git.fmrib.ox.ac.uk" + DOC_HOST: "paulmc@jalapeno.fmrib.ox.ac.uk" + TWINE_USERNAME: "pauldmccarthy" + TWINE_REPOSITORY_URL: "https://testpypi.python.org/pypi" + + +#################################### +# These anchors are used to restrict +# when and where jobs are executed. +#################################### + + +.only_upstream: &only_upstream + only: + - branches@fsl/fslpy + + +.only_master: &only_master + only: + - master@fsl/fslpy + + +.only_releases: &only_releases + only: + - tags@fsl/fslpy + + +.except_releases: &except_releases + except: + - tags + + +########################################################## +# The setup_ssh anchor contains a before_script section +# which does the following: +# +# - Sets up key-based SSH login, and +# installs the private keys, so +# we can connect to servers. +# +# - Configures git, and adds the +# upstream repo as a remote +# +# (see https://docs.gitlab.com/ce/ci/ssh_keys/README.html) +# +# NOTE: It is assumed that non-docker +# executors are already configured +# (or don't need any configuration). +########################################################## + + +.setup_ssh: &setup_ssh + before_script: + + - if [[ -f /.dockerenv ]]; then + + apt-get update -y || yum -y check-update || true; + apt-get install -y openssh-client || yum install -y openssh-client || true; + apt-get install -y rsync || yum install -y rsync || true; + + eval $(ssh-agent -s); + mkdir -p $HOME/.ssh; + + echo "$SSH_PRIVATE_KEY_GIT" > $HOME/.ssh/id_git; + + if [[ "$CI_PROJECT_PATH" == "$UPSTREAM_PROJECT" ]]; then + echo "$SSH_PRIVATE_KEY_DOC_DEPLOY" > $HOME/.ssh/id_doc_deploy; + fi; + + chmod go-rwx $HOME/.ssh/id_*; + + ssh-add $HOME/.ssh/id_git; + + if [[ "$CI_PROJECT_PATH" == "$UPSTREAM_PROJECT" ]]; then + ssh-add $HOME/.ssh/id_doc_deploy; + fi; + + echo "$SSH_SERVER_HOSTKEYS" > $HOME/.ssh/known_hosts; + + touch $HOME/.ssh/config; + + echo "Host ${UPSTREAM_URL##*@}" >> $HOME/.ssh/config; + echo " User ${UPSTREAM_URL%@*}" >> $HOME/.ssh/config; + echo " IdentityFile ~/.ssh/id_git" >> $HOME/.ssh/config; + + echo "Host docdeploy" >> $HOME/.ssh/config; + echo " HostName ${DOC_HOST##*@}" >> $HOME/.ssh/config; + echo " User ${DOC_HOST%@*}" >> $HOME/.ssh/config; + echo " IdentityFile ~/.ssh/id_doc_deploy" >> $HOME/.ssh/config; + + echo "Host *" >> $HOME/.ssh/config; + echo " IdentitiesOnly yes" >> $HOME/.ssh/config; + + git config --global user.name "Gitlab CI"; + git config --global user.email "gitlabci@localhost"; + + if [[ `git remote -v` == *"upstream"* ]]; then + git remote remove upstream; + fi; + git remote add upstream "$UPSTREAM_URL:$UPSTREAM_PROJECT"; + fi + + +################################################### +# The patch_version anchor contains a before_script +# section which is run on release builds, and makes +# sure that the version in the code is up to date +# (i.e. equal to the tag name). +################################################### + + +.patch_version: &patch_version + before_script: + + - if [ -n ${CI_COMMIT_TAG+set} ]; then + python -c "import fsl.version as v; v.patchVersion('fsl/version.py', '$CI_COMMIT_REF_NAME')"; + fi + + +############ +# Test stage +############ + + +.test: &test_template + stage: test + <<: *setup_ssh + + # Releases are just tags on a release + # branch, so we don't need to test them. + <<: *except_releases + + tags: + - docker + script: - - cat requirements.txt | xargs -n 1 pip install - - pip install scipy - - pip install coverage + + # If running on a fork repository, we merge in the + # upstream/master branch. This is done so that merge + # requests from fork to the parent repository will + # have unit tests run on the merged code, something + # which gitlab CE does not currently do for us. + - if [[ "$CI_PROJECT_PATH" != "$UPSTREAM_PROJECT" ]]; then + git fetch upstream; + git merge --no-commit --no-ff upstream/master; + fi; + + # Linux builds for wxPython are currently + # not on pypi, but are available at this + # url. I am currently assuming that the + # test docker images are based on debian + # 8/jessie. + - pip install -f https://wxpython.org/Phoenix/release-extras/linux/gtk3/debian-8/ wxpython + + # All other deps can be installed as normal + - pip install -r requirements.txt - su -s /bin/bash -c "xvfb-run python setup.py test" nobody - coverage report -m -test:3.6: - image: fsleyes-py36 + +test:2.7: + <<: *test_template + image: python:2.7 + + +test:3.5: + <<: *test_template + image: python:3.5 + + +########### +# Doc stage +########### + +build-doc: + <<: *only_upstream + <<: *patch_version + + tags: + - docker + + stage: doc + image: python:3.5 + script: - - cat requirements.txt | xargs -n 1 pip install - - pip install scipy - - pip install coverage - - su -s /bin/bash -c "xvfb-run python setup.py test" nobody - - coverage report -m + - python setup.py doc + - mv doc/html doc/"$CI_COMMIT_REF_NAME" + artifacts: + paths: + - doc/$CI_COMMIT_REF_NAME + + +############# +# Build stage +############# + + +build-dist: + <<: *only_releases + <<: *patch_version + + stage: build + image: python:3.5 + + script: + - pip install wheel + - python setup.py sdist + - python setup.py bdist_wheel + + artifacts: + paths: + - dist/* + + +############## +# Deploy stage +############## + + +deploy-doc: + <<: *only_upstream + <<: *setup_ssh + stage: deploy + when: manual + + tags: + - docker + + dependencies: + - build-doc + + script: + - rsync -rv doc/"$CI_COMMIT_REF_NAME" "docdeploy:" + + +deploy-pypi: + <<: *only_releases + <<: *setup_ssh + stage: deploy + when: manual + image: python:3.5 + + tags: + - docker + + dependencies: + - build-dist + + script: + - pip install setuptools wheel twine + - ls dist/* + - echo "twine upload dist/*" -- GitLab