Skip to content

TST/CI: Split Circle workflow #2386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Feb 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
02607b8
TEST: Split Circle workflow
effigies Jan 20, 2018
700ba29
FIX: Remove setup_remote_docker from fetch/build
effigies Jan 20, 2018
c2b0ebc
CI: Build in serial, to reduce save/load steps
effigies Jan 20, 2018
ab1e6b5
CI: Add two tests in parallel
effigies Jan 20, 2018
34ea718
CI: Remove duplicate steps
effigies Jan 20, 2018
2c66278
CI: Full test suite
effigies Jan 20, 2018
7d7ff19
CI: Add explicit directory to source lines
effigies Jan 20, 2018
0dba542
CI: Install codecov on test jobs
effigies Jan 20, 2018
83a1530
CI: Use runtimes to regroup tests
effigies Jan 21, 2018
a5c8228
CI: Move to docker, attempt to use cache-from
effigies Jan 24, 2018
36e8f69
CI: Install dependencies
effigies Jan 24, 2018
49f7c69
REV: Restore 610e571
effigies Jan 25, 2018
b6932b3
CI: Build images in each job
effigies Jan 25, 2018
7e6760b
TEST: Move DARTEL to MultiProc
effigies Jan 25, 2018
1e9e541
CI: Split tests in config, for timing steps
effigies Jan 25, 2018
d0848ad
Remove old test script
effigies Jan 25, 2018
3cf0d76
CI: Re-add WORKDIR variable, timeouts
effigies Jan 25, 2018
98fd2c1
enh: use yaml pointers to reduce duplication
Feb 10, 2018
c1487e7
TEST: Set WORKDIR if WORKDIR unset
effigies Feb 14, 2018
d204848
CI: Move codecov into CI step
effigies Feb 14, 2018
e5be9ac
CI: Replace test_init with DOCKER_IMAGE, -ux
effigies Feb 14, 2018
60d822b
ENH: Move doc building, save artifacts
effigies Feb 14, 2018
e32cbcc
CI: Run codecov in WORKDIR
effigies Feb 14, 2018
a06530e
CI: Split coverage and smoke tests, un-quote asterisks
effigies Feb 14, 2018
a9c170a
CI: Do not save docker images pointlessly
effigies Feb 14, 2018
f28c479
CI: Store test results
effigies Feb 14, 2018
8982b27
CI: Update environment in attempt to bump codecov
effigies Feb 14, 2018
d424f91
CI: Attempt #2 setting PR number
effigies Feb 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
348 changes: 259 additions & 89 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,121 @@
_machine_kwds: &machine_kwds
image: circleci/classic:201710-02

_store_artifacts_kwds: &store_artifacts_kwds
path: /home/circleci/work/tests

_test_environment: &test_environment
WORKDIR: /home/circleci/work
DOCKER_IMAGE: "nipype/nipype"

_set_pr_number: &set_pr_number
name: Set PR number
command: |
echo 'export CIRCLE_PR_NUMBER="${CIRCLE_PR_NUMBER:-${CIRCLE_PULL_REQUEST##*/}}"' >> $BASH_ENV
source $BASH_ENV
echo $CIRCLE_PR_NUMBER

_generate_dockerfiles: &generate_dockerfiles
name: Generate Dockerfiles
command: |
make gen-dockerfiles

_modify_nipype_version: &modify_nipype_version
name: Modify Nipype version if necessary
command: |
if [ "$CIRCLE_TAG" != "" ]; then
sed -i -E "s/(__version__ = )'[A-Za-z0-9.-]+'/\1'$CIRCLE_TAG'/" nipype/info.py
fi

_get_base_image: &get_base_image
name: Get base image (pull or build)
no_output_timeout: 60m
command: |
source /tmp/docker/get_base_image.sh
if [ "$GET_BASE" == "PULL" ]; then
echo "Pulling base image ..."
docker pull nipype/nipype:base
elif [ "$GET_BASE" == "BUILD" ]; then
e=1 && for i in {1..5}; do
docker build -t nipype/nipype:base - < docker/Dockerfile.base && e=0 && break || sleep 15
done && [ "$e" -eq "0" ]
else
echo "Error: method to get base image not understood"
exit 1
fi

_build_main_image_py36: &build_main_image_py36
name: Build main image (py36)
no_output_timeout: 60m
command: |
e=1 && for i in {1..5}; do
docker build \
--rm=false \
--tag nipype/nipype:latest \
--tag nipype/nipype:py36 \
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--build-arg VCS_REF="$(git rev-parse --short HEAD)" \
--build-arg VERSION="${CIRCLE_TAG}" /home/circleci/nipype \
&& e=0 && break || sleep 15
done && [ "$e" -eq "0" ]

_build_main_image_py27: &build_main_image_py27
name: Build main image (py27)
no_output_timeout: 60m
command: |
e=1 && for i in {1..5}; do
docker build \
--rm=false \
--tag nipype/nipype:py27 \
--build-arg PYTHON_VERSION_MAJOR=2 \
--build-arg PYTHON_VERSION_MINOR=7 \
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--build-arg VCS_REF="$(git rev-parse --short HEAD)" \
--build-arg VERSION="${CIRCLE_TAG}-py27" /home/circleci/nipype \
&& e=0 && break || sleep 15
done && [ "$e" -eq "0" ]

_download_test_data: &_download_test_data
name: Download test data
no_output_timeout: 20m
working_directory: /home/circleci/examples
environment:
OSF_NIPYPE_URL: "https://files.osf.io/v1/resources/nefdp/providers/osfstorage"
command: |
export DATA_NIPYPE_TUTORIAL_URL="${OSF_NIPYPE_URL}/57f4739cb83f6901ed94bf21"
curl -sSL --retry 5 --connect-timeout 15 "$DATA_NIPYPE_TUTORIAL_URL" | tar xj

export DATA_NIPYPE_FSL_COURSE="${OSF_NIPYPE_URL}/57f472cf9ad5a101f977ecfe"
curl -sSL --retry 5 --connect-timeout 15 "$DATA_NIPYPE_FSL_COURSE" | tar xz

export DATA_NIPYPE_FSL_FEEDS="${OSF_NIPYPE_URL}/57f473066c613b01f113e7af"
curl -sSL --retry 5 --connect-timeout 15 "$DATA_NIPYPE_FSL_FEEDS" | tar xz

_prepare_working_directory: &prepare_working_directory
name: Prepare working directory
environment: *test_environment
command: |
mkdir -p "$WORKDIR"
chmod -R 777 "$WORKDIR"

_get_codecov: &_get_codecov
name: Get codecov
command: |
pip install --no-cache-dir codecov

_run_codecov_coverage: &_run_codecov_coverage
name: Run codecov (coverage)
environment: *test_environment
command: |
codecov --file $WORKDIR/tests/coverage*.xml --root "$HOME/nipype" --flags unittests -e CIRCLE_JOB

_run_codecov_smoke: &_run_codecov_smoke
name: Run codecov (smoke tests)
environment: *test_environment
command: |
codecov --file $WORKDIR/tests/smoketest*.xml --root "$HOME/nipype" --flags smoketests -e CIRCLE_JOB


version: 2
jobs:

Expand Down Expand Up @@ -35,116 +153,156 @@ jobs:
- docker/Dockerfile.base-pruned
- docker/get_base_image.sh

test_pytest:
machine: *machine_kwds
working_directory: /home/circleci/nipype
steps:
- checkout:
path: /home/circleci/nipype
- attach_workspace:
at: /tmp
- run: *set_pr_number
- run: *generate_dockerfiles
- run: *modify_nipype_version
- run: *get_base_image
- run: *build_main_image_py36
- run: *build_main_image_py27
- run: *_get_codecov
- run: *_download_test_data
- run: *prepare_working_directory
- run:
name: Run pytests (py36)
no_output_timeout: 30m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_pytest.sh
- run:
name: Run pytests (py27)
no_output_timeout: 30m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py2_pytest.sh
- run: *_run_codecov_coverage
- store_artifacts: *store_artifacts_kwds
- store_test_results: *store_artifacts_kwds

build_and_test:
parallelism: 4
machine:
# Ubuntu 14.04 with Docker 17.10.0-ce
image: circleci/classic:201710-02
test_py3_fmri_fsl_spm:
machine: *machine_kwds
working_directory: /home/circleci/nipype
steps:
- checkout:
path: /home/circleci/nipype
- attach_workspace:
at: /tmp
- run: *set_pr_number
- run: *generate_dockerfiles
- run: *modify_nipype_version
- run: *get_base_image
- run: *build_main_image_py36
- run: *_get_codecov
- run: *_download_test_data
- run: *prepare_working_directory
- run:
name: Get test dependencies and generate Dockerfiles
command: |
pip install --no-cache-dir codecov
make gen-dockerfiles
name: Run FSL FEEDS pipeline (py36)
no_output_timeout: 40m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_fsl_feeds_linear_l1.sh
- run:
name: Modify Nipype version if necessary
command: |
if [ "$CIRCLE_TAG" != "" ]; then
sed -i -E "s/(__version__ = )'[A-Za-z0-9.-]+'/\1'$CIRCLE_TAG'/" nipype/info.py
fi
name: Run FSL reuse pipeline (py36)
no_output_timeout: 40m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_fsl_reuse_linear_l1.sh
- run:
name: Get base image (pull or build)
no_output_timeout: 60m
command: |
source /tmp/docker/get_base_image.sh
if [ "$GET_BASE" == "PULL" ]; then
echo "Pulling base image ..."
docker pull nipype/nipype:base
elif [ "$GET_BASE" == "BUILD" ]; then
e=1 && for i in {1..5}; do
docker build -t nipype/nipype:base - < docker/Dockerfile.base && e=0 && break || sleep 15
done && [ "$e" -eq "0" ]
else
echo "Error: method to get base image not understood"
exit 1
fi
name: Run SPM test workflow - 3D inputs (py36)
no_output_timeout: 40m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_spm_linear_3d.sh
- run:
name: Build main image (py36)
no_output_timeout: 60m
command: |
e=1 && for i in {1..5}; do
docker build \
--rm=false \
--tag nipype/nipype:latest \
--tag nipype/nipype:py36 \
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--build-arg VCS_REF="$(git rev-parse --short HEAD)" \
--build-arg VERSION="${CIRCLE_TAG}" /home/circleci/nipype \
&& e=0 && break || sleep 15
done && [ "$e" -eq "0" ]
- run:
name: Build main image (py27)
no_output_timeout: 60m
command: |
e=1 && for i in {1..5}; do
docker build \
--rm=false \
--tag nipype/nipype:py27 \
--build-arg PYTHON_VERSION_MAJOR=2 \
--build-arg PYTHON_VERSION_MINOR=7 \
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--build-arg VCS_REF="$(git rev-parse --short HEAD)" \
--build-arg VERSION="${CIRCLE_TAG}-py27" /home/circleci/nipype \
&& e=0 && break || sleep 15
done && [ "$e" -eq "0" ]
- run:
name: Download test data
no_output_timeout: 20m
working_directory: /home/circleci/examples
environment:
OSF_NIPYPE_URL: "https://files.osf.io/v1/resources/nefdp/providers/osfstorage"
command: |
export DATA_NIPYPE_TUTORIAL_URL="${OSF_NIPYPE_URL}/57f4739cb83f6901ed94bf21"
curl -sSL --retry 5 --connect-timeout 15 "$DATA_NIPYPE_TUTORIAL_URL" | tar xj
name: Run SPM test workflow - 4D inputs (py36)
no_output_timeout: 40m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_spm_linear_4d.sh
- run: *_run_codecov_smoke
- store_artifacts: *store_artifacts_kwds

export DATA_NIPYPE_FSL_COURSE="${OSF_NIPYPE_URL}/57f472cf9ad5a101f977ecfe"
curl -sSL --retry 5 --connect-timeout 15 "$DATA_NIPYPE_FSL_COURSE" | tar xz
test_py3_fmri_spm_dartel_multiproc:
machine: *machine_kwds
working_directory: /home/circleci/nipype
steps:
- checkout:
path: /home/circleci/nipype
- attach_workspace:
at: /tmp
- run: *set_pr_number
- run: *generate_dockerfiles
- run: *modify_nipype_version
- run: *get_base_image
- run: *build_main_image_py36
- run: *_get_codecov
- run: *_download_test_data
- run: *prepare_working_directory
- run:
name: Run SPM DARTEL Level 1 pipeline (py36)
no_output_timeout: 1h
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_spm_dartel_multiproc_l1.sh
- run:
name: Run SPM DARTEL Level 2 pipeline (py36)
no_output_timeout: 30m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_spm_dartel_multiproc_l2.sh
- run: *_run_codecov_smoke
- store_artifacts: *store_artifacts_kwds

export DATA_NIPYPE_FSL_FEEDS="${OSF_NIPYPE_URL}/57f473066c613b01f113e7af"
curl -sSL --retry 5 --connect-timeout 15 "$DATA_NIPYPE_FSL_FEEDS" | tar xz
test_fmri_spm_nested_multiproc:
machine: *machine_kwds
working_directory: /home/circleci/nipype
steps:
- checkout:
path: /home/circleci/nipype
- attach_workspace:
at: /tmp
- run: *set_pr_number
- run: *generate_dockerfiles
- run: *modify_nipype_version
- run: *get_base_image
- run: *build_main_image_py36
- run: *build_main_image_py27
- run: *_get_codecov
- run: *_download_test_data
- run: *prepare_working_directory
- run:
name: Run tests
no_output_timeout: 4h
environment:
WORKDIR: /home/circleci/work
command: |
mkdir -p "$WORKDIR"
chmod -R 777 "$WORKDIR"
bash /home/circleci/nipype/.circleci/tests.sh
name: Run SPM Nested Level 1 pipeline (py36)
no_output_timeout: 1h
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_fmri_spm_nested_multiproc_l1.sh
- run:
name: Run SPM Nested Level 2 pipeline (py27)
no_output_timeout: 30m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py2_fmri_spm_nested_multiproc_l2.sh
- run: *_run_codecov_smoke
- store_artifacts: *store_artifacts_kwds
- run:
name: Build docs (py36)
no_output_timeout: 30m
environment: *test_environment
command: bash -ux /home/circleci/nipype/.circleci/test_py3_docs.sh
- store_artifacts:
path: /home/circleci/work/tests
path: /home/circleci/work/docs
- run:
name: Save Docker images to workspace
name: Save Docker images to workspace if on master
no_output_timeout: 60m
command: |
if [ "$CIRCLE_NODE_INDEX" -eq "0" ] && [ "$CIRCLE_BRANCH" == "master" ]; then
if [ "$CIRCLE_BRANCH" = "master" -a -z "$CIRCLE_PULL_REQUEST" ]; then
docker save nipype/nipype:base \
nipype/nipype:latest \
nipype/nipype:py36 \
nipype/nipype:py27 | gzip -1 > /tmp/docker/nipype-base-latest-py36-py27.tar.gz
du -h /tmp/docker/nipype-base-latest-py36-py27.tar.gz
nipype/nipype:py27 \
nipype/nipype:py36 | gzip -1 > /tmp/docker/nipype-base-latest-py36-py27.tar.gz \
&& du -h /tmp/docker/nipype-base-latest-py36-py27.tar.gz
fi
- persist_to_workspace:
root: /tmp
paths:
- docker/*

- docker

deploy:
docker:
Expand Down Expand Up @@ -180,15 +338,27 @@ jobs:

workflows:
version: 2
build_test_deply:
build_test_deploy:
jobs:
- compare_base_dockerfiles
- build_and_test:
- test_pytest:
requires:
- compare_base_dockerfiles
- test_py3_fmri_fsl_spm:
requires:
- compare_base_dockerfiles
- test_py3_fmri_spm_dartel_multiproc:
requires:
- compare_base_dockerfiles
- test_fmri_spm_nested_multiproc:
requires:
- compare_base_dockerfiles
- deploy:
filters:
branches:
only: master
requires:
- build_and_test
- test_pytest
- test_fmri_spm_nested_multiproc
- test_py3_fmri_fsl_spm
- test_py3_fmri_spm_dartel_multiproc
3 changes: 3 additions & 0 deletions .circleci/test_py2_fmri_spm_nested_multiproc_l2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker run --rm=false -t -v $WORKDIR:/work -v $HOME/examples:/data/examples:ro -w /work -e NIPYPE_NUMBER_OF_CPUS=4 -e NIPYPE_RESOURCE_MONITOR=1 "${DOCKER_IMAGE}:py27" /usr/bin/run_examples.sh fmri_spm_nested MultiProc /data/examples/ l2pipeline
Loading