Skip to content

chore: Switch to tox for testing and CI #900

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 8 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
229 changes: 67 additions & 162 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Python package
name: Tox

on:
push:
Expand All @@ -13,42 +10,17 @@ on:
- cron: '0 0 * * *'

concurrency:
group: python-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
job_metadata:
if: github.repository == 'nipreps/niworkflows'
runs-on: ubuntu-latest
outputs:
commit_message: ${{ steps.get_commit_message.outputs.commit_message }}
version: ${{ steps.show_version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Print head git commit message
id: get_commit_message
run: |
if [[ -z "$COMMIT_MSG" ]]; then
COMMIT_MSG=$(git show -s --format=%s $REF)
fi
echo commit_message=$COMMIT_MSG | tee -a $GITHUB_OUTPUT
env:
COMMIT_MSG: ${{ github.event.head_commit.message }}
REF: ${{ github.event.pull_request.head.sha }}
- name: Detect version
id: show_version
run: |
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
VERSION=${GITHUB_REF##*/}
else
pipx run hatch version # Once to avoid output of initial setup
VERSION=$( pipx run hatch version )
fi
echo version=$VERSION | tee -a $GITHUB_OUTPUT
permissions:
contents: read

env:
# Force tox and pytest to use color
FORCE_COLOR: true

jobs:
build:
if: github.repository == 'nipreps/niworkflows'
runs-on: ubuntu-latest
Expand Down Expand Up @@ -118,140 +90,73 @@ jobs:
datalad get -J 2 -r ds000003 ds000030/sub-10228/func

test:
needs: [build, get_data, job_metadata]
needs: [get_data]
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
install: [repo]
dependencies: [latest, pre]
include:
- python-version: "3.12"
install: sdist
- python-version: "3.12"
install: wheel
- python-version: "3.12"
install: editable

env:
INSTALL_TYPE: ${{ matrix.install }}

steps:
- uses: actions/checkout@v4
if: matrix.install == 'repo' || matrix.install == 'editable'
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Load test data cache
uses: actions/cache@v4
id: stanford-crn
with:
path: ~/.cache/stanford-crn/
key: data-v0-${{ github.ref_name }}-${{ github.sha }}
- name: Load TemplateFlow cache
uses: actions/cache@v4
id: templateflow
with:
path: ~/.cache/templateflow
key: templateflow-v0-${{ github.ref_name }}-${{ strategy.job-index }}-${{ github.sha }}
restore-keys: |
templateflow-v0-${{ github.ref_name }}-
templateflow-v0-
- name: Fetch packages
if: matrix.install == 'sdist' || matrix.install == 'wheel'
uses: actions/download-artifact@v3
with:
name: dist
path: dist/
- name: Select archive
run: |
if [ "$INSTALL_TYPE" = "sdist" ]; then
ARCHIVE=$( ls dist/*.tar.gz )
elif [ "$INSTALL_TYPE" = "wheel" ]; then
ARCHIVE=$( ls dist/*.whl )
elif [ "$INSTALL_TYPE" = "repo" ]; then
ARCHIVE="."
elif [ "$INSTALL_TYPE" = "editable" ]; then
ARCHIVE="-e ."
fi
echo "ARCHIVE=$ARCHIVE" | tee -a $GITHUB_ENV
- name: Install package
run: python -m pip install $ARCHIVE
- name: Check version
run: |
INSTALLED_VERSION=$(python -c 'import niworkflows; print(niworkflows.__version__, end="")')
echo "INSTALLED: \"${INSTALLED_VERSION}\""
test "${INSTALLED_VERSION}" = "${VERSION}"
env:
VERSION: ${{ needs.job_metadata.outputs.version }}
- name: Install test dependencies
run: python -m pip install "niworkflows[tests]"
- name: Run tests
run: pytest -sv --doctest-modules --cov niworkflows --pyargs niworkflows
- uses: codecov/codecov-action@v4
name: Submit to CodeCov
with:
token: ${{ secrets.CODECOV_TOKEN }}

test-pre:
needs: [get_data, job_metadata]
if: ${{ !contains(needs.job_metadata.outputs.commit_message, '[skip pre]') }}
runs-on: ubuntu-latest
strategy:
matrix:
# Only run --pre tests on Python versions within SPEC0 support
python-version: ["3.11", "3.12"]
install: [repo]
pip-flags: ['--pre']
- python-version: "3.9"
dependencies: min
exclude:
# Do not test pre-releases for versions out of SPEC0
- python-version: "3.9"
dependencies: pre
- python-version: "3.10"
dependencies: pre

env:
INSTALL_TYPE: ${{ matrix.install }}
PIP_FLAGS: ${{ matrix.pip-flags }}
DEPENDS: ${{ matrix.dependencies }}

steps:
- name: Debug commit message
run: echo "${{ needs.job_metadata.outputs.commit_message }}"
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Load test data cache
uses: actions/cache@v4
id: stanford-crn
with:
path: ~/.cache/stanford-crn/
key: data-v0-${{ github.ref_name }}-${{ github.sha }}
- name: Load TemplateFlow cache
uses: actions/cache@v4
id: templateflow
with:
path: ~/.cache/templateflow
key: templateflow-v0-${{ github.ref_name }}-${{ strategy.job-index }}-${{ github.sha }}
restore-keys: |
templateflow-v0-${{ github.ref_name }}-
templateflow-v0-
- name: Install package
run: python -m pip install $PIP_FLAGS .
- name: Check version
run: |
INSTALLED_VERSION=$(python -c 'import niworkflows; print(niworkflows.__version__, end="")')
echo "INSTALLED: \"${INSTALLED_VERSION}\""
test "${INSTALLED_VERSION}" = "${VERSION}"
env:
VERSION: ${{ needs.job_metadata.outputs.version }}
- name: Install test dependencies
run: python -m pip install $PIP_FLAGS "niworkflows[tests]"
- name: Run tests
run: pytest -sv --doctest-modules --cov niworkflows --pyargs niworkflows
- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: Submit to CodeCov
- uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v3
- name: Load test data cache
uses: actions/cache@v4
id: stanford-crn
with:
path: ~/.cache/stanford-crn/
key: data-v0-${{ github.ref_name }}-${{ github.sha }}
- name: Load TemplateFlow cache
uses: actions/cache@v4
id: templateflow
with:
path: ~/.cache/templateflow
key: templateflow-v0-${{ github.ref_name }}-${{ strategy.job-index }}-${{ github.sha }}
restore-keys: |
templateflow-v0-${{ github.ref_name }}-
templateflow-v0-
- uses: actions/cache@v4
with:
path: ~/.cache/templateflow
key: templateflow-v1
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y --no-install-recommends graphviz
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Display Python version
run: python -c "import sys; print(sys.version)"
- name: Install tox
run: |
uv tool install tox --with=tox-uv --with=tox-gh-actions
- name: Show tox config
run: tox c
- name: Run tox
run: tox -v --exit-and-dump-after 1200
- uses: codecov/codecov-action@v4
with:
file: coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
if: ${{ always() }}

flake8:
if: github.event_name != 'schedule'
Expand Down
72 changes: 43 additions & 29 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@ classifiers = [
]
dependencies = [
"acres",
"attrs",
"attrs >=20.1",
"importlib_resources >= 5.7; python_version < '3.11'",
"jinja2",
"jinja2 >=3",
"looseversion",
"matplotlib >= 3.4.2",
"matplotlib >= 3.5",
"nibabel >= 3.0",
"nilearn >= 0.5.2",
"nilearn >= 0.8",
"nipype >= 1.8.5",
"nitransforms >= 21.0.0",
"numpy",
"nitransforms >= 22.0.0",
"numpy >= 1.20",
"packaging",
"pandas",
"pandas >= 1.2",
"pybids >= 0.15.1",
"PyYAML",
"scikit-image",
"scipy",
"seaborn",
"PyYAML >= 5.4",
"scikit-image >= 0.18",
"scipy >= 1.8",
"seaborn >= 0.11",
"svgutils >= 0.3.4",
"templateflow >= 0.7.2",
"transforms3d",
"templateflow >= 23.1",
"transforms3d >= 0.4",
]

[project.optional-dependencies]
Expand All @@ -62,12 +62,12 @@ style = [
"flake8 >= 3.7.0",
]
tests = [
"coverage >=5.2.1",
"pytest >= 4.4",
"pytest-cov",
"coverage[toml] >=5.2.1",
"pytest >= 6",
"pytest-cov >= 2.11",
"pytest-env",
"pytest-xdist >= 1.28",
"pytest-xvfb",
"pytest-xdist >= 2.5",
"pytest-xvfb >= 2",
]
# Aliases
all = ["niworkflows[doc,pointclouds,style,tests]"]
Expand Down Expand Up @@ -116,23 +116,31 @@ skip-string-normalization = true
extend-exclude = '_version.py'

[tool.pytest.ini_options]
norecursedirs = ".git"
addopts = "-sv --doctest-modules"
minversion = "6"
testpaths = ["niworkflows"]
log_cli_level = "INFO"
xfail_strict = true
norecursedirs = [".git"]
addopts = [
"-svx",
"-ra",
"--strict-config",
"--strict-markers",
"--doctest-modules",
# Config pytest-cov
"--cov=niworkflows",
"--cov-report=xml",
"--cov-config=pyproject.toml",
]
doctest_optionflags = "ALLOW_UNICODE NORMALIZE_WHITESPACE ELLIPSIS"
env = """
PYTHONHASHSEED=0
"""
filterwarnings = """
ignore::DeprecationWarning
"""
env = "PYTHONHASHSEED=0"
filterwarnings = ["ignore::DeprecationWarning"]
junit_family = "xunit2"

[tool.coverage.run]
branch = true
omit = [
"*/tests/*",
"niworkflows/_version.py",
"niworkflows/conftest.py",
"*/_version.py",
]

[tool.coverage.report]
Expand All @@ -141,3 +149,9 @@ exclude_lines = [
"raise NotImplementedError",
"warnings\\.warn",
]

[tool.coverage.paths]
source = [
"niworkflows",
"**/site-packages/niworkflows"
]
Loading
Loading