DIPY is an open-source software project, and we have an open development process. This means that we welcome contributions from anyone. We do ask that you first read this document and follow the guidelines we have outlined here and that you follow the NIPY community code of conduct.
If you are looking for places that you could make a meaningful contribution, please contact us! We respond to queries on the Nipy mailing list, and to questions on our gitter channel. A good place to get an idea for things that currently need attention is the issues page of our Github repository. This page collects outstanding issues that you can help address. Join the conversation about the issue, by typing into the text box in the issue page.
Please refer to the development section of the documentation for the procedures we use in developing the code.
We use pytest to write tests of the code, and GitHub Actions for continuous integration.
If you are adding code into a module that already has a 'test' file (e.g., if
you are adding code into dipy/tracking/streamline.py), add additional tests
into the respective file (e.g., dipy/tracking/tests/test_streamline.py ).
New contributions are required to have as close to 100% code coverage as possible. This means that the tests written cause each and every statement in the code to be executed, covering corner-cases, error-handling, and logical branch points. To check how much coverage the tests have, you will need to run:
coverage run -m pytest -s --doctest-modules --verbose dipy
You will get the usual output of pytest, but also a table that indicates the test
coverage in each module: the percentage of coverage and also the lines of code
that are not run in the tests. You can also see the test coverage in the GitHub Actions run corresponding to the PR (in the log for the job with COVERAGE=1).
If your contributions are to a single module, you can see test and
coverage results for only that module without running all of the DIPY
tests. For example, if you are adding code to dipy/core/geometry.py,
you can use:
coverage run --source=dipy.core.geometry -m pytest -s --doctest-modules --verbose dipy/core/tests/test_geometry.py
You can then use coverage report to view the results, or use
coverage html and open htmlcov/index.html in your browser for a
nicely formatted interactive coverage report.
Contributions to tests that extend test coverage in older modules that are not fully covered are very welcome!
Code contributions should be formatted according to the DIPY Coding Style Guideline. Please, read the document to conform your code contributions to the DIPY standard.
DIPY uses Sphinx to generate documentation. The DIPY Coding Style Guideline contains details about documenting the contributions.
DIPY follows a master-first development model. All bug fixes and improvements
must land on master first. Backporting to maintenance branches (maint/X.Y.x)
is done after merging to master via automated cherry-pick — never the reverse.
Workflow: Fix on master → Label PR → Merge → Auto-backport to maint/1.13.x / maint/1.12.x
This ensures master is always the most complete branch, and maintenance branches
receive only curated, tested changes.
| Branch | Purpose | PyPI Target |
|---|---|---|
master |
Main development | 2.0.0 |
maint/1.13.x |
Next minor series | 1.13.x |
maint/1.12.x |
Current stable patch series | 1.12.x |
- Submit your PR targeting
masteras normal. - Before merging, apply one or more backport labels:
backport-maint/1.13.x— cherry-pick to the 1.13.x seriesbackport-maint/1.12.x— cherry-pick to the 1.12.x series
- Merge the PR into
master. - The backport workflow runs automatically and opens a backport PR for each labeled target branch within minutes.
- Review and merge the generated backport PRs.
When to backport: Bug fixes and security patches are good candidates. New features that could break API compatibility should generally stay on
masteronly.
When a cherry-pick conflict occurs, the backport action automatically:
- Posts a comment on the original PR with manual cherry-pick instructions.
- Opens a draft backport PR with the conflict markers committed, so the branch and base are already set up for you to finish manually.
To resolve a conflicted backport draft:
# Fetch the draft branch created by the automation.
git fetch upstream
git checkout backport-<PR_NUMBER>-to-maint/1.13.x
# Resolve conflicts in your editor, then stage and continue.
git add <resolved-files>
git cherry-pick --continue
# Push and mark the draft PR as ready for review.
git push upstream backport-<PR_NUMBER>-to-maint/1.13.x
gh pr ready <BACKPORT_PR_NUMBER> --repo dipy/dipyWhen a new release series is created (e.g., maint/1.14.x):
# Step 1: Create the branch from master and push to upstream.
git fetch upstream
git checkout master && git merge --ff-only upstream/master
git branch maint/1.14.x master
git push upstream maint/1.14.x
# Step 2: Create the GitHub label — this is the ONLY required change.
gh label create "backport-maint/1.14.x" \
--repo dipy/dipy \
--color "e4a400" \
--description "Backport this PR to maint/1.14.x"No changes to .github/workflows/backport.yml are needed — the workflow is
fully dynamic and reads the label name to determine the target branch.