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]