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

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


The following commit(s) were added to refs/heads/main by this push:
     new 055b942  Add a wrapper around the revision creation code to the 
storage interface
055b942 is described below

commit 055b942ca338d22dfbdd27443e63bc5a975b6065
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed Sep 10 19:33:04 2025 +0100

    Add a wrapper around the revision creation code to the storage interface
---
 atr/blueprints/api/api.py      | 25 ++++++++++++++-----------
 atr/revision.py                |  2 --
 atr/storage/writers/release.py | 11 +++++++++++
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index dae9d8a..200ba3a 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -37,7 +37,6 @@ import atr.db.interaction as interaction
 import atr.jwtoken as jwtoken
 import atr.models as models
 import atr.models.sql as sql
-import atr.revision as revision
 import atr.storage as storage
 import atr.storage.outcome as outcome
 import atr.storage.types as types
@@ -878,11 +877,11 @@ async def release_upload(data: 
models.api.ReleaseUploadArgs) -> DictResponse:
     """
     asf_uid = _jwt_asf_uid()
 
-    async with db.session() as db_data:
-        project = await db_data.project(name=data.project, 
_committee=True).demand(exceptions.NotFound())
-        # TODO: user.is_participant(project, asf_uid)
-        if not (user.is_committee_member(project.committee, asf_uid) or 
user.is_admin(asf_uid)):
-            raise exceptions.Forbidden("You do not have permission to upload 
to this project")
+    # async with db.session() as db_data:
+    #     project = await db_data.project(name=data.project, 
_committee=True).demand(exceptions.NotFound())
+    #     # TODO: user.is_participant(project, asf_uid)
+    #     if not (user.is_committee_member(project.committee, asf_uid) or 
user.is_admin(asf_uid)):
+    #         raise exceptions.Forbidden("You do not have permission to upload 
to this project")
 
     revision = await _upload_process_file(data, asf_uid)
     return models.api.ReleaseUploadResults(
@@ -1331,11 +1330,15 @@ async def _upload_process_file(args: 
models.api.ReleaseUploadArgs, asf_uid: str)
     file_bytes = base64.b64decode(args.content, validate=True)
     file_path = args.relpath.lstrip("/")
     description = f"Upload via API: {file_path}"
-    async with revision.create_and_manage(args.project, args.version, asf_uid, 
description=description) as creating:
-        target_path = pathlib.Path(creating.interim_path) / file_path
-        await aiofiles.os.makedirs(target_path.parent, exist_ok=True)
-        async with aiofiles.open(target_path, "wb") as f:
-            await f.write(file_bytes)
+    async with storage.write(asf_uid) as write:
+        wacm = await write.as_project_committee_participant(args.project)
+        async with wacm.release.create_and_manage_revision(args.project, 
args.version, description) as creating:
+            target_path = pathlib.Path(creating.interim_path) / file_path
+            await aiofiles.os.makedirs(target_path.parent, exist_ok=True)
+            if target_path.exists():
+                raise exceptions.BadRequest("File already exists")
+            async with aiofiles.open(target_path, "wb") as f:
+                await f.write(file_bytes)
     if creating.new is None:
         raise exceptions.InternalServerError("Failed to create revision")
     async with db.session() as data:
diff --git a/atr/revision.py b/atr/revision.py
index fcf8ba5..e0aa4b6 100644
--- a/atr/revision.py
+++ b/atr/revision.py
@@ -64,8 +64,6 @@ class SafeSession:
         return False
 
 
-# NOTE: The create_directory parameter is not used anymore
-# The temporary directory will always be created
 @contextlib.asynccontextmanager
 async def create_and_manage(
     project_name: str,
diff --git a/atr/storage/writers/release.py b/atr/storage/writers/release.py
index bfbfea1..b0b2475 100644
--- a/atr/storage/writers/release.py
+++ b/atr/storage/writers/release.py
@@ -18,6 +18,7 @@
 # Removing this will cause circular imports
 from __future__ import annotations
 
+import contextlib
 import datetime
 from typing import TYPE_CHECKING
 
@@ -33,6 +34,7 @@ import atr.util as util
 
 if TYPE_CHECKING:
     import pathlib
+    from collections.abc import AsyncGenerator
 
 
 class GeneralPublic:
@@ -78,6 +80,15 @@ class CommitteeParticipant(FoundationCommitter):
         self.__asf_uid = asf_uid
         self.__committee_name = committee_name
 
+    @contextlib.asynccontextmanager
+    async def create_and_manage_revision(
+        self, project_name: str, version: str, description: str
+    ) -> AsyncGenerator[revision.Creating]:
+        async with revision.create_and_manage(
+            project_name, version, self.__asf_uid, description=description
+        ) as _creating:
+            yield _creating
+
     async def start(self, project_name: str, version: str) -> 
tuple[sql.Release, sql.Project]:
         """Creates the initial release draft record and revision directory."""
         # Get the project from the project name


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

Reply via email to