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-releases.git


The following commit(s) were added to refs/heads/main by this push:
     new 52562d7  Add a vote comment template to release policies
52562d7 is described below

commit 52562d71f59217a327e802d7636344b6db0a8c97
Author: Sean B. Palmer <[email protected]>
AuthorDate: Fri Dec 5 10:37:03 2025 +0000

    Add a vote comment template to release policies
---
 atr/get/projects.py                             |  1 +
 atr/get/vote.py                                 |  2 ++
 atr/models/policy.py                            |  2 ++
 atr/models/sql.py                               |  7 +++++++
 atr/post/projects.py                            |  3 +++
 atr/shared/projects.py                          |  5 +++++
 atr/storage/writers/policy.py                   |  1 +
 migrations/versions/0030_2025.12.05_211a31e3.py | 27 +++++++++++++++++++++++++
 8 files changed, 48 insertions(+)

diff --git a/atr/get/projects.py b/atr/get/projects.py
index e97a7f6..f18207b 100644
--- a/atr/get/projects.py
+++ b/atr/get/projects.py
@@ -527,6 +527,7 @@ def _render_vote_form(project: sql.Project) -> htm.Element:
         "min_hours": project.policy_min_hours,
         "pause_for_rm": project.policy_pause_for_rm,
         "release_checklist": project.policy_release_checklist or "",
+        "vote_comment_template": project.policy_vote_comment_template or "",
         "start_vote_template": project.policy_start_vote_template or "",
     }
 
diff --git a/atr/get/vote.py b/atr/get/vote.py
index c7a9c2a..f2fe7e0 100644
--- a/atr/get/vote.py
+++ b/atr/get/vote.py
@@ -513,12 +513,14 @@ async def _render_vote_authenticated(
         project_name=release.project.name,
         version_name=release.version,
     )
+    vote_comment_template = release.project.policy_vote_comment_template
     cast_vote_form = form.render(
         model_cls=shared.vote.CastVoteForm,
         action=vote_action_url,
         submit_label="Submit vote",
         form_classes=".atr-canary.py-4.px-5.mb-4.border.rounded",
         custom={"decision": vote_widget},
+        defaults={"comment": vote_comment_template},
     )
     page.append(cast_vote_form)
 
diff --git a/atr/models/policy.py b/atr/models/policy.py
index ecc88ac..6e5e793 100644
--- a/atr/models/policy.py
+++ b/atr/models/policy.py
@@ -44,6 +44,7 @@ class ReleasePolicyData(schema.Lax):
     min_hours: int = 72
     pause_for_rm: bool = False
     release_checklist: str = ""
+    vote_comment_template: str = ""
     default_start_vote_template_hash: str = ""
     start_vote_template: str = ""
     github_vote_workflow_path: list[str] = pydantic.Field(default_factory=list)
@@ -86,6 +87,7 @@ class ReleasePolicyData(schema.Lax):
     @pydantic.field_validator(
         "github_repository_name",
         "release_checklist",
+        "vote_comment_template",
         "start_vote_template",
         "announce_release_template",
         mode="before",
diff --git a/atr/models/sql.py b/atr/models/sql.py
index f5c63a7..2892d86 100644
--- a/atr/models/sql.py
+++ b/atr/models/sql.py
@@ -626,6 +626,12 @@ Thanks,
             return ""
         return policy.release_checklist
 
+    @property
+    def policy_vote_comment_template(self) -> str:
+        if ((policy := self.release_policy) is None) or 
(policy.vote_comment_template == ""):
+            return ""
+        return policy.vote_comment_template
+
     @property
     def policy_start_vote_template(self) -> str:
         if ((policy := self.release_policy) is None) or 
(policy.start_vote_template == ""):
@@ -980,6 +986,7 @@ class ReleasePolicy(sqlmodel.SQLModel, table=True):
     manual_vote: bool = sqlmodel.Field(default=False)
     min_hours: int | None = sqlmodel.Field(default=None)
     release_checklist: str = sqlmodel.Field(default="")
+    vote_comment_template: str = sqlmodel.Field(default="")
     pause_for_rm: bool = sqlmodel.Field(default=False)
     start_vote_template: str = sqlmodel.Field(default="")
     announce_release_template: str = sqlmodel.Field(default="")
diff --git a/atr/post/projects.py b/atr/post/projects.py
index 466b579..3f86ec6 100644
--- a/atr/post/projects.py
+++ b/atr/post/projects.py
@@ -217,6 +217,7 @@ async def _process_compose_form(
         min_hours=project.policy_min_hours,
         pause_for_rm=project.policy_pause_for_rm,
         release_checklist=project.policy_release_checklist or "",
+        vote_comment_template=project.policy_vote_comment_template or "",
         start_vote_template=project.policy_start_vote_template or "",
         github_finish_workflow_path=project.policy_github_finish_workflow_path,
         announce_release_template=project.policy_announce_release_template or 
"",
@@ -273,6 +274,7 @@ async def _process_finish_form(
         min_hours=project.policy_min_hours,
         pause_for_rm=project.policy_pause_for_rm,
         release_checklist=project.policy_release_checklist or "",
+        vote_comment_template=project.policy_vote_comment_template or "",
         start_vote_template=project.policy_start_vote_template or "",
         github_finish_workflow_path=[
             p.strip() for p in 
finish_form.github_finish_workflow_path.split("\n") if p.strip()
@@ -360,6 +362,7 @@ async def _process_vote_form(session: web.Committer, 
vote_form: shared.projects.
         min_hours=vote_form.min_hours,
         pause_for_rm=vote_form.pause_for_rm,
         release_checklist=vote_form.release_checklist or "",
+        vote_comment_template=vote_form.vote_comment_template or "",
         start_vote_template=vote_form.start_vote_template or "",
         github_finish_workflow_path=project.policy_github_finish_workflow_path,
         announce_release_template=project.policy_announce_release_template or 
"",
diff --git a/atr/shared/projects.py b/atr/shared/projects.py
index 6ae4da4..a663c16 100644
--- a/atr/shared/projects.py
+++ b/atr/shared/projects.py
@@ -180,6 +180,11 @@ class VotePolicyForm(form.Form):
         "Release checklist",
         widget=form.Widget.CUSTOM,
     )
+    vote_comment_template: str = form.label(
+        "Vote comment template",
+        "Plain text template for vote comments. Voters can edit before 
submitting.",
+        widget=form.Widget.TEXTAREA,
+    )
     start_vote_template: str = form.label(
         "Start vote template",
         "Email template for messages to start a vote on a release.",
diff --git a/atr/storage/writers/policy.py b/atr/storage/writers/policy.py
index 03d8192..89f7bf0 100644
--- a/atr/storage/writers/policy.py
+++ b/atr/storage/writers/policy.py
@@ -113,6 +113,7 @@ class CommitteeMember(CommitteeParticipant):
             self.__set_default_min_hours(policy_data, project, release_policy)
             release_policy.pause_for_rm = policy_data.pause_for_rm
             release_policy.release_checklist = policy_data.release_checklist
+            release_policy.vote_comment_template = 
policy_data.vote_comment_template
             self.__set_default_start_vote_template(policy_data, project, 
release_policy)
         elif project.committee and project.committee.is_podling:
             # The caller ensures that project.committee is not None
diff --git a/migrations/versions/0030_2025.12.05_211a31e3.py 
b/migrations/versions/0030_2025.12.05_211a31e3.py
new file mode 100644
index 0000000..172dd2e
--- /dev/null
+++ b/migrations/versions/0030_2025.12.05_211a31e3.py
@@ -0,0 +1,27 @@
+"""Add a field for vote comment templates
+
+Revision ID: 0030_2025.12.05_211a31e3
+Revises: 0029_2025.11.28_6486ff5e
+Create Date: 2025-12-05 10:25:32.833183+00:00
+"""
+
+from collections.abc import Sequence
+
+import sqlalchemy as sa
+from alembic import op
+
+# Revision identifiers, used by Alembic
+revision: str = "0030_2025.12.05_211a31e3"
+down_revision: str | None = "0029_2025.11.28_6486ff5e"
+branch_labels: str | Sequence[str] | None = None
+depends_on: str | Sequence[str] | None = None
+
+
+def upgrade() -> None:
+    with op.batch_alter_table("releasepolicy", schema=None) as batch_op:
+        batch_op.add_column(sa.Column("vote_comment_template", sa.String(), 
nullable=False, server_default=""))
+
+
+def downgrade() -> None:
+    with op.batch_alter_table("releasepolicy", schema=None) as batch_op:
+        batch_op.drop_column("vote_comment_template")


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

Reply via email to