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-releases.git


The following commit(s) were added to refs/heads/main by this push:
     new 59c226a  Wait for SBOM task to complete before continuing with revision
59c226a is described below

commit 59c226a5f980ba30d82a2a0e35111a39ce85aa50
Author: Alastair McFarlane <[email protected]>
AuthorDate: Thu Dec 11 17:58:08 2025 +0000

    Wait for SBOM task to complete before continuing with revision
---
 atr/db/interaction.py       | 24 +++++++++++++++++++++++-
 atr/post/draft.py           | 25 ++++++++++++-------------
 atr/storage/writers/sbom.py | 13 -------------
 3 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/atr/db/interaction.py b/atr/db/interaction.py
index d1b210f..3225e8a 100644
--- a/atr/db/interaction.py
+++ b/atr/db/interaction.py
@@ -14,7 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-
+import asyncio
 import contextlib
 import datetime
 import enum
@@ -455,6 +455,28 @@ async def user_projects(asf_uid: str, caller_data: 
db.Session | None = None) ->
     return [(p.name, p.display_name) for p in projects]
 
 
+async def wait_for_task(
+    task: sql.Task,
+    caller_data: db.Session | None = None,
+    desired_status: sql.TaskStatus = sql.TaskStatus.COMPLETED,
+    timeout_s: int = 10,
+) -> bool:
+    # We must wait until the sbom_task is complete before we can queue checks
+    # Maximum wait time is 60 * 100ms = 6000ms
+    log.info(f"Waiting for task {task.id} to complete")
+    async with db.ensure_session(caller_data) as data:
+        t = await data.task(id=task.id).get()
+        if t is None:
+            return False
+        for _attempt in range(timeout_s * 10):
+            await data.refresh(t)
+            if t.status == desired_status:
+                return True
+            # Wait 100ms before checking again
+            await asyncio.sleep(0.1)
+    return False
+
+
 async def _trusted_project(repository: str, workflow_ref: str, phase: 
TrustedProjectPhase) -> sql.Project:
     # Debugging
     log.info(f"GitHub OIDC JWT payload: {repository} {workflow_ref}")
diff --git a/atr/post/draft.py b/atr/post/draft.py
index 770ef39..88eaa3e 100644
--- a/atr/post/draft.py
+++ b/atr/post/draft.py
@@ -35,6 +35,7 @@ import atr.shared as shared
 import atr.storage as storage
 import atr.util as util
 import atr.web as web
+from atr.db.interaction import wait_for_task
 
 
 class VotePreviewForm(form.Form):
@@ -193,19 +194,17 @@ async def sbomgen(session: web.Committer, project_name: 
str, version_name: str,
                 if await aiofiles.os.path.exists(sbom_path_in_new_revision):
                     raise base.ASFQuartException("SBOM file already exists", 
errorcode=400)
 
-            if creating.new is None:
-                raise web.FlashError("Internal error: New revision not found")
-
-            # Calculate the paths in the revision now that create_and_manage 
moved it
-            new_revision_dir = util.get_unfinished_dir() / project_name / 
version_name / creating.new.number
-            path_in_new_revision = new_revision_dir / rel_path
-            sbom_path_in_new_revision = new_revision_dir / rel_path.parent / 
sbom_path_rel
-
-            # Create and queue the task, using paths within the new revision
-            sbom_task = await wacp.sbom.generate_cyclonedx(
-                project_name, version_name, creating.new.number, 
path_in_new_revision, sbom_path_in_new_revision
-            )
-            await wacp.sbom.generate_cyclonedx_wait(sbom_task)
+                # This shouldn't happen as we need a revision to kick the task 
off from
+                if creating.old is None:
+                    raise web.FlashError("Internal error: Revision not found")
+
+                # Create and queue the task, using paths within the new 
revision
+                sbom_task = await wacp.sbom.generate_cyclonedx(
+                    project_name, version_name, creating.old.number, 
path_in_new_revision, sbom_path_in_new_revision
+                )
+                success = await wait_for_task(sbom_task)
+                if not success:
+                    raise web.FlashError("Internal error: SBOM generation 
timed out")
 
     except Exception as e:
         log.exception("Error generating SBOM:")
diff --git a/atr/storage/writers/sbom.py b/atr/storage/writers/sbom.py
index 12d35d2..a18e5e9 100644
--- a/atr/storage/writers/sbom.py
+++ b/atr/storage/writers/sbom.py
@@ -18,7 +18,6 @@
 # Removing this will cause circular imports
 from __future__ import annotations
 
-import asyncio
 import datetime
 from typing import TYPE_CHECKING
 
@@ -131,18 +130,6 @@ class CommitteeParticipant(FoundationCommitter):
         await self.__data.refresh(sbom_task)
         return sbom_task
 
-    # TODO: This is not a writer
-    # Move this to the readers
-    async def generate_cyclonedx_wait(self, sbom_task: sql.Task) -> None:
-        # We must wait until the sbom_task is complete before we can queue 
checks
-        # Maximum wait time is 60 * 100ms = 6000ms
-        for _attempt in range(60):
-            await self.__data.refresh(sbom_task)
-            if sbom_task.status != sql.TaskStatus.QUEUED:
-                break
-            # Wait 100ms before checking again
-            await asyncio.sleep(0.1)
-
     async def osv_scan_cyclonedx(
         self,
         project_name: str,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to