-
Notifications
You must be signed in to change notification settings - Fork 192
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
CI: Utilize uv lockfile for reproducible test environments #6640
Conversation
5b73199
to
a3ef407
Compare
a3ef407
to
dff7bde
Compare
In this implementation, the hook will only check whether the lockfile is compatible with pyproject.toml, it will not try to automatically update it, since that should be decided by the developer.
- name: Install dependencies from uv lock | ||
# NOTE: We're also asserting that the lockfile is up to date | ||
if: ${{ inputs.from-lock == 'true' }} | ||
run: uv sync --locked --extra pre-commit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: By default we're installing with pre-commit
optional dependencies (extras), which transitively includes other extras, see pyproject.toml I think this is the best solution to make things work for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we add the extra all
that includes all extra packages to make it more explicit that we check all of them? I am not sure if there is a scenario where we will change something that is not included in pre-commit, but it is also not super clear that we choose pre-commit here to include all extras. At least I would add a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a comment for now. I agree this is not ideal, I have some ideas but want to keep them for a separate PR since there's a lot going on here already.
Note that if we wanted to always install all the extras, we could just pass the --all-extras
parameter to uv. But that would (among others) install the whole jupyter stack which seems wasteful.
utils/dependency_management.py @aiidateam/dependency-manager | ||
.github/workflows/dm.yml @aiidateam/dependency-manager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file does not exist.
@agoscinski @unkcpz I think this PR is mostly ready now, let me know what you think! The only thing missing is developer documentation: I would suggest moving the Dependency Management Wiki article to the repo in a separate PR. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6640 +/- ##
==========================================
+ Coverage 77.51% 77.93% +0.43%
==========================================
Files 560 563 +3
Lines 41444 41662 +218
==========================================
+ Hits 32120 32464 +344
+ Misses 9324 9198 -126 ☔ View full report in Codecov by Sentry. |
Sure, go ahead with a separate PR, thanks! |
@danielhollas nice, thanks a lot! would this be understood and accepted by |
@khsrali I tried it and it works without a problem. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unless they need to modify dependencies in pyproject.toml
I don't understand how this will work. I think if we run uv lock
from different machine, the lock file is generated using the environment where the command is run. Which means two people will have two different lock file generated. Is this leading to large number of lines change?
@@ -96,15 +64,15 @@ jobs: | |||
python-version: ${{ matrix.python-version }} | |||
|
|||
- name: Setup environment | |||
run: .github/workflows/setup.sh | |||
run: source .venv/bin/activate && .github/workflows/setup.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this .venv
created from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is created by uv sync
automatically in the install-aiida-core
action above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we write it as comment or like this?
run: source .venv/bin/activate && .github/workflows/setup.sh | |
run: uv venv && source .venv/bin/activate && .github/workflows/setup.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote a comment about this both here and in actions/install-aiida-core/action.yml
. See 7959c4d
uv should generate a universal lock file independent of your current python version or OS. At least that is my understanding, would be good if you can verify. I have generated the lock here on Linux and Python 3.12 Also you can try using the lock file I generated by running |
When merging main into this branch, the lock needed to be updated. Just to illustrate, here's how the failed pre-commit hook looked` ❯ pre-commit run -a check-uv-lock
Check uv lockfile up to date.............................................Failed
- hook id: check-uv-lock
- exit code: 2
Resolved 254 packages in 126ms
error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. Then all I needed to do is to run ❯ uv lock
Resolved 254 packages in 152ms
Added execnet v2.1.1
Added pytest-xdist v3.6.1 Note, if we wanted, we can also update the lock automatically as part of the pre-commit hook to avoid the extra manual step? |
Yeah, the previous solution using requirements.txt files was done with |
Yes, I think this is better to avoid manual run of the pre-commit locally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work @danielhollas I think this is very useful. I needed some time to wrap my head around the changes. I am trying it out now in #6600
I had an issue with scipy, needed to be 1.14.1 for the python 3.13 but |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some minor changes to add doc here and there. Thanks for the work! I think minor changes + a rebase and then we can merge
- name: Install dependencies from uv lock | ||
# NOTE: We're also asserting that the lockfile is up to date | ||
if: ${{ inputs.from-lock == 'true' }} | ||
run: uv sync --locked --extra pre-commit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we add the extra all
that includes all extra packages to make it more explicit that we check all of them? I am not sure if there is a scenario where we will change something that is not included in pre-commit, but it is also not super clear that we choose pre-commit here to include all extras. At least I would add a comment
@@ -96,15 +64,15 @@ jobs: | |||
python-version: ${{ matrix.python-version }} | |||
|
|||
- name: Setup environment | |||
run: .github/workflows/setup.sh | |||
run: source .venv/bin/activate && .github/workflows/setup.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we write it as comment or like this?
run: source .venv/bin/activate && .github/workflows/setup.sh | |
run: uv venv && source .venv/bin/activate && .github/workflows/setup.sh |
issue-number: ${{ github.event.number }} | ||
body: | | ||
Please update the requirements/ files to ensure that they | ||
are consistent with the dependencies specified in the 'pyproject.toml' file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel bad deleting this, but maintaining this seems to me me not worth the effort. Especially, since we don't update dependencies frequently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you feel bad? None of this is needed now when we have the lockfile, no?
@agoscinski thanks for the review! I've merged in main and added more comments, should be good to go. There are definitely things that could be improved, but I'll save that for a followup. |
@danielhollas , stupid question: |
Not really, in the same way that you don't list pip in your dependencies. :-) uv is the installer so it needs to exist outside of the project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for the work @danielhollas
I remove the outdated "check-requirement" CI restriction. So it is able to merge. |
It seems other CI actions are failed after merging this. I'll have a look later. |
After this PR, the AEP https://github.com/aiidateam/AEP/blob/master/002_dependency_management/readme.md is outdated. @danielhollas would you mind to update it to sync it (or put a link in the AEP point to the doc) with the developer documentation you are preparing? |
Sorry, @danielhollas, for ignoring this... been busy with some other stuff. I see the rest of the aiida-core office took over. Thanks for the work! <3 |
No worries at all, I was mostly tagging everybody for visibility. :-) |
@danielhollas I have to say, this is a fantastic change. It makes testing against different branch extremely easy. I benefit a lot when working and test with plumpy/kiwipy. +100 kudos and thanks again. |
This PR removes the requirement files in
requirements/
folder and replaces them with a single universal lockfileuv.lock
. "universal" in this case means that it contains resolved package versions for all supported python versions and operating systems. More on the uv lockfiles can be found in their docs: https://docs.astral.sh/uv/concepts/projects/layout/#the-lockfileWhen modifying the dependencies in
pyproject.toml
, the lockfile needs to be updated by running(Note that using e.g.
uv add
,uv remove
oruv sync
updates the lockfile automatically)This relative simplicity compared to the previous custom solution allows for much easier development and I could delete a lot of custom YAML in CI. To check whether the lockfile is up to date, one can simply run
This command is run automatically as a pre-commit hook whenever
pyproject.toml
is changed.Note
Developers don't necessarily need to use the lockfile locally, nor are they required to have
uv
installed, unless they need to modify dependencies inpyproject.toml
Closes #6613