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 cfd3bbc  Use the storage interface code to start votes in the API
cfd3bbc is described below

commit cfd3bbcb7476b22ba081a08f7854180fab4a1606
Author: Sean B. Palmer <[email protected]>
AuthorDate: Fri Sep 5 19:08:44 2025 +0100

    Use the storage interface code to start votes in the API
---
 atr/blueprints/api/api.py   | 12 +++++++--
 atr/routes/voting.py        | 10 +++----
 atr/storage/writers/vote.py | 66 ++++++++++-----------------------------------
 3 files changed, 29 insertions(+), 59 deletions(-)

diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index cf0b81c..7283e47 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -1146,15 +1146,23 @@ async def vote_start(data: models.api.VoteStartArgs) -> 
DictResponse:
     try:
         async with storage.write(asf_uid) as write:
             wacm = await write.as_project_committee_member(data.project)
-            task = await wacm.vote.start_api(
+            # TODO: Get fullname and use instead of asf_uid
+            task = await wacm.vote.start(
+                data.email_to,
                 data.project,
                 data.version,
                 data.revision,
-                data.email_to,
                 data.vote_duration,
                 data.subject,
                 data.body,
+                asf_uid,
+                asf_uid,
             )
+    # except Exception as e:
+    #     import traceback
+    #     import atr.log as log
+    #     log.info(traceback.format_exc())
+    #     raise exceptions.BadRequest(str(e))
     except storage.AccessError as e:
         raise exceptions.BadRequest(str(e))
 
diff --git a/atr/routes/voting.py b/atr/routes/voting.py
index 7691814..7d903f0 100644
--- a/atr/routes/voting.py
+++ b/atr/routes/voting.py
@@ -256,19 +256,19 @@ async def _selected_revision_data(
         if release.committee is None:
             raise base.ASFQuartException("Release has no associated 
committee", errorcode=400)
         async with storage.write_as_committee_member(release.committee.name) 
as wacm:
-            await wacm.vote.start(
+            _task = await wacm.vote.start(
                 email_to,
-                permitted_recipients,
                 project_name,
                 version_name,
                 revision,
-                session.uid,
-                session.fullname,
                 vote_duration_choice,
                 subject_data,
                 body_data,
-                release,
+                session.uid,
+                session.fullname,
+                release=release,
                 promote=True,
+                permitted_recipients=permitted_recipients,
             )
         return await session.redirect(
             vote.selected,
diff --git a/atr/storage/writers/vote.py b/atr/storage/writers/vote.py
index b8cb8b5..76eddc8 100644
--- a/atr/storage/writers/vote.py
+++ b/atr/storage/writers/vote.py
@@ -280,18 +280,27 @@ class CommitteeMember(CommitteeParticipant):
     async def start(
         self,
         email_to: str,
-        permitted_recipients: list[str],
         project_name: str,
         version_name: str,
         selected_revision_number: str,
-        asf_uid: str,
-        asf_fullname: str,
         vote_duration_choice: int,
         subject_data: str,
         body_data: str,
-        release: sql.Release,
+        asf_uid: str,
+        asf_fullname: str,
+        release: sql.Release | None = None,
         promote: bool = True,
-    ) -> str:
+        permitted_recipients: list[str] | None = None,
+    ) -> sql.Task:
+        if release is None:
+            release = await self.__data.release(
+                project_name=project_name,
+                version=version_name,
+                _project=True,
+                _committee=True,
+            ).demand(storage.AccessError("Release not found"))
+        if permitted_recipients is None:
+            permitted_recipients = util.permitted_recipients(asf_uid)
         if email_to not in permitted_recipients:
             # This will be checked again by tasks/vote.py for extra safety
             log.info(f"Invalid mailing list choice: {email_to} not in 
{permitted_recipients}")
@@ -335,53 +344,6 @@ class CommitteeMember(CommitteeParticipant):
         # TODO: We should log all outgoing email and the session so that users 
can confirm
         # And can be warned if there was a failure
         # (The message should be shown on the vote resolution page)
-        return f"The vote announcement email will soon be sent to {email_to}."
-
-    async def start_api(
-        self,
-        project_name: str,
-        version_name: str,
-        revision_number: str,
-        email_to: str,
-        vote_duration: int,
-        subject: str,
-        body: str,
-    ) -> sql.Task:
-        release_name = sql.release_name(project_name, version_name)
-        release = await self.__data.release(name=release_name, _project=True, 
_committee=True).demand(
-            storage.AccessError("Release not found")
-        )
-        if release.project.committee is None:
-            raise storage.AccessError("Project has no committee")
-        self.__committee_member_or_admin(release.project.committee, 
self.__asf_uid)
-
-        revision_exists = await 
self.__data.revision(release_name=release_name, number=revision_number).get()
-        if revision_exists is None:
-            raise storage.AccessError(f"Revision '{revision_number}' does not 
exist")
-
-        error = await interaction.promote_release(self.__data, release_name, 
revision_number, vote_manual=False)
-        if error:
-            raise storage.AccessError(error)
-
-        # TODO: Move this into a function in routes/voting.py
-        task = sql.Task(
-            status=sql.TaskStatus.QUEUED,
-            task_type=sql.TaskType.VOTE_INITIATE,
-            task_args=tasks_vote.Initiate(
-                release_name=release_name,
-                email_to=email_to,
-                vote_duration=vote_duration,
-                initiator_id=self.__asf_uid,
-                initiator_fullname=self.__asf_uid,
-                subject=subject,
-                body=body,
-            ).model_dump(),
-            asf_uid=self.__asf_uid,
-            project_name=project_name,
-            version_name=version_name,
-        )
-        self.__data.add(task)
-        await self.__data.commit()
         return task
 
     def __committee_member_or_admin(self, committee: sql.Committee, asf_uid: 
str) -> None:


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

Reply via email to