Developer guide
Setting up the development environment
This project uses uv as its package manager for managing dependencies and ensuring consistent and reproducible environments. To install uv:
curl -LsSf https://astral.sh/uv/install.sh | sh
PS> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
See uv’s documentation for details.
Once uv is installed, synchronize your environment with the dependencies specified in the
pyproject.toml file, including development dependencies:
uv sync
Testing and code quality
Two tools are used to check the code:
Run them against your current environment with:
uv run pytest # run unit tests
uv run ruff check # check for linting issues
uv run ruff format # auto-format code
Adding --fix to ruff check will automatically correct fixable issues. Both should be clean
before a pull request is opened. Run ruff through uv run rather than a ruff installed elsewhere:
uv run uses the version pinned in uv.lock, which is the one CI uses, and other ruff versions
can enable different rules.
Tests that need the IBL online dependencies (ibllib) are skipped unless the ibl extra is
installed. To run them too:
uv sync --extra ibl
uv run pytest
The test suite treats warnings as errors, so a new deprecation warning fails the run. Fix the
cause, or, if the warning comes from inside a third-party package, add a targeted ignore to
filterwarnings in pyproject.toml.
To measure how much of the code is covered by the unit tests, run the tests with coverage enabled and then report on the result:
uv run pytest --cov
uv run coverage report
For a more detailed representation, generate an HTML report:
uv run coverage html
You’ll find the HTML report in the folder htmlcov, where you can open index.html in a web
browser to view detailed coverage statistics.
Pre-commit hooks
pre-commit runs ruff and a few file hygiene checks (trailing
whitespace, final newlines, YAML/TOML syntax, large files, uv.lock being up to date) each time
you commit. Install the hooks once per clone with:
uv run pre-commit install
If a hook fails, or fixes a file, the commit is stopped: review the changes, git add them and
commit again. To run all hooks against the whole repository without committing:
uv run pre-commit run --all-files
The ruff hooks call the ruff in the project environment, so they use the version pinned in
uv.lock and give the same result as CI.
Continuous integration
Every pull request, and every push to main, runs the CI GitHub Actions workflow
(.github/workflows/ci.yml):
Lint:
ruff check,ruff format --check, and a check thatuv.lockmatchespyproject.toml.Test: the test suite on Linux (Python 3.12 and 3.13), macOS and Windows, with the dependency versions in
uv.lock.Test with IBL extra: the test suite with the
iblextra installed, so the ONE/Alyx tests run instead of being skipped.
Pull requests that change the code or documentation also build the documentation
(.github/workflows/documentation.yml), without deploying it, so Sphinx errors are caught before
they reach main. Pushes to main build and deploy it to GitHub Pages.
Dependency updates
Dependabot opens pull requests once a month
(.github/dependabot.yml) that update uv.lock: one for minor and patch updates, one for major
updates, and one for the GitHub Actions used by the workflows. CI runs on each of them. Merge them
when CI passes. When an update touches Qt, pyqtgraph or datoviz, also start the GUI and check it
by hand, as the tests cover little of the GUI. If an update breaks something, fix it on the pull
request’s branch, or tell Dependabot to skip that package and merge the rest.
Git dependencies pinned to a commit, such as ibl-datoviz, are not updated by Dependabot. To move
one, change the commit in pyproject.toml and run uv lock.
Note
mypy is available in the typing dependency group and can be run with
uv run mypy, but the code base is not yet free of type errors, so it is not part of the checks
above.
Pull requests
All development work should be based on the main branch. To contribute:
Create a new branch from an up-to-date
main:git checkout main git pull git checkout -b your-branch-name
Make your changes, keeping each pull request focused on a single topic (feature, bugfix, refactor, etc.).
Before opening a pull request, ensure that all tests pass and the code is properly formatted (see Testing and code quality).
Open your pull request against the
mainbranch. The CI checks (see Continuous integration) must pass before it is merged.
Building the documentation
We use Sphinx to build our documentation and API reference. To build the documentation, run the following command:
uv run --group doc sphinx-build -W --keep-going docs/source docs/build
After running this command, you can view the generated documentation in your web browser by
opening docs/build/index.html. -W turns warnings into errors, as in CI, so a broken
cross-reference fails the build. See Writing documentation for how the documentation is organised.
Building the package
To build ibl-alignment-gui as a distributable Python package, execute the following command:
uv build
This command will create a distributable package of ibl-alignment-gui, in the form of a source
distribution (sdist) and a wheel (bdist_wheel). The generated package files will be located in the
dist directory.
Versioning scheme
ibl-alignment-gui uses Semantic Versioning. Its version
string (currently 0.1.0a4) is a combination of three fields, separated by dots:
MAJOR . MINOR . PATCH
The
MAJORfield is only incremented for breaking changes, i.e., changes that are not backward compatible with previous changes.The
MINORfield will be incremented upon adding new, backward compatible features.The
PATCHfield will be incremented with each new, backward compatible bugfix release that does not implement a new feature.Optionally appended letters can be used to indicate an alpha release (
a), a beta release (b) or a release candidate (rc).
On the developer side, these fields are controlled by both
adjusting the variable
versionfield inpyproject.toml, andadding the corresponding version string to a commit as a git tag, for instance:
git tag 1.2.3 git push origin --tags