Skip to content

Commit 0c2ad9f

Browse files
authored
Merge pull request #284 from effigies/chore/relax-deps
chore: Relax dependencies to numpy 2.0 compatibility
2 parents 5c52e2b + 3df8641 commit 0c2ad9f

File tree

4 files changed

+59
-199
lines changed

4 files changed

+59
-199
lines changed

.circleci/config.yml

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,19 @@ jobs:
1010

1111
steps:
1212
- checkout
13-
- restore_cache:
14-
keys:
15-
- env-v6-{{ .Branch }}-
16-
- env-v6-master-
17-
- env-v6-
13+
- run:
14+
name: Ensure uv is present
15+
command: uv -V || curl -LsSf https://astral.sh/uv/install.sh | sh
1816
- run:
1917
name: Setup git-annex
2018
command: |
21-
sudo apt update && sudo apt-get install apt-transport-https ca-certificates -y && sudo update-ca-certificates
22-
if [[ ! -d /opt/circleci/git-annex.linux ]]; then
23-
cd /tmp
24-
wget https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
25-
tar xzf git-annex-standalone-amd64.tar.gz -C /opt/circleci/
26-
fi
19+
uv tool install git-annex
2720
git config --global user.name 'NiPy'
2821
git config --global user.email 'nipreps@gmail.com'
2922
- run:
3023
name: Setup DataLad
3124
command: |
32-
python3 -m pip install --no-cache-dir -U pip "setuptools >= 45.0" "setuptools_scm[toml] >= 6.2"
33-
python3 -m pip install --no-cache-dir -U datalad datalad-osf
34-
35-
- save_cache:
36-
key: env-v6-{{ .Branch }}-{{ .BuildNum }}
37-
paths:
38-
- /opt/circleci/git-annex.linux
39-
- /opt/circleci/.pyenv/versions
25+
uv tool install --with-executables-from=datalad-osf,datalad-next datalad
4026
4127
- restore_cache:
4228
keys:
@@ -46,9 +32,6 @@ jobs:
4632
- run:
4733
name: Install test data from GIN
4834
command: |
49-
export PATH=/opt/circleci/git-annex.linux:$PATH
50-
pyenv local 3
51-
eval "$(pyenv init --path)"
5235
mkdir -p /tmp/data
5336
cd /tmp/data
5437
datalad install -r https://gin.g-node.org/oesteban/nitransforms-tests
@@ -61,10 +44,10 @@ jobs:
6144

6245
- restore_cache:
6346
keys:
64-
- build-v1-{{ .Branch }}-{{ epoch }}
65-
- build-v1-{{ .Branch }}-
66-
- build-v1-master-
67-
- build-v1-
47+
- build-v2-{{ .Branch }}-{{ epoch }}
48+
- build-v2-{{ .Branch }}-
49+
- build-v2-master-
50+
- build-v2-
6851
paths:
6952
- /tmp/docker
7053
- run:
@@ -81,13 +64,13 @@ jobs:
8164
set -e
8265
if [[ "$success" = "0" ]]; then
8366
echo "Pulling from local registry"
84-
docker tag localhost:5000/ubuntu ubuntu:xenial-20200114
67+
docker tag localhost:5000/ubuntu ubuntu:jammy-20250730
8568
docker pull localhost:5000/nitransforms
8669
docker tag localhost:5000/nitransforms nitransforms:latest
8770
else
8871
echo "Pulling from Docker Hub"
89-
docker pull ubuntu:xenial-20200114
90-
docker tag ubuntu:xenial-20200114 localhost:5000/ubuntu
72+
docker pull ubuntu:jammy-20250730
73+
docker tag ubuntu:jammy-20250730 localhost:5000/ubuntu
9174
docker push localhost:5000/ubuntu
9275
fi
9376
- run:
@@ -99,7 +82,7 @@ jobs:
9982
-t nitransforms:latest \
10083
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
10184
--build-arg VCS_REF=`git rev-parse --short HEAD` \
102-
--build-arg VERSION=$( python3 -m setuptools_scm ) . \
85+
--build-arg VERSION=$( uv run --no-project -w setuptools_scm -m setuptools_scm ) . \
10386
&& e=0 && break || sleep 15
10487
done && [ "$e" -eq "0" ]
10588
docker tag nitransforms:latest localhost:5000/nitransforms
@@ -110,13 +93,13 @@ jobs:
11093
docker exec -it registry /bin/registry garbage-collect --delete-untagged \
11194
/etc/docker/registry/config.yml
11295
- save_cache:
113-
key: build-v1-{{ .Branch }}-{{ epoch }}
96+
key: build-v2-{{ .Branch }}-{{ epoch }}
11497
paths:
11598
- /tmp/docker
11699
- run:
117100
name: Check version packaged in Docker image
118101
command: |
119-
THISVERSION=${CIRCLE_TAG:-$(python3 -m setuptools_scm)}
102+
THISVERSION=${CIRCLE_TAG:-$( uv run --no-project -w setuptools_scm -m setuptools_scm )}
120103
INSTALLED_VERSION=$(\
121104
docker run -it --rm --entrypoint=python nitransforms \
122105
-c 'import nitransforms as nit; print(nit.__version__, end="")' )
@@ -141,10 +124,11 @@ jobs:
141124
-w /src/nitransforms -v $PWD:/src/nitransforms \
142125
-v /tmp/data/nitransforms-tests:/data -e TEST_DATA_HOME=/data \
143126
-e COVERAGE_FILE=/tmp/coverage/.pytest.coverage \
144-
-v /tmp/fslicense/license.txt:/opt/freesurfer/license.txt:ro \
127+
-v /tmp/fslicense/license.txt:/usr/local/freesurfer/license.txt:ro \
145128
-v /tmp/tests:/tmp nitransforms:latest \
146129
pytest --junit-xml=/tmp/summaries/pytest.xml \
147130
--cov nitransforms --cov-report xml:/tmp/coverage/unittests.xml \
131+
-n auto \
148132
nitransforms/
149133
- run:
150134
name: Submit unit test coverage

Dockerfile

Lines changed: 32 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
# Ubuntu 22.04 LTS - Jammy
2-
ARG BASE_IMAGE=ubuntu:jammy-20240125
2+
ARG BASE_IMAGE=ubuntu:jammy-20250730
33

44
#
55
# Build wheel
66
#
7-
FROM python:slim AS src
8-
RUN pip install build
9-
RUN apt-get update && \
10-
apt-get install -y --no-install-recommends git
7+
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS src
8+
RUN apk add git
119
COPY . /src
12-
RUN python -m build /src
10+
RUN uv build --wheel /src
1311

1412
#
1513
# Download stages
1614
#
1715

1816
# Utilities for downloading packages
19-
FROM ${BASE_IMAGE} as downloader
17+
FROM ${BASE_IMAGE} AS downloader
2018
# Bump the date to current to refresh curl/certificates/etc
21-
RUN echo "2023.07.20"
19+
RUN echo "2025.09.25"
2220
RUN apt-get update && \
2321
apt-get install -y --no-install-recommends \
2422
binutils \
@@ -30,159 +28,79 @@ RUN apt-get update && \
3028

3129
RUN update-ca-certificates -f
3230

33-
# FreeSurfer 7.3.2
34-
FROM downloader as freesurfer
35-
COPY docker/files/freesurfer7.3.2-exclude.txt /usr/local/etc/freesurfer7.3.2-exclude.txt
36-
COPY docker/files/fs-cert.pem /usr/local/etc/fs-cert.pem
37-
RUN curl --cacert /usr/local/etc/fs-cert.pem \
38-
-sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/7.3.2/freesurfer-linux-ubuntu22_amd64-7.3.2.tar.gz \
39-
| tar zxv --no-same-owner -C /opt --exclude-from=/usr/local/etc/freesurfer7.3.2-exclude.txt
40-
41-
# AFNI
42-
FROM downloader as afni
43-
# Bump the date to current to update AFNI
44-
RUN echo "2023.07.20"
45-
RUN mkdir -p /opt/afni-latest \
46-
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
47-
| tar -xz -C /opt/afni-latest --strip-components 1 \
48-
--exclude "linux_openmp_64/*.gz" \
49-
--exclude "linux_openmp_64/funstuff" \
50-
--exclude "linux_openmp_64/shiny" \
51-
--exclude "linux_openmp_64/afnipy" \
52-
--exclude "linux_openmp_64/lib/RetroTS" \
53-
--exclude "linux_openmp_64/lib_RetroTS" \
54-
--exclude "linux_openmp_64/meica.libs" \
55-
# Keep only what we use
56-
&& find /opt/afni-latest -type f -not \( \
57-
-name "3dTshift" -or \
58-
-name "3dUnifize" -or \
59-
-name "3dAutomask" -or \
60-
-name "3dvolreg" -or \
61-
-name "3dNwarpApply" \
62-
\) -delete
63-
6431
# Micromamba
65-
FROM downloader as micromamba
66-
67-
# Install a C compiler to build extensions when needed.
68-
# traits<6.4 wheels are not available for Python 3.11+, but build easily.
69-
RUN apt-get update && \
70-
apt-get install -y --no-install-recommends build-essential && \
71-
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
32+
FROM downloader AS micromamba
7233

7334
WORKDIR /
7435
# Bump the date to current to force update micromamba
75-
RUN echo "2024.02.06"
36+
RUN echo "2025.09.05"
7637
RUN curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba
7738

7839
ENV MAMBA_ROOT_PREFIX="/opt/conda"
7940
COPY env.yml /tmp/env.yml
80-
# COPY requirements.txt /tmp/requirements.txt
8141
WORKDIR /tmp
8242
RUN micromamba create -y -f /tmp/env.yml && \
8343
micromamba clean -y -a
8444

8545
#
8646
# Main stage
8747
#
88-
FROM ${BASE_IMAGE} as nitransforms
48+
FROM ${BASE_IMAGE} AS nitransforms
8949

9050
# Configure apt
9151
ENV DEBIAN_FRONTEND="noninteractive" \
9252
LANG="en_US.UTF-8" \
9353
LC_ALL="en_US.UTF-8"
9454

95-
# Some baseline tools; bc is needed for FreeSurfer, so don't drop it
9655
RUN apt-get update && \
9756
apt-get install -y --no-install-recommends \
98-
bc \
99-
ca-certificates \
100-
curl \
101-
git \
102-
gnupg \
103-
lsb-release \
104-
netbase \
105-
xvfb && \
57+
libexpat1 \
58+
libgomp1 \
59+
&& \
10660
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
10761

108-
# Configure PPAs for libpng12 and libxp6
109-
RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
110-
&& GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/zeehio.gpg --recv 0xA1301338A3A48C4A \
111-
&& echo "deb [signed-by=/usr/share/keyrings/linuxuprising.gpg] https://ppa.launchpadcontent.net/linuxuprising/libpng12/ubuntu jammy main" > /etc/apt/sources.list.d/linuxuprising.list \
112-
&& echo "deb [signed-by=/usr/share/keyrings/zeehio.gpg] https://ppa.launchpadcontent.net/zeehio/libxp/ubuntu jammy main" > /etc/apt/sources.list.d/zeehio.list
113-
114-
# Dependencies for AFNI; requires a discontinued multiarch-support package from bionic (18.04)
115-
RUN apt-get update -qq \
116-
&& apt-get install -y -q --no-install-recommends \
117-
ed \
118-
gsl-bin \
119-
libglib2.0-0 \
120-
libglu1-mesa-dev \
121-
libglw1-mesa \
122-
libgomp1 \
123-
libjpeg62 \
124-
libpng12-0 \
125-
libxm4 \
126-
libxp6 \
127-
netpbm \
128-
tcsh \
129-
xfonts-base \
130-
xvfb \
131-
&& curl -sSL --retry 5 -o /tmp/multiarch.deb http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/multiarch-support_2.27-3ubuntu1.5_amd64.deb \
132-
&& dpkg -i /tmp/multiarch.deb \
133-
&& rm /tmp/multiarch.deb \
134-
&& apt-get install -f \
135-
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
136-
&& gsl2_path="$(find / -name 'libgsl.so.19' || printf '')" \
137-
&& if [ -n "$gsl2_path" ]; then \
138-
ln -sfv "$gsl2_path" "$(dirname $gsl2_path)/libgsl.so.0"; \
139-
fi \
140-
&& ldconfig
141-
142-
# Install files from stages
143-
COPY --from=freesurfer /opt/freesurfer /opt/freesurfer
144-
COPY --from=afni /opt/afni-latest /opt/afni-latest
62+
# Install FreeSurfer and AFNI bins from images
63+
COPY --from=freesurfer/freesurfer:7.4.1 \
64+
/usr/local/freesurfer/bin/mri_vol2vol \
65+
/usr/local/freesurfer/bin/
66+
COPY --from=afni/afni_make_build:AFNI_25.2.09 \
67+
/opt/afni/install/libf2c.so \
68+
/opt/afni/install/libmri.so \
69+
/usr/local/lib/
70+
COPY --from=afni/afni_make_build:AFNI_25.2.09 \
71+
/opt/afni/install/3dAllineate \
72+
/opt/afni/install/3dNwarpApply \
73+
/opt/afni/install/3dWarp \
74+
/opt/afni/install/3drefit \
75+
/opt/afni/install/3dvolreg \
76+
/usr/local/bin/
14577

14678
# Simulate SetUpFreeSurfer.sh
14779
ENV OS="Linux" \
14880
FS_OVERRIDE=0 \
14981
FIX_VERTEX_AREA="" \
15082
FSF_OUTPUT_FORMAT="nii.gz" \
151-
FREESURFER_HOME="/opt/freesurfer"
83+
FREESURFER_HOME="/usr/local/freesurfer"
15284
ENV SUBJECTS_DIR="$FREESURFER_HOME/subjects" \
15385
FUNCTIONALS_DIR="$FREESURFER_HOME/sessions" \
154-
MNI_DIR="$FREESURFER_HOME/mni" \
15586
LOCAL_DIR="$FREESURFER_HOME/local" \
156-
MINC_BIN_DIR="$FREESURFER_HOME/mni/bin" \
157-
MINC_LIB_DIR="$FREESURFER_HOME/mni/lib" \
158-
MNI_DATAPATH="$FREESURFER_HOME/mni/data"
159-
ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
160-
MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
161-
PATH="$FREESURFER_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"
87+
PATH="$FREESURFER_HOME/bin:$PATH"
16288

16389
# AFNI config
164-
ENV PATH="/opt/afni-latest:$PATH" \
165-
AFNI_IMSAVE_WARNINGS="NO" \
166-
AFNI_PLUGINPATH="/opt/afni-latest"
167-
168-
# Workbench config
169-
ENV PATH="/opt/workbench/bin_linux64:$PATH"
90+
ENV AFNI_IMSAVE_WARNINGS="NO"
17091

17192
# Create a shared $HOME directory
17293
RUN useradd -m -s /bin/bash -G users neuro
17394
WORKDIR /home/neuro
174-
ENV HOME="/home/neuro" \
175-
LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
95+
ENV HOME="/home/neuro"
17696

17797
COPY --from=micromamba /bin/micromamba /bin/micromamba
17898
COPY --from=micromamba /opt/conda/envs/nitransforms /opt/conda/envs/nitransforms
17999

180100
ENV MAMBA_ROOT_PREFIX="/opt/conda"
181101
RUN micromamba shell init -s bash && \
182102
echo "micromamba activate nitransforms" >> $HOME/.bashrc
183-
ENV PATH="/opt/conda/envs/nitransforms/bin:$PATH" \
184-
CPATH="/opt/conda/envs/nitransforms/include:$CPATH" \
185-
LD_LIBRARY_PATH="/opt/conda/envs/nitransforms/lib:$LD_LIBRARY_PATH"
103+
ENV PATH="/opt/conda/envs/nitransforms/bin:$PATH"
186104

187105
# FSL environment
188106
ENV LANG="C.UTF-8" \
@@ -196,22 +114,10 @@ ENV LANG="C.UTF-8" \
196114
FSLREMOTECALL="" \
197115
FSLGECUDAQ="cuda.q"
198116

199-
# Unless otherwise specified each process should only use one thread - nipype
200-
# will handle parallelization
201-
ENV MKL_NUM_THREADS=1 \
202-
OMP_NUM_THREADS=1
203-
204117
# Install package
205-
# CRITICAL: Make sure python setup.py --version has been run at least once
206-
# outside the container, with access to the git history.
207118
COPY --from=src /src/dist/*.whl .
208119
RUN python -m pip install --no-cache-dir $( ls *.whl )[all]
209120

210-
211-
RUN find $HOME -type d -exec chmod go=u {} + && \
212-
find $HOME -type f -exec chmod go=u {} + && \
213-
rm -rf $HOME/.npm $HOME/.conda $HOME/.empty
214-
215121
RUN ldconfig
216122
WORKDIR /tmp/
217123

0 commit comments

Comments
 (0)