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

commit 70d1bfd748a4f7be0ba471c22a2b4bb480a2c1c3
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Sep 9 18:45:57 2025 +0100

    Allow recording distributions from GitHub during the compose phase
---
 atr/blueprints/api/api.py | 18 +++++++++++++-----
 atr/db/interaction.py     | 21 +++++++++++++--------
 atr/templates/about.html  |  4 +++-
 3 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index 90b3f41..10e39cd 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -589,11 +589,19 @@ async def publisher_distribution_record(data: 
models.api.PublisherDistributionRe
     """
     Record a distribution with a corroborating Trusted Publisher JWT.
     """
-    _payload, asf_uid, project = await interaction.trusted_jwt(
-        data.publisher,
-        data.jwt,
-        interaction.TrustedProjectPhase.FINISH,
-    )
+    try:
+        _payload, asf_uid, project = await interaction.trusted_jwt(
+            data.publisher,
+            data.jwt,
+            interaction.TrustedProjectPhase.FINISH,
+        )
+    except interaction.ReleasePolicyNotFoundError:
+        # TODO: We could perform a more advanced query with multiple in_ 
statements
+        _payload, asf_uid, project = await interaction.trusted_jwt(
+            data.publisher,
+            data.jwt,
+            interaction.TrustedProjectPhase.COMPOSE,
+        )
     async with db.session() as db_data:
         release_name = models.sql.release_name(project.name, data.version)
         release = await db_data.release(
diff --git a/atr/db/interaction.py b/atr/db/interaction.py
index be3bd28..8fd4869 100644
--- a/atr/db/interaction.py
+++ b/atr/db/interaction.py
@@ -69,6 +69,10 @@ class PublicKeyError(RuntimeError):
     pass
 
 
+class ReleasePolicyNotFoundError(RuntimeError):
+    pass
+
+
 class TrustedProjectPhase(enum.Enum):
     COMPOSE = "compose"
     VOTE = "vote"
@@ -472,29 +476,32 @@ async def _delete_release_data_filesystem(release_dir: 
pathlib.Path, release_nam
 async def _trusted_project(repository: str, workflow_ref: str, phase: 
TrustedProjectPhase) -> sql.Project:
     # Debugging
     log.info(f"GitHub OIDC JWT payload: {repository} {workflow_ref}")
-    repository_name, workflow_path = _trusted_project_checks(repository, 
workflow_ref, phase)
+    repository_name, workflow_path = _trusted_project_checks(repository, 
workflow_ref)
 
-    value_error = ValueError(
+    rpnf_error = ReleasePolicyNotFoundError(
         f"Release policy for repository {repository_name} and {phase.value} 
workflow path {workflow_path} not found"
     )
     # TODO: If a policy is reused between projects, we can't get the project
     async with db.session() as db_data:
         match phase:
             case TrustedProjectPhase.COMPOSE:
+                # Searches in github_*compose*_workflow_path
                 policy = await db_data.release_policy(
                     github_repository_name=repository_name,
                     github_compose_workflow_path_has=workflow_path,
-                ).demand(value_error)
+                ).demand(rpnf_error)
             case TrustedProjectPhase.VOTE:
+                # Searches in github_*vote*_workflow_path
                 policy = await db_data.release_policy(
                     github_repository_name=repository_name,
                     github_vote_workflow_path_has=workflow_path,
-                ).demand(value_error)
+                ).demand(rpnf_error)
             case TrustedProjectPhase.FINISH:
+                # Searches in github_*finish*_workflow_path
                 policy = await db_data.release_policy(
                     github_repository_name=repository_name,
                     github_finish_workflow_path_has=workflow_path,
-                ).demand(value_error)
+                ).demand(rpnf_error)
         project = await db_data.project(release_policy_id=policy.id).demand(
             InteractionError(f"Project for release policy {policy.id} not 
found")
         )
@@ -502,12 +509,10 @@ async def _trusted_project(repository: str, workflow_ref: 
str, phase: TrustedPro
         raise InteractionError(f"Project {project.name} has no committee")
     if project.committee.name not in 
registry.GITHUB_AUTOMATED_RELEASE_COMMITTEES:
         raise InteractionError(f"Project {project.name} is not in a committee 
that can make releases")
-    log.info(f"Release policy: {policy}")
-    log.info(f"Project: {project}")
     return project
 
 
-def _trusted_project_checks(repository: str, workflow_ref: str, phase: 
TrustedProjectPhase) -> tuple[str, str]:
+def _trusted_project_checks(repository: str, workflow_ref: str) -> tuple[str, 
str]:
     if not repository.startswith("apache/"):
         raise InteractionError("Repository must start with 'apache/'")
     repository_name = repository.removeprefix("apache/")
diff --git a/atr/templates/about.html b/atr/templates/about.html
index 2b88c20..0bd74ce 100644
--- a/atr/templates/about.html
+++ b/atr/templates/about.html
@@ -85,7 +85,9 @@
       <td class="ui">
         <code>/distribution/stage/P/V</code>
       </td>
-      <td class="cli">-</td>
+      <td class="cli">
+        <code>atr distribution record P V plat owner pkg ver stg details</code>
+      </td>
       <td class="github">-</td>
     </tr>
     <tr>


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

Reply via email to