Developer Guide#

Quick start#

Thanks for contributing! 🙏 Below you can find an overview of the commands to get you up and running quickly, depending on your preferred development tools.

First clone the repository from GitHub and install the package locally in editable mode (-e):

$ git clone https://github.com/aiidateam/aiida-quantumespresso
$ cd aiida-quantumespresso
$ pip install -e .

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

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

Tip

You can also install the development dependencies using the new dependency groups, available from pip v25.1:

$ pip install -e . --group dev

In the future the development extras will most likely be removed.

Pre-commit

To make sure your changes adhere to our formatting/linting preferences, 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

The current documentation build relies on a Sphinx-generated Makefile. Build the documentation with:

$ make -C docs html

Once complete, you can open the documentation in your browser using:

$ make -C docs view

Or clean the documentation files:

$ make -C docs clean

See the documentation section for more information on how we write our documentation.

uv is a Python package and project manager. See the documentation on how to install uv.

Pre-commit

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

$ uvx pre-commit install

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

$ uvx pre-commit run -a

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

Note

Here we use the uvx command to run the pre-commit tool without installing it. Alternatively you can also install pre-commit as a tool and omit uvx.

Tests

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

$ uv run pytest

Or select the test module:

$ uv run pytest tests/parsers/test_pw.py

See the pytest documentation for more information.

Documentation

The current documentation build relies on a Sphinx-generated Makefile. Build the documentation with:

$ uv run make -C docs html

Once complete, you can open the documentation in your browser using:

$ uv run make -C docs view

Or clean the documentation files:

$ uv run make -C docs clean

See the documentation section for more information on how we write our documentation.

You can use Hatch to run development tools in isolated environments.

Pre-commit

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

$ hatch run pre-commit:install

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

$ hatch run 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 using:

$ hatch test

Or select the test module:

$ hatch test tests/parsers/test_pw.py

You can also run the tests for a specific Python version with the -py option:

$ hatch test -py 3.11

Or all supported Python versions with --all:

$ hatch test --all

See the Hatch documentation for more information.

Documentation

The current documentation build relies on a Sphinx-generated Makefile. Build the documentation with Hatch in the docs environment using:

$ hatch run docs:build

This runs make under the hood. Once complete, you can open the documentation in your browser using:

$ hatch run docs:view

Or clean the documentation files:

$ hatch run docs:clean

See the documentation section for more information on how we write our documentation.

Documentation#

We use the DiĂĄtaxis approach for organising the documentation in four sections:

  • Tutorials

  • How-to’s

  • Topics (Explanation)

  • Reference

All of our documentation should be written in MyST Markdown. Below you can find a list of current style guide items:

  1. Write one sentence per line and otherwise no manual line wrapping to make easy to create and review diffs. All standard editors allow for dynamic line wrapping, and the line length is irrelevant for the rendered documentation in, e.g., HTML or PDF format.

  2. File and directory names should be alphanumeric and all lower-case with underscores as word-separators. Example: entry_points.rst

  3. Headers must be set in sentence-case. Example: “Entry points”

  4. Separate paragraphs by one empty line, but not more.

  5. Use the - symbol for itemized lists.

Notes#

run vs submit#

Originally discussed in this issue.

In the majority of real use cases, submit is the preferred engine command, and the documentation should reflect that. Hence, we limit using the run commando to the quick start documentation, and perhaps showing other use cases such as testing calculation setups or workflows (with caching).

Release#

Creating a new release consists of the steps outlined below. In the following, we assume that the latest release was v3.2.1. Furthermore, we assume the following naming conventions for remotes:

  • origin: remote pointing to aiidateam/aiida-quantumespresso

  • fork: remote pointing to personal fork, e.g. mbercx/aiida-quantumespresso

Check how your remotes are configured with git remote -v

Preparing the release branch#

Deciding the type of release#

We use semantic versioning, i.e. version labels have the form v<major>.<minor>.<patch>

  • Patch release: v3.2.1 to v3.2.2, only bug fixes

  • Minor release: v3.2.1 to v3.3.0, bug fixes and new features that maintain backwards compatibility

  • Major release: v3.2.1 to v4.0.0, bug fixes and new features that break backwards compatibility

Creating the release branch#

We use the GitHub Flow branching model. In short: new features, bug fixes, etc are added by opening a pull request to main, and the main branch is tagged after doing a pull request that updates the CHANGELOG.md. Doing so will trigger an automated deployment to PyPI.

For most releases, we assume that all the changes in the current main branch have to be included in the release. As such, branch off the new release branch directly from main:

git fetch --all --prune
git checkout origin/main -b release/3.3.0

Updating the CHANGELOG.md, version and compatibilities#

The next step is to update the CHANGELOG.md with all the changes made since the last release. First, update the source code __version__ in the following file by hand:

  • src/aiida_quantumespresso/__init__.py

Then, run the update_changelog.py script:

python .github/workflows/update_changelog.py

This will automatically add:

  1. The header for the new release and the sub-headers in which the commits should be sorted.

  2. The list of commits since the previous release, with links to them.

Sort the commit items into the correct subsection of the change log. Ideally, the main changes or new features are also described at the top of the change log message, providing code snippets where it’s useful.

Some final checks you should perform:

  • If a certain commit introduces or changes functionality, it should be documented. If the documentation was not introduced during review (which should always be requested), ask the author of the changes to provide it.

  • Also check the compatibility matrix in README.md to see if any changes have to be made.

Once you’ve prepared the release branch locally, commit with the message ‘Release v3.3.0’ and push it to Github. For our major/minor release example:

git commit -am 'Release `v3.3.0`'
git push origin release/3.3.0

Your branch is now ready to be released!

Updating main#

Merge release branch into main#

Now that the release branch is ready, merge it into main via a pull request. Make sure the remote release/3.3.0 branch is up to date by pushing the local changes, then go to Github and create a pull request to the main branch of the official repository.

After the pull request has been approved, merge the PR using the “Squash and Merge”, and make sure the commit is simply named e.g. ‘Release v3.3.0’.

Once this is complete, fetch all the changes locally, checkout the main branch and make sure it’s up to date with the remote:

git fetch --all
git checkout main
git pull origin

Next, tag the final release commit:

git tag -a v3.3.0 -m 'Release `v3.3.0`'

Warning

Once you push the tag to GitHub, a workflow will start that automatically publishes a release on PyPI. Double check that the tag is correct, and that the main branch looks in good shape.

If you accidentally tagged the wrong commit, you can delete the local tag using the following command:

git tag -d v3.3.0

Once you’re confident that the tag and main branch are in good shape, push both to the remote:

git push origin main --tags

With the release tag created, the new release is automatically built and published on PyPI via our continuous deployment (CD) GitHub workflow!

Important

In case you did push with the wrong tag, the CD should fail since we validate the tag as part of the workflow. You can then delete the tag both locally and remotely, make the correct tag locally and push it again. However, if you changed the __version__ to an incorrect one that isn’t on PyPI, and the tag matches that one, it will likely be published. So look carefully before you leap, and monitor the CD!