This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch sbp
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git


The following commit(s) were added to refs/heads/sbp by this push:
     new 5b874ed  Compute attestable metadata before starting a database 
transaction
5b874ed is described below

commit 5b874ed28d29633cc04b35c70a3378dca6dc63c2
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Feb 10 19:05:39 2026 +0000

    Compute attestable metadata before starting a database transaction
---
 atr/attestable.py               | 46 ++++++++++++++++++++---------------------
 atr/storage/writers/revision.py | 21 ++++++++++++++++---
 2 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/atr/attestable.py b/atr/attestable.py
index f487d9e..d4d6d15 100644
--- a/atr/attestable.py
+++ b/atr/attestable.py
@@ -131,18 +131,30 @@ def migrate_to_paths_files() -> int:
     return count
 
 
+async def paths_to_hashes_and_sizes(directory: pathlib.Path) -> 
tuple[dict[str, str], dict[str, int]]:
+    path_to_hash: dict[str, str] = {}
+    path_to_size: dict[str, int] = {}
+    async for rel_path in util.paths_recursive(directory):
+        full_path = directory / rel_path
+        path_key = str(rel_path)
+        if "\\" in path_key:
+            # TODO: We should centralise this, and forbid some other 
characters too
+            raise ValueError(f"Backslash in path is forbidden: {path_key}")
+        path_to_hash[path_key] = await compute_file_hash(full_path)
+        path_to_size[path_key] = (await aiofiles.os.stat(full_path)).st_size
+    return path_to_hash, path_to_size
+
+
 async def write(
-    release_directory: pathlib.Path,
     project_name: str,
     version_name: str,
     revision_number: str,
     uploader_uid: str,
-    parent_revision_number: str | None,
+    previous: models.AttestableV1 | None,
+    path_to_hash: dict[str, str],
+    path_to_size: dict[str, int],
 ) -> None:
-    previous: models.AttestableV1 | None = None
-    if parent_revision_number is not None:
-        previous = await load(project_name, version_name, 
parent_revision_number)
-    result = await _generate(release_directory, revision_number, uploader_uid, 
previous)
+    result = _generate(path_to_hash, path_to_size, revision_number, 
uploader_uid, previous)
     file_path = attestable_path(project_name, version_name, revision_number)
     await util.atomic_write_file(file_path, result.model_dump_json(indent=2))
     paths_result = models.AttestablePathsV1(paths=result.paths)
@@ -185,27 +197,15 @@ def _compute_hashes_with_attribution(
     return new_hashes
 
 
-async def _generate(
-    directory: pathlib.Path,
+def _generate(
+    path_to_hash: dict[str, str],
+    path_to_size: dict[str, int],
     revision_number: str,
     uploader_uid: str,
     previous: models.AttestableV1 | None,
 ) -> models.AttestableV1:
-    current_path_to_hash: dict[str, str] = {}
     current_hash_to_paths: dict[str, set[str]] = {}
-    path_to_size: dict[str, int] = {}
-
-    async for rel_path in util.paths_recursive(directory):
-        full_path = directory / rel_path
-        path_key = str(rel_path)
-        if "\\" in path_key:
-            # TODO: We should centralise this, and forbid some other 
characters too
-            raise ValueError(f"Backslash in path is forbidden: {path_key}")
-        hash_ref = await compute_file_hash(full_path)
-        file_size = (await aiofiles.os.stat(full_path)).st_size
-
-        current_path_to_hash[path_key] = hash_ref
-        path_to_size[path_key] = file_size
+    for path_key, hash_ref in path_to_hash.items():
         current_hash_to_paths.setdefault(hash_ref, set()).add(path_key)
 
     new_hashes = _compute_hashes_with_attribution(
@@ -213,6 +213,6 @@ async def _generate(
     )
 
     return models.AttestableV1(
-        paths=dict(current_path_to_hash),
+        paths=dict(path_to_hash),
         hashes=dict(new_hashes),
     )
diff --git a/atr/storage/writers/revision.py b/atr/storage/writers/revision.py
index 0bc1f11..e776fc3 100644
--- a/atr/storage/writers/revision.py
+++ b/atr/storage/writers/revision.py
@@ -105,7 +105,7 @@ class CommitteeParticipant(FoundationCommitter):
         self.__committee_name = committee_name
 
     @contextlib.asynccontextmanager
-    async def create_and_manage(
+    async def create_and_manage(  # noqa: C901
         self,
         project_name: str,
         version_name: str,
@@ -165,6 +165,16 @@ class CommitteeParticipant(FoundationCommitter):
             await aioshutil.rmtree(temp_dir)
             raise
 
+        try:
+            path_to_hash, path_to_size = await 
attestable.paths_to_hashes_and_sizes(temp_dir_path)
+            parent_revision_number = old_revision.number if old_revision else 
None
+            previous_attestable = None
+            if parent_revision_number is not None:
+                previous_attestable = await attestable.load(project_name, 
version_name, parent_revision_number)
+        except Exception:
+            await aioshutil.rmtree(temp_dir)
+            raise
+
         async with SafeSession(temp_dir) as data:
             try:
                 # This is the only place where models.Revision is constructed
@@ -206,9 +216,14 @@ class CommitteeParticipant(FoundationCommitter):
                 await aioshutil.rmtree(temp_dir)
                 raise
 
-            parent_revision_number = old_revision.number if old_revision else 
None
             await attestable.write(
-                new_revision_dir, project_name, version_name, 
new_revision.number, asf_uid, parent_revision_number
+                project_name,
+                version_name,
+                new_revision.number,
+                asf_uid,
+                previous_attestable,
+                path_to_hash,
+                path_to_size,
             )
 
             # Commit to end the transaction started by data.begin_immediate


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to