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 595a841  Move the code to store an uploaded file to the release writer
595a841 is described below

commit 595a841d6e167edaf2555e2e5cf991fd939480c8
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu Sep 11 19:42:29 2025 +0100

    Move the code to store an uploaded file to the release writer
---
 atr/blueprints/api/api.py      | 25 +++----------------------
 atr/storage/writers/release.py | 24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index 200ba3a..f14fc49 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -16,7 +16,6 @@
 # under the License.
 
 
-import base64
 import hashlib
 import pathlib
 from typing import Any
@@ -883,7 +882,9 @@ async def release_upload(data: 
models.api.ReleaseUploadArgs) -> DictResponse:
     #     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)
+    async with storage.write(asf_uid) as write:
+        wacp = await write.as_project_committee_participant(data.project)
+        revision = await wacp.release.upload_file(data)
     return models.api.ReleaseUploadResults(
         endpoint="/release/upload",
         revision=revision,
@@ -1324,23 +1325,3 @@ def _simple_check(*args: str | None) -> None:
     for arg in args:
         if arg == "None":
             raise exceptions.BadRequest("Argument cannot be the string 'None'")
-
-
-async def _upload_process_file(args: models.api.ReleaseUploadArgs, asf_uid: 
str) -> sql.Revision:
-    file_bytes = base64.b64decode(args.content, validate=True)
-    file_path = args.relpath.lstrip("/")
-    description = f"Upload via API: {file_path}"
-    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:
-        release_name = sql.release_name(args.project, args.version)
-        return await data.revision(release_name=release_name, 
number=creating.new.number).demand(exceptions.NotFound())
diff --git a/atr/storage/writers/release.py b/atr/storage/writers/release.py
index 9b050aa..d9dd687 100644
--- a/atr/storage/writers/release.py
+++ b/atr/storage/writers/release.py
@@ -18,8 +18,10 @@
 # Removing this will cause circular imports
 from __future__ import annotations
 
+import base64
 import contextlib
 import datetime
+import pathlib
 from typing import TYPE_CHECKING
 
 import aiofiles.os
@@ -27,13 +29,13 @@ import aioshutil
 
 import atr.db as db
 import atr.log as log
+import atr.models.api as api
 import atr.models.sql as sql
 import atr.revision as revision
 import atr.storage as storage
 import atr.util as util
 
 if TYPE_CHECKING:
-    import pathlib
     from collections.abc import AsyncGenerator
 
 
@@ -170,6 +172,26 @@ class CommitteeParticipant(FoundationCommitter):
         )
         return release, project
 
+    async def upload_file(self, args: api.ReleaseUploadArgs) -> sql.Revision:
+        file_bytes = base64.b64decode(args.content, validate=True)
+        file_path = args.relpath.lstrip("/")
+        description = f"Upload via API: {file_path}"
+        async with self.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 storage.AccessError("File already exists")
+            async with aiofiles.open(target_path, "wb") as f:
+                await f.write(file_bytes)
+        if creating.new is None:
+            raise storage.AccessError("Failed to create revision")
+        async with db.session() as data:
+            release_name = sql.release_name(args.project, args.version)
+            return await data.revision(
+                release_name=release_name,
+                number=creating.new.number,
+            ).demand(storage.AccessError("Revision not found"))
+
 
 class CommitteeMember(CommitteeParticipant):
     def __init__(


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

Reply via email to