Skip to content

Conversation

@GeigerJ2
Copy link
Contributor

@GeigerJ2 GeigerJ2 commented Dec 5, 2025

@GeigerJ2 GeigerJ2 changed the base branch from main to support/2.7.x December 5, 2025 14:37
@codecov
Copy link

codecov bot commented Dec 5, 2025

Codecov Report

❌ Patch coverage is 90.27237% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.16%. Comparing base (adf6fc0) to head (2befa6b).
⚠️ Report is 21 commits behind head on support/2.7.x.

Files with missing lines Patch % Lines
...rc/aiida/storage/psql_dos/orm/querybuilder/main.py 70.00% 12 Missing ⚠️
src/aiida/common/utils.py 86.21% 4 Missing ⚠️
src/aiida/engine/processes/calcjobs/manager.py 76.93% 3 Missing ⚠️
src/aiida/transports/plugins/ssh_async.py 91.31% 2 Missing ⚠️
src/aiida/cmdline/commands/cmd_code.py 97.73% 1 Missing ⚠️
src/aiida/manage/configuration/config.py 92.31% 1 Missing ⚠️
src/aiida/manage/configuration/settings.py 80.00% 1 Missing ⚠️
src/aiida/tools/graph/graph_traversers.py 75.00% 1 Missing ⚠️
Additional details and impacted files
@@                Coverage Diff                @@
##           support/2.7.x    #7132      +/-   ##
=================================================
+ Coverage          79.13%   79.16%   +0.04%     
=================================================
  Files                565      565              
  Lines              43391    43488      +97     
=================================================
+ Hits               34331    34425      +94     
- Misses              9060     9063       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@danielhollas
Copy link
Collaborator

danielhollas commented Dec 5, 2025

I am bit confused by the number of commits (for a patch release!) shouldn't we just pick the most critical bug fixes and leave the rest for the 2.8.0). That seems much safer and in line with other patch release which have always been very targeted in the past.

(EDIT: sorry if I missed discussion about this)

@GeigerJ2
Copy link
Contributor Author

GeigerJ2 commented Dec 5, 2025

I am bit confused by the number of commits (for a patch release!) shouldn't we just pick the most critical bug fixes and leave the rest for the 2.8.0). That seems much safer and in line with other patch release which have always been very targeted in the past.

(EDIT: sorry if I missed discussion about this)

Hm, that's a valid concern... though, I actually went manually through all the commits, and only selected the ones that are suitable for a patch release following SemVer (that is, no new features). E.g., numpy upgrade, click upgrade, unstashing, any new methods, etc., are not included. In addition, the recent PRs have been rather small, e.g., I already have two one-line change PRs to drop the duplicated CLI arguments. We also plan v2.8.0, with a bunch of new features already in the pipeline, rather soon. So, I do think it's fine to go through with this patch release (given that now it's ready, basically). What do you think?

EDIT: Didn't know about the history of patch releases, and how targeted they were in the past, tbh. Though, my original motivation for the patch release was fixing the PSQL OpErrs that would lead to archive export failures, and as that kept dragging on, and people reported (and fixed) more and more issues, the list of things in the 2.7.2 project grew ^^
All of that being said, if the selection of commits is indeed uncommon, I can also prepare an alternative release branch with just critical bug fixes.

Thoughts, @khsrali, @agoscinski?

@danielhollas
Copy link
Collaborator

Well, the fact the 2.8 release is imminent is more of an argument to have a small and targeted patch release only containing critical bugfixes.

. though, I actually went manually through all the commits, and only selected the ones that are suitable for a patch release following SemVer (that is, no new features).

To be super clear, I fully trust you did a great job of this. But in the end it is just statistics --- every change, (even a "bugfix") brings an extra chance of breaking something. That's why I think patch releases should be targeted only for critical bugfixes. To me in this case those are the async-ssh fixes and your PSQL import/export fixes (perhaps others I am not aware of).

and as that kept dragging on, and people reported (and fixed) more and more issues, the list of things in the 2.7.2 project grew

Yeah, I think in semver it doesn't say that every bugfix need to be released in a patch release --- it can very well be in minor release. It says the opposite implication --- patch releases can only contain bugfixes and nothing else.
(not to mention that aiida-core doesn't actually follow semver since we have breaking changes in minor releases often) :-D .

@danielhollas
Copy link
Collaborator

Anyway, this is obviously up to you, just wanted to flag this. :-)

btw: It looks like 2.7.1 is missing from CHANGELOG?

@GeigerJ2
Copy link
Contributor Author

GeigerJ2 commented Dec 5, 2025

Cheers, thanks for bringing this up, @danielhollas I thought more about it on the way home and I think you're right, better to have a smaller, more focused patch release 🙏🏻 Will take care of it on Monday!

lainme and others added 6 commits December 8, 2025 14:54
…ry detection (#6935)

Previously, the configuration directory lookup split the AIIDA_PATH environment variable using a hardcoded ':' separator, which caused issues on Windows systems where ';' is used as the path separator. This update introduces platform detection using sys.platform to select the correct separator for splitting paths, ensuring compatibility across operating systems.

---------

Co-authored-by: lainme <[email protected]>
Co-authored-by: Ali Khosravi <[email protected]>
(cherry picked from commit 32d515a)
…rchive file missing (#6929)

(cherry picked from commit 274ce67)
move values to insert to `execute` statement rather than `insert`

(cherry picked from commit 9bccdc8)
@GeigerJ2
Copy link
Contributor Author

GeigerJ2 commented Dec 8, 2025

Starting over again with less commits, and the PR descriptions non fucked up

@GeigerJ2 GeigerJ2 reopened this Dec 8, 2025
GeigerJ2 and others added 10 commits December 9, 2025 09:44
This fixes SQLAlchemy `OperationalError`s when creating large archives
with the PSQL backend by batching query filters using
`DEFAULT_FILTER_SIZE` (999). The default value was re-used from PR #6889
in which it was originally set to avoid exceeding the
`SQLITE_MAX_VARIABLE_NUMBER` limit for archive imports with the SQLite
backend.

Key changes:
- Add `filter_size` parameter to `create_archive()`,
  `_collect_required_entities()` and all helper functions called therein
  to apply batching to query filters, using the default value of 999
  (not exposed to the user via CLI)
- Move `batch_iter()` to `aiida.common.utils` for reuse
- Drop `QueryParams` in favor of the explicit `batch_size` and
  `filter_size` arguments
- Update graph traversal to batch node ID queries, as well

Some import functions still need batching (see #6907), which will be
done in a follow-up PR.

---------

Co-authored-by: Daniel Hollas <[email protected]>
(cherry picked from commit cfbbd68)
To avoid the command being seemingly stuck.

(cherry picked from commit fc00f5d)
For table construction, the pydantic `FieldInfo`s of each model field
are being used to exclude fields with `exclude_from_cli=True`. In
addition, `is_attribute` is being (mis)used (see comment in src) to
avoid bare `AtrributeError` exception handling, which otherwise captures
`filepath_files` of `PortableCode`, which is never set on the instance
or stored in the database after creation of the entity.

The meaningless `test_code_show` test function has been improved and
regression tests using the `file_regression` fixture were added that
compare the command output to the expected output, stored in `txt`
files. This ensures no other formatting changes appear in the future (no
duplications, wrong capitalization, etc., as resolved by this PR).

(cherry picked from commit 32742c0)
This is required if it's in the top folder (of the repository)
and will thus be put in the top folder of the SCRATCH directory
(AiiDA's RemoteData), otherwise the bash script (given to the
scheduler) will not be able to execute it, since `./` is not
typically on the bash's PATH environment variable for security
reasons.

Also, fixing a small bug where the PortableCode will not accept
using a binary defined in a subfolder of the Repository.

(cherry picked from commit 9256f2f)
Before this fix, those codes were not shown (e.g.,
PortableCodes). Now, they are properly added to the list.

(cherry picked from commit 27b52da)
* CI: Add Slack notification to install-with-conda-job

(cherry picked from commit 0dcd10a)
This should improve performance of async_ssh plugin
for lots of small files since we're no longer sleeping
500ms when waiting for a lock.

Also makes the code more safe since one doesn't need
to manually lock and unlock, and fixes a bug since the
number of file IO connections was not decreased
when an OsError exception was thrown.

(cherry picked from commit ad5cafd)
Use database-specific optimizations for large IN clauses in QB, reducing
parameter usage from N parameters (one per value) to 1 parameter per
list. This avoids hitting database parameter limits (SQLite: ~999,
PostgreSQL: ~65k) when filtering on large sets of IDs.

Implementation details:

PostgreSQL uses `unnest()` with native ARRAY types. The list is passed
as a single array parameter using `type_coerce()` (a Python-side
SQLAlchemy hint that doesn't generate SQL CAST). PostgreSQL natively
understands arrays, so values from `unnest()` are already properly
typed.

SQLite uses `json_each()` since it lacks native array support. The list
is serialized to JSON and passed as a single parameter. Since
`json_each()` returns all values as TEXT, explicit SQL CAST is required
to convert to the target column type.

For very large lists (>500k items), automatic batching splits them into
multiple OR'd conditions. The recursion depth is always exactly 2. The
first call splits into ≤500k batches, and recursive calls immediately
hit the base case since each batch is guaranteed to be ≤500k items.

This optimization eliminates the need for `filter_size` parameter
batching throughout the codebase, particularly in archive import/export
operations where large node sets are common.

(cherry picked from commit 8d562b4)
### Problem

  The JobsList class had a race condition where:
  1. Job A requests a status update, triggering a scheduler query
  2. While the scheduler is being queried (with only Job A), Job B also requests an update
  3. After the scheduler returns (with only Job A's status), both futures were resolved
  4. Job B's future was resolved as DONE, because AiiDA assumes any job ID that disappeared from the scheduler query has completed

  This premature "DONE" status causes several critical issues:
  - Premature retrieval: AiiDA attempts to retrieve output files while the job is still running
  - Corrupted files: Files may be incomplete or still being written when retrieved
  - False failure reports: Jobs still running may be incorrectly marked as failed

  This issue only surfaces when using async transport plugins like core.ssh_async or aiida-firecrest, where the timing conditions make the race condition more likely to occur.

  ### Solution

  Only resolve futures for jobs that were actually inspected by the scheduler

  ### Testing

  Added test_prevent_racing_condition which explicitly tests the race condition scenario

(cherry picked from commit e79f0a4)
The removal of the filter_size batching in #6998 caused the progress bar
to only update once at the end instead of incrementally. Here, we
re-introduce query batching (50k IDs per batch for UX) and added
QueryBuilder streaming-based progress updates (every ~10k entities) by
replacing the blocking list comprehension with an explicit for-loop.
Progress now updates during both query batching (for UX) and result
streaming.

(cherry picked from commit 4e54cd4)
@GeigerJ2 GeigerJ2 force-pushed the release/2.7.2 branch 2 times, most recently from 046da5e to 49d0614 Compare December 9, 2025 13:27
Comment on lines 784 to 789
Note: The 500k batch threshold is chosen to balance several factors: parameter limits
(each batch uses 1 parameter, allowing SQLite's 999-parameter limit to handle up to
~500M items and PostgreSQL's 65k-parameter limit to handle up to ~33B items), memory
constraints (in practice, Python memory becomes the bottleneck as a list of 500M items
would require 4-20GB RAM before reaching the database), and database performance
(modern databases handle 500k-item arrays/JSON easily on typical workstations and servers).
Copy link
Contributor Author

@GeigerJ2 GeigerJ2 Dec 9, 2025

Choose a reason for hiding this comment

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

Re-wrote this as a paragraph, as RTD was always failing with the previous text, complaining about the formatting of the lists (even when adding blank lines, I spent like an hour trying to resolve these complaints...):

  - "Bullet list ends without a blank line; unexpected unindent"
  - "Definition list ends without a blank line; unexpected unindent"

As I don't think this really matters, I re-wrote it as a non-rst plain text paragraph.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to merge this change separately to main first?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, yeah, that does make sense. I just realized that the offending RST code in the docstring might've passed CI on main as autodoc was being dropped before in #7056, so there was never a proper RST "compilation" step, and the issue went unnoticed. I went ahead and fixed it to use actual code directives for the SQL statements, so that RST doesn't mis-interpret them, and give misleading exceptions. Will open a PR, that should be possible to merge and cherry-pick here soon.

@GeigerJ2 GeigerJ2 force-pushed the release/2.7.2 branch 2 times, most recently from 65698c2 to 4b941ab Compare December 9, 2025 14:50
Comment on lines +11 to +12
from __future__ import annotations

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@GeigerJ2
Copy link
Contributor Author

GeigerJ2 commented Dec 9, 2025

Wow, OK, this process turned out to be more painful than I anticipated 😅
I got all the commits cherry-picked, using git cherry-pick -x in each case to automatically amend the (cherry picked from commit <original-hash>) rather than the patch-release.sh script, as the latter turned out to be useless due to the many conflicts that had to be manually resolved when selecting disconnected commits from main that would interrupt the script each time.

In addition, I added commit 4b941ab to make CI pass. Reasons for each change are in the comments above, @danielhollas, see here.

Now just missing a few final steps for tomorrow:

  • release commit
  • pushing to test-pypi
  • adding the tag
  • actually publish to pypi
  • announcements

:)

@GeigerJ2 GeigerJ2 marked this pull request as draft December 9, 2025 16:14
@GeigerJ2 GeigerJ2 requested review from danielhollas and khsrali and removed request for agoscinski and unkcpz December 9, 2025 16:15
Copy link
Collaborator

@danielhollas danielhollas left a comment

Choose a reason for hiding this comment

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

In addition, I added commit 4b941ab to make CI pass. Reasons for each change are in the comments above, @danielhollas, see here.

All looks good, thanks!

Now just missing a few final steps for tomorrow: release commit, pushing to test-pypi, adding the tag, actually publish to pypi, and announcements :)

You also need to add CHANGELOG right?

@GeigerJ2
Copy link
Contributor Author

Thanks for the assistance with this, @danielhollas 🫶

You also need to add CHANGELOG right?

Yes, that's part of the release commit :)

@GeigerJ2 GeigerJ2 marked this pull request as ready for review December 10, 2025 08:50
@GeigerJ2 GeigerJ2 merged commit 9d0a86f into support/2.7.x Dec 10, 2025
55 of 56 checks passed
@GeigerJ2 GeigerJ2 deleted the release/2.7.2 branch December 10, 2025 11:35
@GeigerJ2 GeigerJ2 restored the release/2.7.2 branch December 10, 2025 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants