This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch sbp
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/sbp by this push:
new a50d92d9 Handle phase mismatches and add further checking
a50d92d9 is described below
commit a50d92d9998eeaa36caeef146f0c29f68d75142e
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed Apr 1 20:22:43 2026 +0100
Handle phase mismatches and add further checking
---
atr/api/__init__.py | 9 ++++++---
atr/post/draft.py | 53 +++++++++++++++++++++++++++++++++++------------------
atr/post/keys.py | 1 +
atr/post/sbom.py | 19 ++++++-------------
atr/post/upload.py | 9 ++++++++-
5 files changed, 56 insertions(+), 35 deletions(-)
diff --git a/atr/api/__init__.py b/atr/api/__init__.py
index 1c4af5e7..9cca2570 100644
--- a/atr/api/__init__.py
+++ b/atr/api/__init__.py
@@ -1174,9 +1174,12 @@ async def release_upload(
# if not (user.is_committee_member(project.committee, asf_uid) or
user.is_admin(asf_uid)):
# raise exceptions.Forbidden("You do not have permission to upload
to this project")
- async with storage.write(asf_uid) as write:
- wacp = await write.as_project_committee_participant(data.project)
- result = await wacp.release.upload_file(data)
+ try:
+ async with storage.write(asf_uid) as write:
+ wacp = await write.as_project_committee_participant(data.project)
+ result = await wacp.release.upload_file(data)
+ except types.PhaseMismatchError as e:
+ raise exceptions.Conflict(str(e))
if isinstance(result, sql.Quarantined):
return {
"endpoint": "/release/upload",
diff --git a/atr/post/draft.py b/atr/post/draft.py
index 020a4987..05518ae9 100644
--- a/atr/post/draft.py
+++ b/atr/post/draft.py
@@ -32,6 +32,7 @@ import atr.models.safe as safe
import atr.models.sql as sql
import atr.shared as shared
import atr.storage as storage
+import atr.storage.types as types
import atr.util as util
import atr.web as web
@@ -55,15 +56,23 @@ async def cache_reset(
raise base.ASFQuartException("Admin access required", errorcode=403)
description = "Empty revision to restart all checks without cache for the
whole release candidate draft"
- async with storage.write(session) as write:
- wacp = await write.as_project_committee_participant(project_key)
- result = await wacp.revision.create_revision_with_quarantine(
- project_key,
- version_key,
- session.uid,
-
allowed_phases=frozenset({sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT}),
- description=description,
- reset_to_global_cache=True,
+ try:
+ async with storage.write(session) as write:
+ wacp = await write.as_project_committee_participant(project_key)
+ result = await wacp.revision.create_revision_with_quarantine(
+ project_key,
+ version_key,
+ session.uid,
+
allowed_phases=frozenset({sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT}),
+ description=description,
+ reset_to_global_cache=True,
+ )
+ except types.PhaseMismatchError as e:
+ return await session.redirect(
+ get.compose.selected,
+ project_key=str(project_key),
+ version_key=str(version_key),
+ error=str(e),
)
success = "Release set back to global caching"
@@ -210,15 +219,23 @@ async def recheck(
raise base.ASFQuartException("Admin access required", errorcode=403)
description = "Empty revision to restart all checks without cache for the
whole release candidate draft"
- async with storage.write(session) as write:
- wacp = await write.as_project_committee_participant(project_key)
- result = await wacp.revision.create_revision_with_quarantine(
- project_key,
- version_key,
- session.uid,
-
allowed_phases=frozenset({sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT}),
- description=description,
- set_local_cache=True,
+ try:
+ async with storage.write(session) as write:
+ wacp = await write.as_project_committee_participant(project_key)
+ result = await wacp.revision.create_revision_with_quarantine(
+ project_key,
+ version_key,
+ session.uid,
+
allowed_phases=frozenset({sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT}),
+ description=description,
+ set_local_cache=True,
+ )
+ except types.PhaseMismatchError as e:
+ return await session.redirect(
+ get.compose.selected,
+ project_key=str(project_key),
+ version_key=str(version_key),
+ error=str(e),
)
success = "All checks restarted with release-local cache"
diff --git a/atr/post/keys.py b/atr/post/keys.py
index e5351d45..69b3ece3 100644
--- a/atr/post/keys.py
+++ b/atr/post/keys.py
@@ -154,6 +154,7 @@ async def import_selected_revision(
URL: /keys/import/<project_key>/<version_key>
"""
await session.check_access(project_key)
+ await session.release(project_key, version_key, with_committee=False,
with_project=False)
async with storage.write() as write:
wacm = await write.as_project_committee_member(project_key)
outcomes: outcome.List[types.Key] = await
wacm.keys.import_keys_file(project_key, version_key)
diff --git a/atr/post/sbom.py b/atr/post/sbom.py
index 04db67e4..3a96c4e1 100644
--- a/atr/post/sbom.py
+++ b/atr/post/sbom.py
@@ -23,7 +23,6 @@ import asfquart.base as base
import quart
import atr.blueprints.post as post
-import atr.db as db
import atr.get as get
import atr.log as log
import atr.models.safe as safe
@@ -64,12 +63,9 @@ async def _augment(
raise base.ASFQuartException("SBOM augmentation is only supported for
.cdx.json files", errorcode=400)
try:
- async with db.session() as data:
- release = await data.release(project_key=str(project_key),
version=str(version_key)).demand(
- RuntimeError("Release does not exist for new revision
creation")
- )
- revision_number = release.safe_latest_revision_number
- log.info(f"Augmenting SBOM for {project_key} {version_key}
{revision_number!s} {rel_path!s}")
+ release = await session.release(project_key, version_key,
with_committee=False, with_project=False)
+ revision_number = release.safe_latest_revision_number
+ log.info(f"Augmenting SBOM for {project_key} {version_key}
{revision_number!s} {rel_path!s}")
async with storage.write_as_project_committee_member(project_key) as
wacm:
sbom_task = await wacm.sbom.augment_cyclonedx(
project_key,
@@ -105,12 +101,9 @@ async def _scan(
raise base.ASFQuartException("OSV scanning is only supported for
.cdx.json files", errorcode=400)
try:
- async with db.session() as data:
- release = await data.release(project_key=str(project_key),
version=str(version_key)).demand(
- RuntimeError("Release does not exist for OSV scan")
- )
- revision_number = release.safe_latest_revision_number
- log.info(f"Starting OSV scan for {project_key!s} {version_key!s}
{revision_number!s} {rel_path!s}")
+ release = await session.release(project_key, version_key,
with_committee=False, with_project=False)
+ revision_number = release.safe_latest_revision_number
+ log.info(f"Starting OSV scan for {project_key!s} {version_key!s}
{revision_number!s} {rel_path!s}")
async with storage.write_as_project_committee_member(project_key) as
wacm:
sbom_task = await wacm.sbom.osv_scan_cyclonedx(
project_key,
diff --git a/atr/post/upload.py b/atr/post/upload.py
index 7d71c35b..3271106b 100644
--- a/atr/post/upload.py
+++ b/atr/post/upload.py
@@ -43,7 +43,7 @@ import atr.web as web
@post.typed
-async def finalise(
+async def finalise( # noqa: C901
session: web.Committer,
_upload_finalise: Literal["upload/finalise"],
project_key: safe.ProjectKey,
@@ -108,6 +108,13 @@ async def finalise(
project_key=str(project_key),
version_key=str(version_key),
)
+ except types.PhaseMismatchError as e:
+ return await session.redirect(
+ get.compose.selected,
+ error=str(e),
+ project_key=str(project_key),
+ version_key=str(version_key),
+ )
except types.FailedError as e:
await aioshutil.rmtree(staging_dir)
await quart.flash(str(e), "error")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]