Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Developer Guide

Quick start

Thanks for contributing! 🙏 Below you can find an overview of the commands to get you up and running quickly.

First clone the repository from GitHub

git clone <GITHUB-REPO>

and install the package locally in editable mode (-e):

cd aiida-epw
pip install -e .
Default
uv
Hatch

The “default” approach to developing is to install the development extras in your current environment:

pip install -e .[pre-commit,tests,docs]

🔧 Pre-commit

To make sure your changes adhere to our formatting/linting preferences and commit-message convention, install the pre-commit hooks:

pre-commit install

They will then run on every git commit. You can also run them on e.g. all files using:

pre-commit run -a

Drop the -a option in case you only want to run on staged files.

🧪 Tests

You can run all tests in the tests directory with pytest:

pytest

Or select the test module:

pytest tests/parsers/test_pw.py

See the pytest documentation for more information.

📚 Documentation

We use MyST as our documentation framework. Go into the docs directory and start the documentation server with:

myst start

and open the documentation in your browser via the link shown. Every time you save a file, the corresponding documentation page is updated automatically!

A GitHub action is set up to automatically deploy the documentation to GitHub Pages. See the corresponding GitHub Pages documentation for the steps required.

Pre-commit rules

From the extensive Ruff ruleset, we ignore the following globally:

CodeRuleRationale / Note
TRY003raise-vanilla-argsFormatting warning/exception messages beforehand makes the code less readable, for a minor benefit in readability of the exception.
EM101raw-string-in-exceptionSame as TRY003
EM102f-string-in-exceptionSame as TRY003
PLR2004magic-value-comparisonWe have a lot of “magic values” to compare with in scientific code; naming them all would reduce readability for little benefit.
FBT002boolean-default-value-positional-argumentWe understand the concept, but adhering to this rule is not a small change in syntax; disable for now.
TID252relative-importsWe don’t mind relative imports; as long as you don’t go up a level, they’re more readable (less verbose).

And the following rules for the files in the tests directory:

CodeRuleRationale / Note
INP001implicit-namespace-packageWhen tests are not part of the package, there is no need for __init__.py files.
S101assertAsserts should not be used in production environments, but are fine for tests.

And the following rules for the files in the dev directory:

CodeRuleRationale / Note
INP001implicit-namespace-packageDev scripts are not part of the package, so there is no need for __init__.py files.
T201printDev scripts use print() for user-facing output, which is fine outside of library code.

Release

Releases of aiida-epw are cut by pushing a vX.Y.Z tag to GitHub. The cd workflow under .github/workflows/cd.yaml then builds an sdist and wheel with Hatch and publishes them to PyPI.

  1. Bump the version and generate the changelog draft:

     hatch run bump <new-version>

    This runs hatch version to update src/aiida-epw/__about__.py, then runs dev/update_changelog.py to prepend a new section to CHANGELOG.md with commits sorted by type. Review the generated changelog, make any edits, and commit the bump on main (typically via a PR).

  2. Tag the bump commit and push the tag:

     git tag -a v<new-version> -m '🚀 Release v<new-version>'
     git push origin v<new-version>
  3. The cd.yaml workflow picks up the tag, builds the distributions, and publishes them to PyPI.

The git tag and the version in __about__.py must agree. PyPI only sees the version baked into the built distribution, so a mismatch will silently publish under the wrong version (or be rejected as a duplicate of an existing release), and re-tagging after the fact is awkward.

Commit messages

Each commit subject must start with a leading emoji indicating the type of change. This is enforced locally by a commit-msg pre-commit hook (dev/check_commit_msg.py) and in CI by a commit-msgs job that checks every commit in a pull request. The changelog script (dev/update_changelog.py) uses the same emojis to automatically sort commits into the right sections, so the sorting happens at commit time, when the changes are still fresh in memory.

For the full specification and emoji table, see the commit message conventions.