You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by sb...@apache.org on 2025/03/26 18:37:06 UTC
(tooling-trusted-release) branch main updated: Allow some projects and release functions to be used for URL construction
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 a1b90d7 Allow some projects and release functions to be used for URL construction
a1b90d7 is described below
commit a1b90d71f23e6c787badc6254a33b325ded7315d
Author: Sean B. Palmer <se...@miscoranda.com>
AuthorDate: Wed Mar 26 20:36:42 2025 +0200
Allow some projects and release functions to be used for URL construction
---
atr/routes/candidate.py | 1 -
atr/routes/projects.py | 6 +--
atr/routes/release.py | 38 +++++------------
atr/templates/candidate-review.html | 82 +------------------------------------
atr/templates/keys-review.html | 2 +-
atr/templates/project-view.html | 2 +-
atr/templates/release-vote.html | 2 +-
7 files changed, 17 insertions(+), 116 deletions(-)
diff --git a/atr/routes/candidate.py b/atr/routes/candidate.py
index b83998a..6de758b 100644
--- a/atr/routes/candidate.py
+++ b/atr/routes/candidate.py
@@ -167,7 +167,6 @@ async def review(session: routes.CommitterSession) -> str:
# Get all releases where the user is a PMC member or committer
# TODO: We don't actually record who uploaded the release candidate
# We should probably add that information!
- # TODO: This duplicates code in root_package_add
releases = await data.release(
stage=models.ReleaseStage.CANDIDATE,
_committee=True,
diff --git a/atr/routes/projects.py b/atr/routes/projects.py
index 6d89060..d20fbe3 100644
--- a/atr/routes/projects.py
+++ b/atr/routes/projects.py
@@ -19,7 +19,6 @@
import http.client
-import asfquart.auth as auth
import asfquart.base as base
import quart
import werkzeug.wrappers.response as response
@@ -111,9 +110,8 @@ async def root_projects_vote_policy_add(project_name: str) -> response.Response
)
-@routes.app_route("/projects/<project_name>/vote-policy/edit", methods=["GET", "POST"])
-@auth.require(auth.Requirements.committer)
-async def root_projects_vote_policy_edit(project_name: str) -> response.Response | str:
+@routes.committer_route("/projects/<project_name>/vote-policy/edit", methods=["GET", "POST"])
+async def projects_vote_policy_edit(session: routes.CommitterSession, project_name: str) -> response.Response | str:
uid = await util.get_asf_id_or_die()
async with db.session() as data:
diff --git a/atr/routes/release.py b/atr/routes/release.py
index dd5c3ba..0aaa5d3 100644
--- a/atr/routes/release.py
+++ b/atr/routes/release.py
@@ -23,9 +23,7 @@ import logging.handlers
import aiofiles.os
import aioshutil
import asfquart
-import asfquart.auth as auth
import asfquart.base as base
-import asfquart.session as session
import quart
import werkzeug.wrappers.response as response
@@ -59,14 +57,9 @@ async def release_delete_validate(data: db.Session, release_name: str, session_u
return release
-@routes.app_route("/release/delete", methods=["POST"])
-@auth.require(auth.Requirements.committer)
-async def root_release_delete() -> response.Response:
+@routes.committer_route("/release/delete", methods=["POST"])
+async def delete(session: routes.CommitterSession) -> response.Response:
"""Delete a release and all its associated files."""
- web_session = await session.read()
- if (web_session is None) or (web_session.uid is None):
- raise base.ASFQuartException("Not authenticated", errorcode=401)
-
form = await routes.get_form(quart.request)
release_name = form.get("release_name")
@@ -78,7 +71,7 @@ async def root_release_delete() -> response.Response:
async with data.begin():
try:
# First validate and get the release info
- release = await release_delete_validate(data, release_name, web_session.uid)
+ release = await release_delete_validate(data, release_name, session.uid)
project_name = release.project.name
version = release.version
@@ -99,14 +92,9 @@ async def root_release_delete() -> response.Response:
return quart.redirect(util.as_url(candidate.review))
-@routes.app_route("/release/bulk/<int:task_id>", methods=["GET"])
-async def release_bulk_status(task_id: int) -> str | response.Response:
+@routes.committer_route("/release/bulk/<int:task_id>", methods=["GET"])
+async def release_bulk_status(session: routes.CommitterSession, task_id: int) -> str | response.Response:
"""Show status for a bulk download task."""
- web_session = await session.read()
- if (web_session is None) or (web_session.uid is None):
- await quart.flash("You must be logged in to view bulk download status.", "error")
- return quart.redirect(quart.url_for("root_login"))
-
async with db.session() as data:
# Query for the task with the given ID
task = await data.task(id=task_id).get()
@@ -133,8 +121,8 @@ async def release_bulk_status(task_id: int) -> str | response.Response:
# Check whether the user has permission to view this task
# Either they're a PMC member or committer for the release's PMC
if release and release.committee:
- if (web_session.uid not in release.committee.committee_members) and (
- web_session.uid not in release.committee.committers
+ if (session.uid not in release.committee.committee_members) and (
+ session.uid not in release.committee.committers
):
await quart.flash("You don't have permission to view this task.", "error")
return quart.redirect(util.as_url(candidate.review))
@@ -142,15 +130,9 @@ async def release_bulk_status(task_id: int) -> str | response.Response:
return await quart.render_template("release-bulk.html", task=task, release=release, TaskStatus=models.TaskStatus)
-@routes.app_route("/release/vote", methods=["GET", "POST"])
-@auth.require(auth.Requirements.committer)
-async def root_release_vote() -> response.Response | str:
+@routes.committer_route("/release/vote", methods=["GET", "POST"])
+async def vote(session: routes.CommitterSession) -> response.Response | str:
"""Show the vote initiation form for a release."""
-
- web_session = await session.read()
- if web_session is None:
- raise base.ASFQuartException("Not authenticated", errorcode=401)
-
release_name = quart.request.args.get("release_name", "")
form = None
if quart.request.method == "POST":
@@ -190,7 +172,7 @@ async def root_release_vote() -> response.Response | str:
vote_duration,
gpg_key_id,
commit_hash,
- web_session.uid,
+ session.uid,
],
)
async with db.create_async_db_session() as db_session:
diff --git a/atr/templates/candidate-review.html b/atr/templates/candidate-review.html
index 21a800e..5d5e143 100644
--- a/atr/templates/candidate-review.html
+++ b/atr/templates/candidate-review.html
@@ -42,7 +42,7 @@
</div>
<div class="d-flex gap-3 align-items-center pt-2">
<form method="post"
- action="{{ url_for('root_release_delete') }}"
+ action="{{ as_url(routes.release.delete) }}"
class="d-inline-block m-0">
<input type="hidden" name="release_name" value="{{ release.name }}" />
<button type="submit"
@@ -52,88 +52,10 @@
</button>
</form>
<a class="btn btn-primary"
- href="{{ url_for('root_release_vote', release_name=release.name) }}">Start vote</a>
+ href="{{ as_url(routes.release.vote, release_name=release.name) }}">Start vote</a>
</div>
</div>
</div>
-
- {% for package in release.packages %}
- <table class="table border border-1 mb-4 table-bordered candidate-table atr-data">
- <tr>
- <th>Name</th>
- <td>
- {{ format_artifact_name(release.project.name if release.project else "unknown", release.version, release.committee.is_podling) }}
- </td>
- </tr>
- <tr>
- <th>Artifact filename</th>
- <td>{{ package.filename }}</td>
- </tr>
- <tr>
- <th>File size</th>
- <td>{{ format_file_size(package.bytes_size) }}</td>
- </tr>
- <tr>
- <th>Uploaded</th>
- <td>{{ package.uploaded.strftime("%Y-%m-%d %H:%M UTC") }}</td>
- </tr>
- <tr>
- <th>Package checks</th>
- <td>
- {% set total_tasks = package.tasks|length %}
- {% set pending_tasks = package.tasks|selectattr("status.value", "==", "queued")|list|length %}
- {% set running_tasks = package.tasks|selectattr("status.value", "==", "active")|list|length %}
- {% set passed_tasks = package.tasks|selectattr("status.value", "==", "completed")|list|length %}
- {% set issue_tasks = package.tasks|selectattr("status.value", "==", "failed")|list|length %}
- {% set completed_tasks = passed_tasks + issue_tasks %}
- {% if total_tasks == 0 %}
- <form method="post"
- action="{{ url_for('root_package_check') }}"
- class="d-inline">
- <input type="hidden"
- name="artifact_sha3"
- value="{{ package.artifact_sha3 }}" />
- <input type="hidden" name="release_name" value="{{ release.name }}" />
- <button type="submit" class="btn btn-primary">Check package</button>
- </form>
- {% else %}
- {%- set status_parts = [] -%}
- {%- if pending_tasks > 0 -%}
- {%- set _ = status_parts.append(pending_tasks|string + " Pending") -%}
- {%- endif -%}
- {%- if running_tasks > 0 -%}
- {%- set _ = status_parts.append(running_tasks|string + " Running") -%}
- {%- endif -%}
- {%- if passed_tasks > 0 -%}
- {%- set _ = status_parts.append(passed_tasks|string + " Passed") -%}
- {%- endif -%}
- {%- if issue_tasks > 0 -%}
- {%- set _ = status_parts.append(issue_tasks|string + " " + ("Issue" if issue_tasks == 1 else "Issues")) -%}
- {%- endif -%}
- {{ status_parts|join(", ") }} ({{ completed_tasks }}/{{ total_tasks }} {{ "Check" if total_tasks == 1 else "Checks" }} Complete)
- {% if package.tasks %}
- <div class="mt-3">
- <a href="{{ url_for('root_package_check', artifact_sha3=package.artifact_sha3, release_name=release.name) }}"
- class="btn btn-primary">Show check status</a>
- </div>
- {% endif %}
- {% endif %}
- </td>
- </tr>
- <tr>
- <th>Artifact hash (SHA3-256)</th>
- <td>{{ package.artifact_sha3 }}</td>
- </tr>
- <tr>
- <th>Artifact hash (SHA-512)</th>
- <td>{{ package.sha512 }}</td>
- </tr>
- <tr>
- <th>Signature hash (SHA3-256)</th>
- <td>{{ package.signature_sha3 }}</td>
- </tr>
- </table>
- {% endfor %}
{% endfor %}
{% else %}
<p class="text-secondary fst-italic">You haven't created any releases yet.</p>
diff --git a/atr/templates/keys-review.html b/atr/templates/keys-review.html
index e2fe50e..aff8635 100644
--- a/atr/templates/keys-review.html
+++ b/atr/templates/keys-review.html
@@ -138,7 +138,7 @@
<strong>You haven't added any SSH keys yet.</strong>
</p>
<p>
- <a href="{{ url_for('root_keys_ssh_add') }}">Add an SSH key</a>
+ <a href="{{ as_url(routes._keys.ssh_add) }}">Add an SSH key</a>
</p>
{% endif %}
{% endblock content %}
diff --git a/atr/templates/project-view.html b/atr/templates/project-view.html
index 4388532..195e7e6 100644
--- a/atr/templates/project-view.html
+++ b/atr/templates/project-view.html
@@ -113,7 +113,7 @@
{% if project.vote_policy and (is_project_lead or is_admin) %}
<div>
<a class="btn btn-primary btn-sm"
- href="{{ url_for('root_projects_vote_policy_edit', project_name=project.name) }}"><i class="fa-solid fa-pen-to-square"></i></a>
+ href="{{ as_url(routes.projects.vote_policy_edit, project_name=project.name) }}"><i class="fa-solid fa-pen-to-square"></i></a>
</div>
{% elif (is_project_lead or is_admin) %}
<div>
diff --git a/atr/templates/release-vote.html b/atr/templates/release-vote.html
index 36df439..86d2ace 100644
--- a/atr/templates/release-vote.html
+++ b/atr/templates/release-vote.html
@@ -27,7 +27,7 @@
<form method="post"
class="striking py-4 px-5"
- action="{{ url_for('root_release_vote') }}">
+ action="{{ as_url(routes.release.vote) }}">
<input type="hidden" name="release_name" value="{{ release.name }}" />
<div class="mb-4">
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org