You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by ar...@apache.org on 2026/04/13 10:22:22 UTC
(tooling-trusted-releases) 01/01: #1002 - Validate vote duration (and fix API recipient handling)
This is an automated email from the ASF dual-hosted git repository.
arm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
commit f2672f18253c5b6e0ee754437323e9ca13979234
Author: Alastair McFarlane <ar...@apache.org>
AuthorDate: Mon Apr 13 11:03:50 2026 +0100
#1002 - Validate vote duration (and fix API recipient handling)
---
atr/api/__init__.py | 5 +++++
atr/get/voting.py | 4 ++--
atr/models/api.py | 4 +++-
atr/shared/voting.py | 6 ++++++
atr/util.py | 8 ++++++++
5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/atr/api/__init__.py b/atr/api/__init__.py
index 003a0774..fcee20f2 100644
--- a/atr/api/__init__.py
+++ b/atr/api/__init__.py
@@ -1609,6 +1609,9 @@ async def vote_start(
permitted_recipients = util.permitted_voting_recipients(asf_uid, wacp.committee_key)
if data.email_to not in permitted_recipients:
raise exceptions.Forbidden("Invalid mailing list choice")
+
+ util.validate_email_recipients(data)
+ util.validate_vote_duration(data.vote_duration)
# TODO: Get fullname and use instead of asf_uid
task = await wacp.vote.start(
data.email_to,
@@ -1620,6 +1623,8 @@ async def vote_start(
data.body,
asf_uid,
asf_uid,
+ email_cc=data.email_cc,
+ email_bcc=data.email_bcc,
)
# except Exception as e:
# import traceback
diff --git a/atr/get/voting.py b/atr/get/voting.py
index 22c4ca3a..cdf2c054 100644
--- a/atr/get/voting.py
+++ b/atr/get/voting.py
@@ -71,8 +71,8 @@ async def selected_revision(
permitted_recipients = util.permitted_voting_recipients(session.uid, committee.key)
min_hours = 72
- if release.release_policy and (release.release_policy.min_hours is not None):
- min_hours = release.release_policy.min_hours
+ if release.project.release_policy and (release.project.release_policy.min_hours is not None):
+ min_hours = release.project.release_policy.min_hours
default_subject_template = await construct.start_vote_subject_default(project_key)
default_body_template = await construct.start_vote_default(project_key)
diff --git a/atr/models/api.py b/atr/models/api.py
index b0d27689..a623b2ca 100644
--- a/atr/models/api.py
+++ b/atr/models/api.py
@@ -613,7 +613,9 @@ class VoteStartArgs(schema.Strict):
version: safe.VersionKey = schema.example("0.0.1")
revision: safe.RevisionNumber = schema.example("00005")
email_to: str = schema.example("dev@example.apache.org")
- vote_duration: int = schema.example(10)
+ email_cc: list[str] = schema.default_example([], "[dev@example.apache.org]")
+ email_bcc: list[str] = schema.default_example([], "[dev@example.apache.org]")
+ vote_duration: int = schema.example(72)
subject: str = schema.example("[VOTE] Apache Example 0.0.1 release")
body: str = schema.example("The Apache Example team is pleased to announce the release of Example 0.0.1...")
diff --git a/atr/shared/voting.py b/atr/shared/voting.py
index dd44e20d..2ad1306e 100644
--- a/atr/shared/voting.py
+++ b/atr/shared/voting.py
@@ -34,6 +34,12 @@ class StartVotingForm(form.Form):
subject_template_hash: str = form.label("Subject template hash", widget=form.Widget.HIDDEN)
body: str = form.label("Body", widget=form.Widget.CUSTOM)
+ @pydantic.field_validator("vote_duration")
+ @classmethod
+ def validate_vote_duration(cls, field):
+ util.validate_vote_duration(field)
+ return field
+
@pydantic.model_validator(mode="after")
def _validate_recipients(self) -> "StartVotingForm":
util.validate_email_recipients(self)
diff --git a/atr/util.py b/atr/util.py
index 7d5be1ab..77f3504f 100644
--- a/atr/util.py
+++ b/atr/util.py
@@ -1118,6 +1118,14 @@ def validate_trusted_publishing_constraints(
raise ValueError("GitHub workflow paths must start with '.github/workflows/'.")
+def validate_vote_duration(duration: int):
+ if duration == 0:
+ return
+ if duration > 0:
+ if duration < 72 or duration > 168:
+ raise ValueError("Vote duration must be between 0 and 168")
+
+
# TODO: AM put these rules into safe.versionkey
def version_key_error(version_key: str) -> str | None:
"""Check if the given version name is valid."""
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org