Skip to content

Commit ccdb58c

Browse files
authored
Merge pull request #782 from effigies/tox
Update CI to use build-and-inspect-python-package and tox-uv
2 parents 8280bd3 + 3569db6 commit ccdb58c

File tree

12 files changed

+236
-132
lines changed

12 files changed

+236
-132
lines changed

.coveragerc

Lines changed: 0 additions & 2 deletions
This file was deleted.

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ updates:
44
directory: /
55
schedule:
66
interval: weekly
7+
groups:
8+
actions-infrastructure:
9+
patterns:
10+
- "actions/*"

.github/workflows/ci-cd.yml

Lines changed: 68 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ on:
88
types: [published]
99
push:
1010
branches:
11-
- master
11+
- main
1212
pull_request:
13+
branches:
14+
- main
1315

1416
concurrency:
1517
group: ${{ github.workflow }}-${{ github.ref }}
@@ -18,75 +20,77 @@ concurrency:
1820
permissions:
1921
contents: read
2022

21-
jobs:
23+
env:
24+
# Force tox and pytest to use color
25+
FORCE_COLOR: true
2226

27+
jobs:
2328
build:
29+
name: Build & verify package
2430
runs-on: ubuntu-latest
31+
permissions:
32+
attestations: write
33+
id-token: write
2534
steps:
2635
- uses: actions/checkout@v4
2736
with:
2837
fetch-depth: 0
29-
- uses: actions/setup-python@v5
30-
with:
31-
python-version: 3
32-
- run: pip install --upgrade build twine
33-
- run: python -m build
34-
- run: twine check dist/*
35-
- uses: actions/upload-artifact@v4
38+
- uses: hynek/build-and-inspect-python-package@v2
3639
with:
37-
name: dist
38-
path: dist/
39-
- name: Build archive
40-
run: |
41-
git clean -fxd
42-
mkdir archive
43-
git archive -o archive/pydra.zip HEAD
44-
- uses: actions/upload-artifact@v4
45-
with:
46-
name: archive
47-
path: archive/
40+
attest-build-provenance-github: ${{ github.event_name != 'pull_request' }}
4841

4942
test:
50-
needs: ['build']
43+
runs-on: ${{ matrix.os }}
5144
strategy:
5245
matrix:
5346
os: [ubuntu-latest, macos-latest, windows-latest]
5447
python-version: ['3.11', '3.12', '3.13']
48+
dependencies: [latest, pre]
49+
include:
50+
# Test minimum dependencies on oldest supported Python
51+
- os: ubuntu-latest
52+
python-version: "3.11"
53+
dependencies: min
5554
fail-fast: false
56-
runs-on: ${{ matrix.os }}
55+
56+
env:
57+
DEPENDS: ${{ matrix.dependencies }}
58+
5759
steps:
5860
- name: Fetch repository
5961
uses: actions/checkout@v4
60-
- name: Fetch tags
61-
run: git fetch --prune --unshallow
62+
with:
63+
fetch-depth: 0
64+
- name: Install the latest version of uv
65+
uses: astral-sh/setup-uv@v5
6266
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
6367
uses: actions/setup-python@v5
6468
with:
6569
python-version: ${{ matrix.python-version }}
66-
- name: Update pip
67-
run: python -m pip install --upgrade pip
68-
- name: Install Pydra
69-
run: pip install .[test]
70-
- name: Print version
71-
run: python -c "import pydra.engine; print(pydra.utils.__version__)"
72-
- name: Disable etelemetry
73-
run: echo "NO_ET=TRUE" >> $GITHUB_ENV
74-
- name: Pytest
70+
- name: Install tox
7571
run: |
76-
pytest -vs -n auto pydra --doctest-modules --import-mode=importlib --cov pydra --cov-config .coveragerc --cov-report xml:cov.xml --rootdir pydra
72+
uv tool install tox --with=tox-uv --with=tox-gh-actions
73+
- name: Show tox config
74+
run: tox c
75+
- name: Run tox
76+
run: tox -v --exit-and-dump-after 1200
7777
- name: Upload coverage to Codecov
7878
uses: codecov/codecov-action@v5
7979
with:
8080
fail_ci_if_error: true
8181
token: ${{ secrets.CODECOV_TOKEN }}
8282

8383
test-singularity:
84-
needs: ['build']
8584
runs-on: ubuntu-22.04
8685
strategy:
8786
matrix:
8887
python-version: ['3.11', '3.12', '3.13']
88+
dependencies: [latest]
8989
fail-fast: False
90+
91+
env:
92+
DEPENDS: ${{ matrix.dependencies }}
93+
9094
steps:
9195
- name: Set env
9296
run: |
@@ -118,30 +122,32 @@ jobs:
118122
run: |
119123
echo ${{ github.ref }}
120124
singularity --version
125+
- uses: actions/checkout@v4
126+
with:
127+
fetch-depth: 0
128+
- name: Install the latest version of uv
129+
uses: astral-sh/setup-uv@v5
121130
- name: Set up Python ${{ matrix.python-version }}
122131
uses: actions/setup-python@v5
123132
with:
124133
python-version: ${{ matrix.python-version }}
125-
- name: Update build tools
126-
run: python -m pip install --upgrade pip
127-
- name: Checkout Pydra repo
128-
uses: actions/checkout@v4
129-
with:
130-
repository: ${{ github.repository }}
131-
- name: Fetch tags
132-
run: git fetch --prune --unshallow
133-
- name: Install pydra (test)
134-
run: pip install -e ".[test]"
135-
- name: Pytest
136-
run: pytest -vs --import-mode=importlib --cov pydra --cov-config .coveragerc --cov-report xml:cov.xml pydra/environments/tests/test_singularity.py pydra/environments/tests/test_environments.py --rootdir pydra
134+
- name: Install tox
135+
run: |
136+
uv tool install tox --with=tox-uv --with=tox-gh-actions
137+
- name: Show tox config
138+
run: tox c
139+
- name: Run tox
140+
# Run test files with singularity tests; re-add the overridable "-n auto"
141+
run: |
142+
tox -v --exit-and-dump-after 1200 -- -n auto \
143+
pydra/environments/tests/test_singularity.py pydra/environments/tests/test_environments.py
137144
- name: Upload coverage to Codecov
138145
uses: codecov/codecov-action@v5
139146
with:
140147
fail_ci_if_error: true
141148
token: ${{ secrets.CODECOV_TOKEN }}
142149

143150
test-slurm:
144-
needs: ['build']
145151
strategy:
146152
matrix:
147153
python-version: [3.11.5]
@@ -153,8 +159,8 @@ jobs:
153159
- name: Disable etelemetry
154160
run: echo "NO_ET=TRUE" >> $GITHUB_ENV
155161
- uses: actions/checkout@v4
156-
- name: Fetch tags
157-
run: git fetch --prune --unshallow
162+
with:
163+
fetch-depth: 0
158164
- name: Pull docker image
159165
run: |
160166
docker pull $DOCKER_IMAGE
@@ -174,20 +180,17 @@ jobs:
174180
docker exec slurm bash -c "echo $NO_ET"
175181
docker exec slurm bash -c "ls -la && echo list top level dir"
176182
docker exec slurm bash -c "ls -la /pydra && echo list pydra dir"
177-
if [[ "${{ matrix.python-version }}" == "3.11.5" ]]; then
178-
docker exec slurm bash -c "CONFIGURE_OPTS=\"-with-openssl=/opt/openssl\" pyenv install -v 3.11.5"
179-
fi
183+
docker exec slurm bash -c "CONFIGURE_OPTS=\"-with-openssl=/opt/openssl\" pyenv install -v ${{ matrix.python-version }}"
180184
docker exec slurm bash -c "pyenv global ${{ matrix.python-version }}"
181185
docker exec slurm bash -c "pip install --upgrade pip && pip install -e /pydra[test,psij] && python -c 'import pydra.engine; print(pydra.utils.__version__)'"
182186
- name: Run pytest
183187
run: |
184-
docker exec slurm bash -c "pytest /pydra/pydra/workers/tests/test_worker.py --import-mode=importlib --rootdir /pydra/pydra --only-worker=slurm --color=yes -vs --cov pydra --cov-config /pydra/.coveragerc --cov-report xml:/pydra/cov.xml"
188+
docker exec slurm bash -c "cd /pydra; pytest pydra/workers/tests/test_worker.py --only-worker=slurm --color=yes"
185189
- name: Upload coverage to Codecov
186190
uses: codecov/codecov-action@v5
187191
with:
188192
fail_ci_if_error: true
189193
token: ${{ secrets.CODECOV_TOKEN }}
190-
files: ./cov.xml
191194

192195
# test-sge:
193196
# needs: ['build']
@@ -270,7 +273,6 @@ jobs:
270273
# files: ./cov.xml
271274

272275
build-docs:
273-
needs: ['build']
274276
runs-on: ubuntu-latest
275277
# Set up the environment so that it finds conda
276278
defaults:
@@ -306,8 +308,8 @@ jobs:
306308
dbus-monitor --session &
307309
sleep 3
308310
- uses: actions/checkout@v4
309-
- name: Fetch tags
310-
run: git fetch --prune --unshallow
311+
with:
312+
fetch-depth: 0
311313
- name: Install Minconda
312314
uses: conda-incubator/setup-miniconda@v3
313315
with:
@@ -321,63 +323,44 @@ jobs:
321323
uses: actions/setup-python@v5
322324
with:
323325
python-version: '3.x'
324-
- name: Install dependencies
325-
run: |
326-
python -m pip install --upgrade pip
327-
pip install build twine
328326
- name: Install package
329327
run: pip install .[doc]
330328
- name: Install Python3 kernel
331329
run: python -m ipykernel install --user
332330
- name: Build docs
333-
run: |
334-
cd docs
335-
make html
336-
cd ..
331+
run: make -C docs html
337332
- uses: actions/upload-artifact@v4
338333
with:
339334
name: docs
340335
path: docs/build/html
341336

342337
deploy:
343-
needs: [build-docs, test, test-singularity, test-slurm]
338+
needs: [build, build-docs, test, test-singularity, test-slurm]
344339
runs-on: ubuntu-latest
340+
if: github.event_name == 'release'
341+
permissions:
342+
attestations: write
343+
id-token: write
345344
steps:
346345
- name: Download dist
347346
uses: actions/download-artifact@v4
348347
with:
349-
name: dist
348+
name: Packages
350349
path: dist
351-
- name: Check for PyPI token on tag
352-
id: deployable
353-
if: github.event_name == 'release'
354-
env:
355-
PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}"
356-
run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi
357350
- name: Upload to PyPI
358-
if: steps.deployable.outputs.DEPLOY
359351
uses: pypa/gh-action-pypi-publish@release/v1
360-
with:
361-
user: __token__
362-
password: ${{ secrets.PYPI_API_TOKEN }}
363352

364353
deploy-docs:
365354
needs: [build-docs, deploy]
366355
runs-on: ubuntu-latest
356+
if: github.event_name == 'release'
367357
steps:
368358
- name: Download docs
369359
uses: actions/download-artifact@v4
370360
with:
371361
name: docs
372362
path: docs-build
373-
- name: Check for GHPAGES_DEPLOY_KEY token
374-
id: deployable
375-
if: github.event_name == 'release'
376-
env:
377-
GHPAGES_DEPLOY_KEY: "${{ secrets.GHPAGES_DEPLOY_KEY }}"
378-
run: if [ -n "$GHPAGES_DEPLOY_KEY" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi
379363
- name: Deploy Docs to GitHub Pages
380-
if: steps.deployable.outputs.DEPLOY
381364
uses: peaceiris/actions-gh-pages@v4
382365
with:
383366
github_token: ${{ secrets.GHPAGES_DEPLOY_KEY }}

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
# ATM, this is the closest trigger to a PR merging
55
push:
66
branches:
7-
- master
7+
- main
88

99
concurrency:
1010
group: ${{ github.workflow }}-${{ github.ref }}

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ __pycache__
1010
.vscode/
1111

1212
.coverage*
13-
!.coveragerc
14-
cov.xml
13+
coverage.xml
1514

1615
.*.swp
1716
*~
@@ -21,5 +20,7 @@ cov.xml
2120
.DS_Store
2221
.ipynb_checkpoints
2322

23+
.tox
24+
2425
# This can be generated in-tree. We never want to commit it.
2526
pydra/utils/_version.py

README.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,20 @@ which can be installed similarly
7373
Developer installation
7474
======================
7575

76-
Pydra requires Python 3.11+. To install in developer mode:
77-
78-
::
76+
Pydra requires Python 3.11+. To install in developer mode::
7977

8078
git clone [email protected]:nipype/pydra.git
8179
cd pydra
8280
pip install -e ".[dev]"
8381

82+
In order to run pydra's test locally::
8483

85-
In order to run pydra's test locally:
86-
87-
::
84+
pytest pydra
8885

89-
pytest -vs pydra
86+
We use `tox <https://tox.wiki/>`_ to test versions and dependency sets.
87+
For example, to test on the minimum and latest dependencies, run::
9088

89+
tox -e py311-min -e py313-latest
9190

9291
It is also useful to install pre-commit:
9392

pydra/compose/shell/tests/test_shell_run.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,13 +2250,6 @@ class Outputs(shell.Outputs):
22502250
assert outputs.out1.fspath.exists()
22512251

22522252

2253-
@pytest.mark.xfail(
2254-
sys.version_info >= (3, 11),
2255-
reason=(
2256-
"Fails on Python 3.11 in some cases (presumably a typing thing with that specific "
2257-
"version of Python)"
2258-
),
2259-
)
22602253
@pytest.mark.parametrize("results_function", [run_no_submitter, run_submitter])
22612254
def test_shell_cmd_outputspec_7(tmp_path, worker, results_function):
22622255
"""

pydra/engine/result.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ def copyfile_workflow(
237237
value = getattr(outputs, field.name)
238238
# if the field is a path or it can contain a path _copyfile_single_value is run
239239
# to move all files and directories to the workflow directory
240-
new_value = copy_nested_files(value, wf_path, mode=FileSet.CopyMode.hardlink)
240+
new_value = copy_nested_files(
241+
value, wf_path, mode=FileSet.CopyMode.hardlink_or_copy
242+
)
241243
setattr(outputs, field.name, new_value)
242244
return outputs
243245

0 commit comments

Comments
 (0)