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]