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 fcafec5 Distinguish between committers and contributors in the vote
summary
fcafec5 is described below
commit fcafec585e7b1fec97d0ff6f62e177d6bfda5b73
Author: Sean B. Palmer <[email protected]>
AuthorDate: Fri Jun 27 18:42:32 2025 +0100
Distinguish between committers and contributors in the vote summary
---
atr/routes/vote.py | 84 +++++++++++++++++++---------------------
atr/templates/vote-tabulate.html | 38 +++++++++++++++++-
2 files changed, 77 insertions(+), 45 deletions(-)
diff --git a/atr/routes/vote.py b/atr/routes/vote.py
index a2e0ee5..3900ae1 100644
--- a/atr/routes/vote.py
+++ b/atr/routes/vote.py
@@ -333,61 +333,57 @@ def _tabulate_vote_continue(line: str) -> bool:
async def _tabulate_vote_status(asf_uid: str, list_raw: str, release:
models.Release) -> str:
status = "Unknown"
+ committee = None
if util.is_dev_environment():
committee_label = list_raw.split(".apache.org", 1)[0].split(".", 1)[-1]
async with db.session() as data:
committee = await data.committee(name=committee_label).get()
- if committee is not None:
- if asf_uid in committee.committee_members:
- status = "Binding"
- else:
- status = "Non-binding"
elif release.project is not None:
- if release.project.committee is not None:
- print(repr(asf_uid), release.project.committee.committee_members)
- if asf_uid in release.project.committee.committee_members:
- status = "Binding"
- else:
- status = "Non-binding"
+ committee = release.project.committee
+ if committee is not None:
+ if asf_uid in committee.committee_members:
+ status = "Binding"
+ elif asf_uid in committee.committers:
+ status = "Committer"
+ else:
+ status = "Contributor"
return status
-def _tabulate_vote_summary(tabulated_votes: dict[str, VoteEmail]) -> str:
- binding_votes = 0
- binding_votes_yes = 0
- binding_votes_no = 0
- binding_votes_abstain = 0
- non_binding_votes = 0
- non_binding_votes_yes = 0
- non_binding_votes_no = 0
- non_binding_votes_abstain = 0
- other_votes = 0
+def _tabulate_vote_summary(tabulated_votes: dict[str, VoteEmail]) -> dict[str,
int]:
+ result = {
+ "binding_votes": 0,
+ "binding_votes_yes": 0,
+ "binding_votes_no": 0,
+ "binding_votes_abstain": 0,
+ "non_binding_votes": 0,
+ "non_binding_votes_yes": 0,
+ "non_binding_votes_no": 0,
+ "non_binding_votes_abstain": 0,
+ "unknown_votes": 0,
+ "unknown_votes_yes": 0,
+ "unknown_votes_no": 0,
+ "unknown_votes_abstain": 0,
+ }
+
for vote_email in tabulated_votes.values():
if vote_email.status == "Binding":
- binding_votes += 1
- if vote_email.vote.value == "Yes":
- binding_votes_yes += 1
- elif vote_email.vote.value == "No":
- binding_votes_no += 1
- else:
- binding_votes_abstain += 1
- elif vote_email.status == "Non-binding":
- non_binding_votes += 1
- if vote_email.vote.value == "Yes":
- non_binding_votes_yes += 1
- elif vote_email.vote.value == "No":
- non_binding_votes_no += 1
- else:
- non_binding_votes_abstain += 1
+ result["binding_votes"] += 1
+ result["binding_votes_yes"] += 1 if (vote_email.vote.value ==
"Yes") else 0
+ result["binding_votes_no"] += 1 if (vote_email.vote.value == "No")
else 0
+ result["binding_votes_abstain"] += 1 if (vote_email.vote.value ==
"Abstain") else 0
+ elif vote_email.status in {"Committer", "Contributor"}:
+ result["non_binding_votes"] += 1
+ result["non_binding_votes_yes"] += 1 if (vote_email.vote.value ==
"Yes") else 0
+ result["non_binding_votes_no"] += 1 if (vote_email.vote.value ==
"No") else 0
+ result["non_binding_votes_abstain"] += 1 if (vote_email.vote.value
== "Abstain") else 0
else:
- other_votes += 1
- return f"""\
-Binding votes: {binding_votes}
- ({binding_votes_yes} yes, {binding_votes_no} no, {binding_votes_abstain}
abstain).
-Non-binding votes: {non_binding_votes}
- ({non_binding_votes_yes} yes, {non_binding_votes_no} no,
{non_binding_votes_abstain} abstain).
-Other votes: {other_votes}.
-"""
+ result["unknown_votes"] += 1
+ result["unknown_votes_yes"] += 1 if (vote_email.vote.value ==
"Yes") else 0
+ result["unknown_votes_no"] += 1 if (vote_email.vote.value == "No")
else 0
+ result["unknown_votes_abstain"] += 1 if (vote_email.vote.value ==
"Abstain") else 0
+
+ return result
async def _task_archive_url(task_mid: str) -> str | None:
diff --git a/atr/templates/vote-tabulate.html b/atr/templates/vote-tabulate.html
index 2877931..88bd74a 100644
--- a/atr/templates/vote-tabulate.html
+++ b/atr/templates/vote-tabulate.html
@@ -50,7 +50,43 @@
{% endfor %}
</tbody>
</table>
- {% if summary %}<p>{{ summary }}</p>{% endif %}
+ {% if summary %}
+ <h2>Vote summary</h2>
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th>Vote type</th>
+ <th>Yes</th>
+ <th>No</th>
+ <th>Abstain</th>
+ <th>Total</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Binding votes</td>
+ <td>{{ summary.binding_votes_yes }}</td>
+ <td>{{ summary.binding_votes_no }}</td>
+ <td>{{ summary.binding_votes_abstain }}</td>
+ <td>{{ summary.binding_votes }}</td>
+ </tr>
+ <tr>
+ <td>Non-binding votes</td>
+ <td>{{ summary.non_binding_votes_yes }}</td>
+ <td>{{ summary.non_binding_votes_no }}</td>
+ <td>{{ summary.non_binding_votes_abstain }}</td>
+ <td>{{ summary.non_binding_votes }}</td>
+ </tr>
+ <tr>
+ <td>Unknown votes</td>
+ <td>{{ summary.unknown_votes_yes }}</td>
+ <td>{{ summary.unknown_votes_no }}</td>
+ <td>{{ summary.unknown_votes_abstain }}</td>
+ <td>{{ summary.unknown_votes }}</td>
+ </tr>
+ </tbody>
+ </table>
+ {% endif %}
{% else %}
<p>No votes tabulated yet.</p>
{% endif %}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]