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 67bb9d0  Allow minimum vote duration to be nullable to act as a 
default value
67bb9d0 is described below

commit 67bb9d0b68c1eeafa343318fa85183f620c67dd3
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu May 29 17:22:03 2025 +0100

    Allow minimum vote duration to be nullable to act as a default value
---
 atr/db/models.py                                |  14 ++--
 atr/routes/projects.py                          | 100 ++++++++++++++----------
 atr/templates/project-view.html                 |   1 +
 migrations/versions/0005_2025.05.29_49f92935.py |  27 +++++++
 4 files changed, 95 insertions(+), 47 deletions(-)

diff --git a/atr/db/models.py b/atr/db/models.py
index 3155d1f..037eed5 100644
--- a/atr/db/models.py
+++ b/atr/db/models.py
@@ -120,7 +120,7 @@ class ReleasePolicy(sqlmodel.SQLModel, table=True):
     id: int = sqlmodel.Field(default=None, primary_key=True)
     mailto_addresses: list[str] = sqlmodel.Field(default_factory=list, 
sa_column=sqlalchemy.Column(sqlalchemy.JSON))
     manual_vote: bool = sqlmodel.Field(default=False)
-    min_hours: int = sqlmodel.Field(default=0)
+    min_hours: int | None = sqlmodel.Field(default=None)
     release_checklist: str = sqlmodel.Field(default="")
     pause_for_rm: bool = sqlmodel.Field(default=False)
     start_vote_template: str = sqlmodel.Field(default="")
@@ -313,6 +313,10 @@ Thanks,
 [YOUR_FULL_NAME] ([YOUR_ASF_ID])
 """
 
+    @property
+    def policy_default_min_hours(self) -> int:
+        return 72
+
     @property
     def policy_announce_release_template(self) -> str:
         if ((policy := self.release_policy) is None) or 
(policy.announce_release_template == ""):
@@ -335,11 +339,9 @@ Thanks,
 
     @property
     def policy_min_hours(self) -> int:
-        if ((policy := self.release_policy) is None) or (policy.min_hours == 
0):
-            # Not sure what the default should be
-            # Also, we can't use 0 as "default" because it's also "unlimited"
-            # This suggests that we make min_hours nullable and use None for 
the default value
-            return 72
+        if ((policy := self.release_policy) is None) or (policy.min_hours is 
None):
+            # TODO: Not sure what the default should be
+            return self.policy_default_min_hours
         return policy.min_hours
 
     @property
diff --git a/atr/routes/projects.py b/atr/routes/projects.py
index 2a9a332..5574235 100644
--- a/atr/routes/projects.py
+++ b/atr/routes/projects.py
@@ -52,6 +52,7 @@ class ReleasePolicyForm(util.QuartFormTyped):
     project_name = wtforms.HiddenField("project_name")
     default_start_vote_template_hash = wtforms.HiddenField()
     default_announce_release_template_hash = wtforms.HiddenField()
+    default_min_hours_value_at_render = wtforms.HiddenField()
 
     mailto_addresses = wtforms.FieldList(
         wtforms.StringField(
@@ -224,46 +225,18 @@ async def view(session: routes.CommitterSession, name: 
str) -> response.Response
             if quart.request.method == "POST":
                 form = await ReleasePolicyForm.create_form(data=await 
quart.request.form)
                 if await form.validate_on_submit():
-                    if project.release_policy is None:
-                        project.release_policy = 
models.ReleasePolicy(project=project)
-                        data.add(project.release_policy)
-
-                    project.release_policy.mailto_addresses = 
[util.unwrap(form.mailto_addresses.entries[0].data)]
-                    project.release_policy.manual_vote = 
util.unwrap(form.manual_vote.data)
-                    project.release_policy.min_hours = 
util.unwrap(form.min_hours.data)
-                    project.release_policy.release_checklist = 
util.unwrap(form.release_checklist.data)
-
-                    # Handle start_vote_template
-                    submitted_start_template = 
str(util.unwrap(form.start_vote_template.data))
-                    submitted_start_template = 
submitted_start_template.replace("\r\n", "\n")
-                    rendered_default_start_hash = 
str(util.unwrap(form.default_start_vote_template_hash.data))
-                    current_default_start_text = 
project.policy_start_vote_default
-                    current_default_start_hash = 
util.compute_sha3_256(current_default_start_text.encode())
-                    submitted_start_hash = 
util.compute_sha3_256(submitted_start_template.encode())
-
-                    if (submitted_start_hash == rendered_default_start_hash) 
or (
-                        submitted_start_hash == current_default_start_hash
-                    ):
-                        project.release_policy.start_vote_template = ""
-                    else:
-                        project.release_policy.start_vote_template = 
submitted_start_template
-
-                    # Handle announce_release_template
-                    submitted_announce_template = 
str(util.unwrap(form.announce_release_template.data))
-                    submitted_announce_template = 
submitted_announce_template.replace("\r\n", "\n")
-                    rendered_default_announce_hash = 
str(util.unwrap(form.default_announce_release_template_hash.data))
-                    current_default_announce_text = 
project.policy_announce_release_default
-                    current_default_announce_hash = 
util.compute_sha3_256(current_default_announce_text.encode())
-                    submitted_announce_hash = 
util.compute_sha3_256(submitted_announce_template.encode())
-
-                    if (submitted_announce_hash == 
rendered_default_announce_hash) or (
-                        submitted_announce_hash == 
current_default_announce_hash
-                    ):
-                        project.release_policy.announce_release_template = ""
-                    else:
-                        project.release_policy.announce_release_template = 
submitted_announce_template
-
-                    project.release_policy.pause_for_rm = 
util.unwrap(form.pause_for_rm.data)
+                    release_policy = project.release_policy
+                    if release_policy is None:
+                        release_policy = models.ReleasePolicy(project=project)
+                        project.release_policy = release_policy
+                        data.add(release_policy)
+
+                    release_policy.mailto_addresses = 
[util.unwrap(form.mailto_addresses.entries[0].data)]
+                    release_policy.manual_vote = 
util.unwrap(form.manual_vote.data)
+                    release_policy.release_checklist = 
util.unwrap(form.release_checklist.data)
+                    _set_default_fields(form, project, release_policy)
+
+                    release_policy.pause_for_rm = 
util.unwrap(form.pause_for_rm.data)
                     await data.commit()
                     await quart.flash("Release policy updated successfully.", 
"success")
                     return quart.redirect(util.as_url(view, name=project.name))
@@ -281,13 +254,15 @@ async def view(session: routes.CommitterSession, name: 
str) -> response.Response
                 form.start_vote_template.data = 
project.policy_start_vote_template
                 form.announce_release_template.data = 
project.policy_announce_release_template
                 form.pause_for_rm.data = project.policy_pause_for_rm
-                # Set the hashes of the current defaults
+
+                # Set the hashes and value of the current defaults
                 form.default_start_vote_template_hash.data = 
util.compute_sha3_256(
                     project.policy_start_vote_default.encode()
                 )
                 form.default_announce_release_template_hash.data = 
util.compute_sha3_256(
                     project.policy_announce_release_default.encode()
                 )
+                form.default_min_hours_value_at_render.data = 
str(project.policy_default_min_hours)
 
         return await template.render(
             "project-view.html",
@@ -374,3 +349,46 @@ async def _add_project(form: AddFormProtocol, asf_id: str) 
-> response.Response:
         await data.commit()
 
     return quart.redirect(util.as_url(view, name=new_project_label))
+
+
+def _set_default_fields(form: ReleasePolicyForm, project: models.Project, 
release_policy: models.ReleasePolicy) -> None:
+    # Handle start_vote_template
+    submitted_start_template = str(util.unwrap(form.start_vote_template.data))
+    submitted_start_template = submitted_start_template.replace("\r\n", "\n")
+    rendered_default_start_hash = 
str(util.unwrap(form.default_start_vote_template_hash.data))
+    current_default_start_text = project.policy_start_vote_default
+    current_default_start_hash = 
util.compute_sha3_256(current_default_start_text.encode())
+    submitted_start_hash = 
util.compute_sha3_256(submitted_start_template.encode())
+
+    if (submitted_start_hash == rendered_default_start_hash) or 
(submitted_start_hash == current_default_start_hash):
+        release_policy.start_vote_template = ""
+    else:
+        release_policy.start_vote_template = submitted_start_template
+
+    # Handle announce_release_template
+    submitted_announce_template = 
str(util.unwrap(form.announce_release_template.data))
+    submitted_announce_template = submitted_announce_template.replace("\r\n", 
"\n")
+    rendered_default_announce_hash = 
str(util.unwrap(form.default_announce_release_template_hash.data))
+    current_default_announce_text = project.policy_announce_release_default
+    current_default_announce_hash = 
util.compute_sha3_256(current_default_announce_text.encode())
+    submitted_announce_hash = 
util.compute_sha3_256(submitted_announce_template.encode())
+
+    if (submitted_announce_hash == rendered_default_announce_hash) or (
+        submitted_announce_hash == current_default_announce_hash
+    ):
+        release_policy.announce_release_template = ""
+    else:
+        release_policy.announce_release_template = submitted_announce_template
+
+    # Handle min_hours
+    submitted_min_hours = int(util.unwrap(form.min_hours.data) or 0)
+    default_value_seen_on_page_min_hours = 
int(util.unwrap(form.default_min_hours_value_at_render.data))
+    current_system_default_min_hours = project.policy_default_min_hours
+
+    if (
+        submitted_min_hours == default_value_seen_on_page_min_hours
+        or submitted_min_hours == current_system_default_min_hours
+    ):
+        release_policy.min_hours = None
+    else:
+        release_policy.min_hours = submitted_min_hours
diff --git a/atr/templates/project-view.html b/atr/templates/project-view.html
index 5f67b32..81fa53e 100644
--- a/atr/templates/project-view.html
+++ b/atr/templates/project-view.html
@@ -68,6 +68,7 @@
           {{ form.project_name(value=project.name) }}
           {{ form.default_start_vote_template_hash() }}
           {{ form.default_announce_release_template_hash() }}
+          {{ form.default_min_hours_value_at_render() }}
 
           <div class="mb-3 pb-3 row border-bottom">
             {{ forms.label(form.mailto_addresses.entries[0], col="md3") }}
diff --git a/migrations/versions/0005_2025.05.29_49f92935.py 
b/migrations/versions/0005_2025.05.29_49f92935.py
new file mode 100644
index 0000000..4b5a847
--- /dev/null
+++ b/migrations/versions/0005_2025.05.29_49f92935.py
@@ -0,0 +1,27 @@
+"""Make minimum vote duration nullable to signify default
+
+Revision ID: 0005_2025.05.29_49f92935
+Revises: 0004_2025.05.27_52cbd2b5
+Create Date: 2025-05-29 16:07:40.588955+00:00
+"""
+
+from collections.abc import Sequence
+
+import sqlalchemy as sa
+from alembic import op
+
+# Revision identifiers, used by Alembic
+revision: str = "0005_2025.05.29_49f92935"
+down_revision: str | None = "0004_2025.05.27_52cbd2b5"
+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.alter_column("min_hours", existing_type=sa.INTEGER(), 
nullable=True)
+
+
+def downgrade() -> None:
+    with op.batch_alter_table("releasepolicy", schema=None) as batch_op:
+        batch_op.alter_column("min_hours", existing_type=sa.INTEGER(), 
nullable=False)


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

Reply via email to