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 71d9c38 Make phase routes redirect to the correct phase if necessary
71d9c38 is described below
commit 71d9c38b62e12930c349b1005f3400f8912cf1dd
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu Sep 11 19:08:50 2025 +0100
Make phase routes redirect to the correct phase if necessary
---
atr/routes/compose.py | 12 ++++-
atr/routes/finish.py | 12 ++++-
atr/routes/mapping.py | 30 ++++++++---
atr/routes/vote.py | 19 ++++---
atr/templates/check-selected-candidate-forms.html | 66 ++++++++++++-----------
atr/templates/check-selected-release-info.html | 2 +-
6 files changed, 92 insertions(+), 49 deletions(-)
diff --git a/atr/routes/compose.py b/atr/routes/compose.py
index c93436d..b147808 100644
--- a/atr/routes/compose.py
+++ b/atr/routes/compose.py
@@ -17,6 +17,7 @@
from typing import TYPE_CHECKING
+import asfquart.base as base
import werkzeug.wrappers.response as response
import wtforms
@@ -28,6 +29,7 @@ import atr.models.sql as sql
import atr.revision as revision
import atr.routes as routes
import atr.routes.draft as draft
+import atr.routes.mapping as mapping
import atr.storage as storage
import atr.template as template
import atr.util as util
@@ -122,7 +124,15 @@ async def selected(session: routes.CommitterSession,
project_name: str, version_
"""Show the contents of the release candidate draft."""
await session.check_access(project_name)
- release = await session.release(project_name, version_name,
with_committee=True, with_project_release_policy=True)
+ async with db.session() as data:
+ release = await data.release(
+ project_name=project_name,
+ version=version_name,
+ _committee=True,
+ _project_release_policy=True,
+ ).demand(base.ASFQuartException("Release does not exist",
errorcode=404))
+ if release.phase != sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT:
+ return await mapping.release_as_redirect(session, release)
return await check(session, release)
diff --git a/atr/routes/finish.py b/atr/routes/finish.py
index f774e36..2b8bf3a 100644
--- a/atr/routes/finish.py
+++ b/atr/routes/finish.py
@@ -21,6 +21,7 @@ from collections.abc import Awaitable, Callable
from typing import Any, Final
import aiofiles.os
+import asfquart.base as base
import quart
import quart.wrappers.response as quart_response
import werkzeug.datastructures as datastructures
@@ -35,6 +36,7 @@ import atr.log as log
import atr.models.sql as sql
import atr.revision as revision
import atr.routes as routes
+import atr.routes.mapping as mapping
import atr.routes.root as root
import atr.template as template
import atr.util as util
@@ -126,8 +128,14 @@ async def selected(
return await session.redirect(selected, project_name=project_name,
version_name=version_name)
async with db.session() as data:
- release = await session.release(project_name, version_name,
phase=sql.ReleasePhase.RELEASE_PREVIEW, data=data)
- user_ssh_keys = await data.ssh_key(asf_uid=session.uid).all()
+ release = await data.release(
+ project_name=project_name,
+ version=version_name,
+ _committee=True,
+ ).demand(base.ASFQuartException("Release does not exist",
errorcode=404))
+ if release.phase != sql.ReleasePhase.RELEASE_PREVIEW:
+ return await mapping.release_as_redirect(session, release)
+ user_ssh_keys = await data.ssh_key(asf_uid=session.uid).all()
latest_revision_dir = util.release_directory(release)
try:
diff --git a/atr/routes/mapping.py b/atr/routes/mapping.py
index acfa23c..3f96462 100644
--- a/atr/routes/mapping.py
+++ b/atr/routes/mapping.py
@@ -15,7 +15,12 @@
# specific language governing permissions and limitations
# under the License.
+from collections.abc import Callable
+
+import werkzeug.wrappers.response as response
+
import atr.models.sql as sql
+import atr.routes as routes
import atr.routes.compose as compose
import atr.routes.finish as finish
import atr.routes.release as routes_release
@@ -23,14 +28,27 @@ import atr.routes.vote as vote
import atr.util as util
-def release_as_url(release: sql.Release) -> str:
+async def release_as_redirect(session: routes.CommitterSession, release:
sql.Release) -> response.Response:
+ route = release_as_route(release)
+ if route is routes_release.finished:
+ return await session.redirect(route, project_name=release.project.name)
+ return await session.redirect(route, project_name=release.project.name,
version_name=release.version)
+
+
+def release_as_route(release: sql.Release) -> Callable:
match release.phase:
case sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT:
- return util.as_url(compose.selected,
project_name=release.project.name, version_name=release.version)
+ return compose.selected
case sql.ReleasePhase.RELEASE_CANDIDATE:
- return util.as_url(vote.selected,
project_name=release.project.name, version_name=release.version)
+ return vote.selected
case sql.ReleasePhase.RELEASE_PREVIEW:
- return util.as_url(finish.selected,
project_name=release.project.name, version_name=release.version)
+ return finish.selected
case sql.ReleasePhase.RELEASE:
- finished = routes_release.finished # type: ignore[has-type]
- return util.as_url(finished, project_name=release.project.name)
+ return routes_release.finished
+
+
+def release_as_url(release: sql.Release) -> str:
+ route = release_as_route(release)
+ if route is routes_release.finished:
+ return util.as_url(route, project_name=release.project.name)
+ return util.as_url(route, project_name=release.project.name,
version_name=release.version)
diff --git a/atr/routes/vote.py b/atr/routes/vote.py
index cb1ce7d..b9d685a 100644
--- a/atr/routes/vote.py
+++ b/atr/routes/vote.py
@@ -15,9 +15,11 @@
# specific language governing permissions and limitations
# under the License.
+import asfquart.base as base
import quart
import werkzeug.wrappers.response as response
+import atr.db as db
import atr.db.interaction as interaction
import atr.forms as forms
import atr.log as log
@@ -25,6 +27,7 @@ import atr.models.results as results
import atr.models.sql as sql
import atr.routes as routes
import atr.routes.compose as compose
+import atr.routes.mapping as mapping
import atr.storage as storage
import atr.util as util
@@ -42,13 +45,15 @@ async def selected(session: routes.CommitterSession,
project_name: str, version_
"""Show the contents of the release candidate draft."""
await session.check_access(project_name)
- release = await session.release(
- project_name,
- version_name,
- with_committee=True,
- phase=sql.ReleasePhase.RELEASE_CANDIDATE,
- with_project_release_policy=True,
- )
+ async with db.session() as data:
+ release = await data.release(
+ project_name=project_name,
+ version=version_name,
+ _committee=True,
+ _project_release_policy=True,
+ ).demand(base.ASFQuartException("Release does not exist",
errorcode=404))
+ if release.phase != sql.ReleasePhase.RELEASE_CANDIDATE:
+ return await mapping.release_as_redirect(session, release)
latest_vote_task = await interaction.release_latest_vote_task(release)
archive_url = None
task_mid = None
diff --git a/atr/templates/check-selected-candidate-forms.html
b/atr/templates/check-selected-candidate-forms.html
index c4de407..17ca5fd 100644
--- a/atr/templates/check-selected-candidate-forms.html
+++ b/atr/templates/check-selected-candidate-forms.html
@@ -3,40 +3,42 @@
{% endif %}
-<h2>Cast your vote</h2>
+{% if form %}
+ <h2>Cast your vote</h2>
-<form method="post"
- action="{{ as_url(routes.vote.selected_post, project_name=project_name,
version_name=version_name) }}"
- class="atr-canary py-4 px-5 mb-4 border rounded">
- {{ form.hidden_tag() }}
+ <form method="post"
+ action="{{ as_url(routes.vote.selected_post,
project_name=project_name, version_name=version_name) }}"
+ class="atr-canary py-4 px-5 mb-4 border rounded">
+ {{ form.hidden_tag() }}
- <div class="row mb-3 pb-3 border-bottom">
- {{ forms.label(form.vote_value, col="md3") }}
- <div class="col-md-9">
- <div class="btn-group" role="group" aria-label="Vote options">
- {% for subfield in form.vote_value %}
- {% set btn_class = "btn-outline-secondary" %}
- {% if subfield.data == "+1" %}
- {% set btn_class = "btn-outline-success" %}
- {% endif %}
- {% if subfield.data == "-1" %}
- {% set btn_class = "btn-outline-danger" %}
- {% endif %}
- {{ forms.widget(subfield, classes="btn-check", autocomplete="off") }}
- {{ forms.label(subfield, classes="btn " + btn_class) }}
- {% endfor %}
+ <div class="row mb-3 pb-3 border-bottom">
+ {{ forms.label(form.vote_value, col="md3") }}
+ <div class="col-md-9">
+ <div class="btn-group" role="group" aria-label="Vote options">
+ {% for subfield in form.vote_value %}
+ {% set btn_class = "btn-outline-secondary" %}
+ {% if subfield.data == "+1" %}
+ {% set btn_class = "btn-outline-success" %}
+ {% endif %}
+ {% if subfield.data == "-1" %}
+ {% set btn_class = "btn-outline-danger" %}
+ {% endif %}
+ {{ forms.widget(subfield, classes="btn-check", autocomplete="off")
}}
+ {{ forms.label(subfield, classes="btn " + btn_class) }}
+ {% endfor %}
+ </div>
+ {{ forms.errors(form.vote_value, classes="text-danger small mt-1") }}
</div>
- {{ forms.errors(form.vote_value, classes="text-danger small mt-1") }}
</div>
- </div>
- <div class="row mb-3">
- {{ forms.label(form.vote_comment, col="md3") }}
- <div class="col-md-9">
- {{ forms.widget(form.vote_comment, rows="3") }}
- {{ forms.errors(form.vote_comment, classes="text-danger small mt-1") }}
+ <div class="row mb-3">
+ {{ forms.label(form.vote_comment, col="md3") }}
+ <div class="col-md-9">
+ {{ forms.widget(form.vote_comment, rows="3") }}
+ {{ forms.errors(form.vote_comment, classes="text-danger small mt-1") }}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-9 offset-md-3">{{ form.submit(class_="btn
btn-primary") }}</div>
</div>
- </div>
- <div class="row">
- <div class="col-md-9 offset-md-3">{{ form.submit(class_="btn btn-primary")
}}</div>
- </div>
-</form>
+ </form>
+{% endif %}
diff --git a/atr/templates/check-selected-release-info.html
b/atr/templates/check-selected-release-info.html
index 957d4fc..cc93c84 100644
--- a/atr/templates/check-selected-release-info.html
+++ b/atr/templates/check-selected-release-info.html
@@ -86,7 +86,7 @@
{% if release.vote_manual %}
<a href="{{ as_url(routes.resolve.manual_selected,
project_name=release.project.name, version_name=release.version) }}"
class="btn btn-success"><i class="bi bi-clipboard-check
me-1"></i> Resolve vote</a>
- {% else %}
+ {% elif hidden_form %}
<form action="{{ as_url(routes.resolve.tabulated_selected_post,
project_name=release.project.name, version_name=release.version) }}"
method="post"
class="mb-0">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]