Skip to content

Commit 2b45086

Browse files
committed
MAINT: Optimize CI tests making Docker image lighter
This PR takes TemplateFlow's cache and FreeSurfer out of the Docker image. Now both are mounted at ``docker run`` time. Hopefully, we would be addressing two issues: - Caching issues (templateflow updates the checksum for every image built). - Docker image size (esp. removing FS but still using it, closes #46)
1 parent c781e6f commit 2b45086

File tree

2 files changed

+128
-165
lines changed

2 files changed

+128
-165
lines changed

.circleci/config.yml

Lines changed: 118 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,118 @@ docs_deploy: &docs
3434

3535
version: 2
3636
jobs:
37-
build:
37+
cache_test_data:
38+
docker:
39+
- image: python:3.7.4
40+
working_directory: /tmp/data
41+
environment:
42+
- TEMPLATEFLOW_HOME: /tmp/templateflow
43+
steps:
44+
- restore_cache:
45+
keys:
46+
- env-v1-{{ .Branch }}-
47+
- env-v1-master-
48+
- env-v1-
49+
- restore_cache:
50+
keys:
51+
- data-v2-{{ .Branch }}-
52+
- data-v2-master-
53+
- data-v2-
54+
55+
- run:
56+
name: Setup git-annex
57+
command: |
58+
mkdir -p /tmp/cache
59+
if [[ ! -e "/tmp/cache/git-annex-standalone.tar.gz" ]]; then
60+
wget -O- http://neuro.debian.net/lists/trusty.us-ca.full | sudo tee /etc/apt/sources.list.d/neurodebian.sources.list
61+
apt-key adv --recv-keys --keyserver hkp://pool.sks-keyservers.net:80 0xA5D32F012649A5A9
62+
apt update && sudo apt-get install -y --no-install-recommends git-annex-standalone
63+
mkdir -p /tmp/cache
64+
tar czvf /tmp/cache/git-annex-standalone.tar.gz /usr/bin/git-annex /usr/bin/git-annex-shell /usr/lib/git-annex.linux
65+
else
66+
tar xzfv /tmp/cache/git-annex-standalone.tar.gz -C /
67+
fi
68+
git config --global user.name 'CRN'
69+
git config --global user.email '[email protected]'
70+
71+
- run:
72+
name: Setup DataLad & TemplateFlow
73+
command: |
74+
python -m pip install --no-cache-dir -U pip
75+
python -m pip install --no-cache-dir -U datalad
76+
python -m pip install --no-cache-dir -U templateflow
77+
python -c "from templateflow import api as tfapi; \
78+
tfapi.get('MNI152NLin2009cAsym', resolution=2, desc='brain', suffix='mask'); \
79+
tfapi.get('MNI152NLin2009cAsym', resolution=2, desc='fMRIPrep', suffix='boldref');"
80+
- run:
81+
name: Install ds001600
82+
command: |
83+
datalad install https://github.com/OpenNeuroDatasets/ds001600.git
84+
datalad update --merge ds001600/
85+
datalad get -r ds001600/*
86+
- run:
87+
name: Get testdata
88+
command: |
89+
if [[ ! -d /tmp/data/testdata ]]; then
90+
wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
91+
-O testdata.zip "https://files.osf.io/v1/resources/9sy2a/providers/osfstorage/5d44b940bcd6d900198ed6be/?zip="
92+
unzip testdata.zip -d /tmp/data/testdata
93+
fi
94+
95+
- run:
96+
name: Pull FreeSurfer down
97+
command: |
98+
if [[ ! -d /tmp/freesurfer ]]; then
99+
curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.1/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.1.tar.gz | tar zxv --no-same-owner -C /tmp \
100+
--exclude='freesurfer/diffusion' \
101+
--exclude='freesurfer/docs' \
102+
--exclude='freesurfer/fsfast' \
103+
--exclude='freesurfer/lib/cuda' \
104+
--exclude='freesurfer/lib/qt' \
105+
--exclude='freesurfer/matlab' \
106+
--exclude='freesurfer/mni/share/man' \
107+
--exclude='freesurfer/subjects/fsaverage_sym' \
108+
--exclude='freesurfer/subjects/fsaverage3' \
109+
--exclude='freesurfer/subjects/fsaverage4' \
110+
--exclude='freesurfer/subjects/cvs_avg35' \
111+
--exclude='freesurfer/subjects/cvs_avg35_inMNI152' \
112+
--exclude='freesurfer/subjects/bert' \
113+
--exclude='freesurfer/subjects/lh.EC_average' \
114+
--exclude='freesurfer/subjects/rh.EC_average' \
115+
--exclude='freesurfer/subjects/sample-*.mgz' \
116+
--exclude='freesurfer/subjects/V1_average' \
117+
--exclude='freesurfer/trctrain'
118+
fi
119+
- run:
120+
name: Store FreeSurfer license file
121+
command: |
122+
echo "b2VzdGViYW5Ac3RhbmZvcmQuZWR1CjMwNzU2CiAqQ1MzYkJ5VXMxdTVNCiBGU2kvUGJsejJxR1V3Cg==" | base64 -d > /tmp/freesurfer/license.txt
123+
124+
- save_cache:
125+
key: env-v1-{{ .Branch }}-{{ .BuildNum }}
126+
paths:
127+
- /tmp/cache/git-annex-standalone.tar.gz
128+
129+
- save_cache:
130+
key: data-v2-{{ .Branch }}-{{ .BuildNum }}
131+
paths:
132+
- /tmp/data
133+
- /tmp/freesurfer
134+
- /tmp/templateflow
135+
136+
build_n_pytest:
38137
machine:
39138
image: circleci/classic:201711-01
40-
working_directory: /tmp/src/sdcflows
139+
working_directory: /tmp/tests
41140
environment:
42141
TZ: "/usr/share/zoneinfo/America/Los_Angeles"
43-
SCRATCH: "/scratch"
44142
steps:
45143
- restore_cache:
46144
keys:
47-
- build-v1-{{ .Branch }}-{{ epoch }}
48-
- build-v1-{{ .Branch }}-
49-
- build-v1-master-
50-
- build-v1-
145+
- build-v2-{{ .Branch }}-{{ epoch }}
146+
- build-v2-{{ .Branch }}-
147+
- build-v2-master-
148+
- build-v2-
51149
paths:
52150
- /tmp/docker
53151
- run:
@@ -75,11 +173,13 @@ jobs:
75173
docker push localhost:5000/ubuntu
76174
docker pull poldracklab/sdcflows:latest
77175
fi
78-
- checkout
176+
- checkout:
177+
path: /tmp/src/sdcflows
79178
- run:
80179
name: Build Docker image
81180
no_output_timeout: 60m
82181
command: |
182+
cd /tmp/src/sdcflows
83183
export PY3=$(pyenv versions | grep '3\.' |
84184
sed -e 's/.* 3\./3./' -e 's/ .*//')
85185
pyenv local $PY3
@@ -113,87 +213,15 @@ jobs:
113213
docker exec -it registry /bin/registry garbage-collect --delete-untagged \
114214
/etc/docker/registry/config.yml
115215
- save_cache:
116-
key: build-v1-{{ .Branch }}-{{ epoch }}
216+
key: build-v2-{{ .Branch }}-{{ epoch }}
117217
paths:
118218
- /tmp/docker
119-
- persist_to_workspace:
120-
root: /tmp
121-
paths:
122-
- src/sdcflows
123219

124-
cache_test_data:
125-
machine:
126-
image: circleci/classic:201711-01
127-
working_directory: /tmp/data
128-
steps:
129220
- restore_cache:
130221
keys:
131222
- data-v2-{{ .Branch }}-
132223
- data-v2-master-
133224
- data-v2-
134-
- run:
135-
name: Setup git-annex
136-
command: |
137-
mkdir -p /tmp/cache
138-
if [[ ! -e "/tmp/cache/git-annex-standalone.tar.gz" ]]; then
139-
wget -O- http://neuro.debian.net/lists/trusty.us-ca.full | sudo tee /etc/apt/sources.list.d/neurodebian.sources.list
140-
sudo apt-key adv --recv-keys --keyserver hkp://pool.sks-keyservers.net:80 0xA5D32F012649A5A9
141-
sudo apt update && sudo apt-get install -y --no-install-recommends git-annex-standalone
142-
mkdir -p /tmp/cache
143-
tar czvf /tmp/cache/git-annex-standalone.tar.gz /usr/bin/git-annex /usr/bin/git-annex-shell /usr/lib/git-annex.linux
144-
else
145-
sudo tar xzfv /tmp/cache/git-annex-standalone.tar.gz -C /
146-
fi
147-
git config --global user.name 'CRN'
148-
git config --global user.email '[email protected]'
149-
150-
- run:
151-
name: Setup DataLad
152-
command: |
153-
pyenv global 3.5.2
154-
virtualenv venv
155-
pip install --no-cache-dir -U pip
156-
pip install --no-cache-dir -U datalad
157-
- run:
158-
name: Install ds001600
159-
command: |
160-
datalad install https://github.com/OpenNeuroDatasets/ds001600.git
161-
datalad update --merge ds001600/
162-
datalad get -r ds001600/*
163-
- run:
164-
name: Get testdata
165-
command: |
166-
if [[ ! -d /tmp/data/testdata ]]; then
167-
wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
168-
-O testdata.zip "https://files.osf.io/v1/resources/9sy2a/providers/osfstorage/5d44b940bcd6d900198ed6be/?zip="
169-
unzip testdata.zip -d /tmp/data/testdata
170-
fi
171-
172-
- run:
173-
name: Store FreeSurfer license file
174-
command: |
175-
mkdir -p /tmp/data/
176-
echo "b2VzdGViYW5Ac3RhbmZvcmQuZWR1CjMwNzU2CiAqQ1MzYkJ5VXMxdTVNCiBGU2kvUGJsejJxR1V3Cg==" | base64 -d > /tmp/data/fslicense.txt
177-
178-
- save_cache:
179-
key: data-v2-{{ .Branch }}-{{ .BuildNum }}
180-
paths:
181-
- "/opt/circleci/.pyenv/versions/3.5.2"
182-
- /tmp/data
183-
- /tmp/cache/git-annex-standalone.tar.gz
184-
185-
- persist_to_workspace:
186-
root: /tmp
187-
paths:
188-
- data
189-
190-
test_sdcflows:
191-
machine:
192-
image: circleci/classic:201711-01
193-
working_directory: /tmp/tests
194-
steps:
195-
- attach_workspace:
196-
at: /tmp
197225
- restore_cache:
198226
keys:
199227
- workdir-v2-{{ .Branch }}-
@@ -225,32 +253,15 @@ jobs:
225253
echo "Found tag [wipe ${wipe_dir}] - clearing up $path ..."
226254
rm -rf ${path}
227255
fi
228-
- restore_cache:
229-
keys:
230-
- build-v1-{{ .Branch }}-{{ epoch }}
231-
- build-v1-{{ .Branch }}-
232-
- build-v1-master-
233-
- build-v1-
234-
paths:
235-
- /tmp/docker
236-
- run:
237-
name: Set-up a Docker registry
238-
command: |
239-
docker run -d -p 5000:5000 --restart=always --name=registry \
240-
-v /tmp/docker:/var/lib/registry registry:2
241-
- run:
242-
name: Pull images from local registry
243-
command: |
244-
docker pull localhost:5000/sdcflows
245-
docker tag localhost:5000/sdcflows poldracklab/sdcflows:latest
246256
- run:
247257
name: Run tests
248258
no_output_timeout: 2h
249259
command: |
250260
mkdir -p /tmp/work
251261
docker run -it --rm -e TEST_DATA_HOME=/data/ -e TEST_OUTPUT_DIR=/out \
252-
-v /tmp/data/fslicense.txt:/opt/freesurfer/license.txt:ro -e FS_LICENSE=/opt/freesurfer/license.txt \
262+
-v /tmp/freesurfer:/opt/freesurfer:ro -e FS_LICENSE=/opt/freesurfer/license.txt \
253263
-v /tmp/work:/work -e TEST_WORK_DIR=/work \
264+
-v /tmp/templateflow:/home/sdcflows/.cache/templateflow \
254265
-v /tmp/data:/data:ro -v /tmp/src:/src -v /tmp/tests:/out \
255266
-w /work poldracklab/sdcflows:latest \
256267
pytest -v --junit-xml=/out/pytest.xml /src/sdcflows/sdcflows
@@ -324,10 +335,10 @@ jobs:
324335
steps:
325336
- restore_cache:
326337
keys:
327-
- build-v1-{{ .Branch }}-{{ epoch }}
328-
- build-v1-{{ .Branch }}-
329-
- build-v1-master-
330-
- build-v1-
338+
- build-v2-{{ .Branch }}-{{ epoch }}
339+
- build-v2-{{ .Branch }}-
340+
- build-v2-master-
341+
- build-v2-
331342
paths:
332343
- /tmp/docker
333344
- run:
@@ -466,13 +477,6 @@ workflows:
466477
version: 2
467478
build_deploy:
468479
jobs:
469-
- build:
470-
filters:
471-
branches:
472-
ignore:
473-
- /docs?\/.*/
474-
tags:
475-
only: /.*/
476480
- cache_test_data:
477481
filters:
478482
branches:
@@ -481,9 +485,8 @@ workflows:
481485
tags:
482486
only: /.*/
483487

484-
- test_sdcflows:
488+
- build_n_pytest:
485489
requires:
486-
- build
487490
- cache_test_data
488491
filters:
489492
branches:
@@ -503,10 +506,9 @@ workflows:
503506

504507
- deploy_pypi:
505508
requires:
506-
- build
507509
- build_docs
508510
- test_package
509-
- test_sdcflows
511+
- build_n_pytest
510512
filters:
511513
branches:
512514
ignore: /.*/
@@ -527,14 +529,12 @@ workflows:
527529
branches:
528530
ignore:
529531
- /tests?\/.*/
530-
- /ds005\/.*/
531-
- /ds054\/.*/
532532
tags:
533533
only: /.*/
534534

535535
- deploy_docs_master:
536536
requires:
537-
- test_sdcflows
537+
- build_n_pytest
538538
- test_package
539539
- build_docs
540540
filters:

0 commit comments

Comments
 (0)