Skip to content

docs: use pinned dependencies in CICD #590

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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
66 changes: 66 additions & 0 deletions doc/source/how-to/continuous-integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,69 @@ Workflow examples are provided for various checks, such as :ref:`code style <cod

.. literalinclude:: code/release.yml
:language: yaml

Importance of pinned dependencies
---------------------------------

.. note::

This guidance applies to CI workflows. It does not apply to the
`dependency version range <https://dev.docs.pyansys.com/how-to/packaging.html#dependency-version-range>`_.
of the project itself.

To guarantee reproducibility, stability, and predictability of workflows, it is critical that
CI uses a locked, fully resolved list of pinned versions. If a project allows floating
versions of dependencies, for example `numpy>=1.26`, to be used in CI, it is exposed to random
failures without any code change. In fact, problems can occur at different levels:

- Runtime bugs: Update in runtime dependencies, like `numpy` or `pandas`, can introduce changes
in API behavior, deprecations, or regressions, affecting production code.
- Test failures: A minor update of a testing library could introduce breaking changes or
modify test behavior, causing false negatives or false positives.
- Documentation build failures: A documentation generator like `Sphinx` might introduce
subtle or breaking changes, like new warnings treated as errors or theme updates breaking
rendering, causing your docs build to fail.

Pinning dependencies helps to avoid these issues by freezing exact versions and ensuring that CI
workflows are reliable and predictable.

Additionally, having a complete, pinned set of dependencies is very useful for users and
contributors. If an user encounters issues while running tests locally, using the frozen
dependencies from CI could fix the problems or provide a reproducible environment for debugging.
Overall, this improves support, debugging speed, and community contribution experience.

How to pin dependencies
-----------------------

Depending on the type of project, different tools can be used to manage and pin dependencies.
In the following, this guidance assumes that your project has defined
`optional installation targets <https://dev.docs.pyansys.com/how-to/packaging.html#optional-target-recommendations-in-the-pyansys-ecosystem>`_
to illustrate how to install specific subsets of dependencies.

If you are using `poetry <https://python-poetry.org/>`_, you can use the ``poetry lock``
command to generate a ``poetry.lock`` file with all the dependencies and their versions.
Once the lock file created, you can use the following command in your CI workflow to install
the project with `tests` dependencies:

.. code-block:: yaml

- name: Install dependencies with extra tests
run: |
poetry install --with tests

If your project uses `flit` or `hatch`, you can use `uv <https://github.com/astral-sh/uv>`_
to resolve the dependencies and generate a requirements file. You can use the
``uv pip compile -o requirements.txt pyproject.toml`` command to generate a ``requirements.txt``
file with the main dependencies defined in your project. Note that, unlike the
``poetry.lock`` file, the requirements file does not include the variations for each installation
target. To create a requirements file with a specific extra, you can use the ``--extras`` option.
For example, you can create a requirement file with the `tests` extra by running the
``uv pip compile --extra tests -o requirements-tests.txt pyproject.toml``. Once the file has been created,
you can use the following command in your CI workflow to install the project with `tests`
dependencies:

.. code-block:: yaml

- name: Install dependencies with extra tests
run: |
pip install -r requirements-tests.txt
Comment on lines +235 to +251
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we focus on giving guidance using the pylock.toml file moving forward (rather than the requirements.txt files usage). Not talking about poetry here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good point, this is now available with recent uv version https://github.com/astral-sh/uv/releases/tag/0.6.15.

Copy link
Contributor Author

@SMoraisAnsys SMoraisAnsys Apr 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checked and it's not available yet with poetry. It's available with the latest version of pip https://pip.pypa.io/en/stable/cli/pip_lock/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah.. That's what I thought. That's also why I mentioned to leave poetry out of the mix for the pylock.toml file

Copy link
Contributor Author

@SMoraisAnsys SMoraisAnsys May 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note sure dependabot supports this kind of format yet, see dependabot/dependabot-core#12094
We should probably wait a bit more to move foward that approach. I agree to use pylock.toml though

1 change: 1 addition & 0 deletions doc/styles/config/vocabularies/ANSYS/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ untracked
untrusted
unvalidated
URIs
uv
Vale
venv
Visual Studio Code
Expand Down