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 d8772b0 Document remaining routes code to move to the storage
interface
d8772b0 is described below
commit d8772b0c3d1b6d7559a9247e279d30919c29dbb0
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed Sep 10 19:57:43 2025 +0100
Document remaining routes code to move to the storage interface
---
atr/routes/draft.py | 2 ++
atr/routes/keys.py | 15 +++++++++------
atr/routes/preview.py | 46 ++++++----------------------------------------
atr/routes/projects.py | 15 +++++++++------
atr/routes/release.py | 6 +++---
atr/routes/resolve.py | 1 +
atr/routes/sbom.py | 1 +
atr/routes/vote.py | 1 +
8 files changed, 32 insertions(+), 55 deletions(-)
diff --git a/atr/routes/draft.py b/atr/routes/draft.py
index a1dbb66..73cf541 100644
--- a/atr/routes/draft.py
+++ b/atr/routes/draft.py
@@ -299,6 +299,7 @@ async def sbomgen(
raise routes.FlashError("Internal error: New revision not found")
# Create and queue the task, using paths within the new revision
+ # TODO: Move this to the storage interface
async with db.session() as data:
# We still need release.name for the task metadata
sbom_task = sql.Task(
@@ -364,6 +365,7 @@ async def svnload(session: routes.CommitterSession,
project_name: str, version_n
"version_name": version_name,
"asf_uid": session.uid,
}
+ # TODO: Move this to the storage interface
async with db.session() as data:
svn_import_task = sql.Task(
task_type=sql.TaskType.SVN_IMPORT_FILES,
diff --git a/atr/routes/keys.py b/atr/routes/keys.py
index 3c033f9..b6c09ae 100644
--- a/atr/routes/keys.py
+++ b/atr/routes/keys.py
@@ -202,6 +202,7 @@ async def delete(session: routes.CommitterSession) ->
response.Response:
return await session.redirect(keys, error="Missing key fingerprint for
deletion.")
# Try to delete an SSH key first
+ # TODO: Use the storage interface instead
async with db.session() as data:
ssh_key = await data.ssh_key(fingerprint=fingerprint,
asf_uid=session.uid).get()
if ssh_key:
@@ -229,19 +230,21 @@ async def delete(session: routes.CommitterSession) ->
response.Response:
async def details(session: routes.CommitterSession, fingerprint: str) -> str |
response.Response:
"""Display details for a specific OpenPGP key."""
fingerprint = fingerprint.lower()
+ user_committees = []
async with db.session() as data:
key, is_owner = await _key_and_is_owner(data, session, fingerprint)
form = None
if is_owner:
project_list = session.committees + session.projects
user_committees = await data.committee(name_in=project_list).all()
- committee_choices: forms.Choices = [(c.name, c.display_name or
c.name) for c in user_committees]
+ if is_owner:
+ committee_choices: forms.Choices = [(c.name, c.display_name or c.name)
for c in user_committees]
- # TODO: Probably need to do data in a separate phase
- form = await UpdateKeyCommitteesForm.create_form(
- data=await quart.request.form if (quart.request.method ==
"POST") else None
- )
- forms.choices(form.selected_committees, committee_choices)
+ # TODO: Probably need to do data in a separate phase
+ form = await UpdateKeyCommitteesForm.create_form(
+ data=await quart.request.form if (quart.request.method == "POST")
else None
+ )
+ forms.choices(form.selected_committees, committee_choices)
if form and await form.validate_on_submit():
async with db.session() as data:
diff --git a/atr/routes/preview.py b/atr/routes/preview.py
index 7012975..927ab61 100644
--- a/atr/routes/preview.py
+++ b/atr/routes/preview.py
@@ -17,19 +17,17 @@
"""preview.py"""
-import aiofiles.os
-import aioshutil
import asfquart
import quart
import werkzeug.wrappers.response as response
import atr.construct as construct
-import atr.db as db
import atr.forms as forms
import atr.log as log
import atr.models.sql as sql
import atr.routes as routes
import atr.routes.root as root
+import atr.storage as storage
import atr.template as template
import atr.util as util
@@ -103,30 +101,11 @@ async def delete(session: routes.CommitterSession) ->
response.Response:
return await session.redirect(root.index, error="Missing required
parameters")
# Check that the user has access to the project
- async with db.session() as data:
- project = await data.project(name=project_name,
status=sql.ProjectStatus.ACTIVE).get()
- if not project or not any(
- (
- (c.name == project.committee_name)
- and ((session.uid in c.committee_members) or (session.uid in
c.committers))
- )
- for c in (await session.user_committees)
- ):
- return await session.redirect(root.index, error="You do not have
access to this project")
-
- # Delete the metadata from the database
- async with data.begin():
- try:
- await _delete_preview(data, release_name)
- except Exception as e:
- log.exception("Error deleting preview:")
- return await session.redirect(root.index, error=f"Error
deleting preview: {e!s}")
-
- # Delete the files on disk, including all revisions
- # We can't use util.release_directory_base here because we don't have the
release object
- preview_dir = util.get_unfinished_dir() / project_name / version_name
- if await aiofiles.os.path.exists(preview_dir):
- await aioshutil.rmtree(preview_dir)
+ async with storage.write(session.uid) as write:
+ wacp = await write.as_project_committee_member(project_name)
+ await wacp.release.delete(
+ project_name, version_name,
phase=sql.ReleasePhase.RELEASE_PREVIEW, include_downloads=False
+ )
return await session.redirect(root.index, success="Preview deleted
successfully")
@@ -188,16 +167,3 @@ async def view_path(
phase_key="preview",
content_listing=content_listing,
)
-
-
-async def _delete_preview(data: db.Session, release_name: str) -> None:
- """Delete a release preview and all its associated files."""
- # Check that the release exists
- release = await data.release(name=release_name, _project=True).get()
- if not release:
- raise routes.FlashError("Preview not found")
- if release.phase != sql.ReleasePhase.RELEASE_PREVIEW:
- raise routes.FlashError("Release is not in the preview phase")
-
- # Delete the release record
- await data.delete(release)
diff --git a/atr/routes/projects.py b/atr/routes/projects.py
index c2acecc..966a83f 100644
--- a/atr/routes/projects.py
+++ b/atr/routes/projects.py
@@ -265,6 +265,7 @@ async def delete(session: routes.CommitterSession) ->
response.Response:
if not project_name:
return await session.redirect(projects, error="Missing project name
for deletion.")
+ # TODO: Move this to the storage interface
async with db.session() as data:
project = await data.project(
name=project_name, status=sql.ProjectStatus.ACTIVE,
_releases=True, _distribution_channels=True
@@ -331,6 +332,7 @@ async def view(session: routes.CommitterSession, name: str)
-> response.Response
metadata_form = None
can_edit = False
+ # TODO: Move this to the storage interface
async with db.session() as data:
project = await data.project(
name=name, _committee=True, _committee_public_signing_keys=True,
_release_policy=True
@@ -353,12 +355,12 @@ async def view(session: routes.CommitterSession, name:
str) -> response.Response
if metadata_form is None:
metadata_form = await
ProjectMetadataForm.create_form(data={"project_name": project.name})
- if policy_form is None:
- policy_form = await _policy_form_create(project)
- candidate_drafts = await interaction.candidate_drafts(project)
- candidates = await interaction.candidates(project)
- previews = await interaction.previews(project)
- full_releases = await interaction.full_releases(project)
+ if policy_form is None:
+ policy_form = await _policy_form_create(project)
+ candidate_drafts = await interaction.candidate_drafts(project)
+ candidates = await interaction.candidates(project)
+ previews = await interaction.previews(project)
+ full_releases = await interaction.full_releases(project)
return await template.render(
"project-view.html",
@@ -602,6 +604,7 @@ async def _project_add(form: AddForm, asf_id: str) ->
response.Response:
committee_name, display_name, label = form_values
super_project = None
+ # TODO: Move this to the storage interface
async with db.session() as data:
# Get the base project to derive from
# We're allowing derivation from a retired project here
diff --git a/atr/routes/release.py b/atr/routes/release.py
index 29d2a9e..97554c4 100644
--- a/atr/routes/release.py
+++ b/atr/routes/release.py
@@ -129,9 +129,9 @@ async def select(session: routes.CommitterSession,
project_name: str) -> str:
base.ASFQuartException(f"Project {project_name} not found",
errorcode=404)
)
releases = await interaction.releases_in_progress(project)
- return await template.render(
- "release-select.html", project=project, releases=releases,
format_datetime=util.format_datetime
- )
+ return await template.render(
+ "release-select.html", project=project, releases=releases,
format_datetime=util.format_datetime
+ )
@routes.public("/release/view/<project_name>/<version_name>")
diff --git a/atr/routes/resolve.py b/atr/routes/resolve.py
index bb9a864..6e4d047 100644
--- a/atr/routes/resolve.py
+++ b/atr/routes/resolve.py
@@ -112,6 +112,7 @@ async def manual_selected_post(
vote_result_url = util.unwrap(resolve_form.vote_result_url.data)
await _committees_check(vote_thread_url, vote_result_url)
+ # TODO: Move this to the storage interface
async with db.session() as data:
release = await data.merge(release)
if vote_result == "passed":
diff --git a/atr/routes/sbom.py b/atr/routes/sbom.py
index 32af892..8c360db 100644
--- a/atr/routes/sbom.py
+++ b/atr/routes/sbom.py
@@ -66,6 +66,7 @@ async def augment(
if revision_number is None:
raise RuntimeError("No revision number found for new revision
creation")
log.info(f"Augmenting SBOM for {project_name} {version_name}
{revision_number} {rel_path}")
+ # TODO: Move this to the storage interface
sbom_task = sql.Task(
task_type=sql.TaskType.SBOM_AUGMENT,
task_args=tasks.sbom.FileArgs(
diff --git a/atr/routes/vote.py b/atr/routes/vote.py
index 6c8ac8d..11095b2 100644
--- a/atr/routes/vote.py
+++ b/atr/routes/vote.py
@@ -175,6 +175,7 @@ async def _send_vote(
body_text = "\n\n".join(body)
in_reply_to = vote_thread_mid
+ # TODO: Move this to the storage interface
task = sql.Task(
status=sql.TaskStatus.QUEUED,
task_type=sql.TaskType.MESSAGE_SEND,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]