This is an automated email from the ASF dual-hosted git repository.

arm 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 025a0cd  Allow phase and UID to be passed out to workflows
025a0cd is described below

commit 025a0cdceb3def52639e308a0ba84d6aacb38572
Author: Alastair McFarlane <[email protected]>
AuthorDate: Tue Jan 13 17:29:36 2026 +0000

    Allow phase and UID to be passed out to workflows
---
 atr/api/__init__.py                  | 15 ++++++++++-----
 atr/db/interaction.py                | 18 +++++++++++-------
 atr/models/api.py                    |  2 ++
 atr/post/distribution.py             | 12 +++++++++++-
 atr/storage/writers/distributions.py |  2 ++
 atr/tasks/gha.py                     |  3 +++
 6 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/atr/api/__init__.py b/atr/api/__init__.py
index ee94a8e..2cb7b68 100644
--- a/atr/api/__init__.py
+++ b/atr/api/__init__.py
@@ -256,23 +256,28 @@ async def committees_list() -> DictResponse:
 async def distribute_ssh_register(data: models.api.DistributeSshRegisterArgs) 
-> DictResponse:
     """
     Register an SSH key sent with a corroborating Trusted Publisher JWT,
-    validating the requested version is in the correct phase.
+    validating the requested release is in the correct phase.
     """
-    payload, asf_uid, project = await interaction.trusted_jwt_for_version(
-        data.publisher, data.jwt, interaction.TrustedProjectPhase(data.phase), 
data.version
+    payload, asf_uid, project, release = await 
interaction.trusted_jwt_for_dist(
+        data.publisher,
+        data.jwt,
+        data.asf_uid,
+        interaction.TrustedProjectPhase(data.phase),
+        data.project_name,
+        data.version,
     )
     async with 
storage.write_as_committee_member(util.unwrap(project.committee).name, asf_uid) 
as wacm:
         fingerprint, expires = await wacm.ssh.add_workflow_key(
             payload["actor"],
             payload["actor_id"],
-            project.name,
+            release.project_name,
             data.ssh_key,
         )
 
     return models.api.DistributeSshRegisterResults(
         endpoint="/distribute/ssh/register",
         fingerprint=fingerprint,
-        project=project.name,
+        project=release.project_name,
         expires=expires,
     ).model_dump(), 200
 
diff --git a/atr/db/interaction.py b/atr/db/interaction.py
index beef1ec..bc27ef4 100644
--- a/atr/db/interaction.py
+++ b/atr/db/interaction.py
@@ -397,14 +397,18 @@ async def trusted_jwt(publisher: str, jwt: str, phase: 
TrustedProjectPhase) -> t
     return payload, asf_uid, project
 
 
-async def trusted_jwt_for_version(
-    publisher: str, jwt: str, phase: TrustedProjectPhase, version_name: str
-) -> tuple[dict[str, Any], str, sql.Project]:
-    payload, asf_uid, project = await trusted_jwt(publisher, jwt, phase)
+async def trusted_jwt_for_dist(
+    publisher: str, jwt: str, asf_uid: str, phase: TrustedProjectPhase, 
project_name: str, version_name: str
+) -> tuple[dict[str, Any], str, sql.Project, sql.Release]:
+    payload, _asf_uid = await validate_trusted_jwt(publisher, jwt)
+    # payload, asf_uid, project = await trusted_jwt(publisher, jwt, phase)
     async with db.session() as db_data:
-        release = await db_data.release(project_name=project.name, 
version=version_name).get()
+        project = await db_data.project(name=project_name, 
_committee=True).demand(
+            InteractionError(f"Project {project_name} does not exist")
+        )
+        release = await db_data.release(project_name=project_name, 
version=version_name).get()
         if not release:
-            raise InteractionError(f"Release {version_name} does not exist in 
project {project.name}")
+            raise InteractionError(f"Release {version_name} does not exist in 
project {project_name}")
         if (phase == TrustedProjectPhase.COMPOSE) and (release.phase != 
sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT):
             raise InteractionError(f"Release {version_name} is not in compose 
phase")
         if (phase == TrustedProjectPhase.VOTE) and (release.phase != 
sql.ReleasePhase.RELEASE_CANDIDATE):
@@ -412,7 +416,7 @@ async def trusted_jwt_for_version(
         if (phase == TrustedProjectPhase.FINISH) and (release.phase != 
sql.ReleasePhase.RELEASE_PREVIEW):
             raise InteractionError(f"Release {version_name} is not in finish 
phase")
 
-    return payload, asf_uid, project
+    return payload, asf_uid, project, release
 
 
 async def unfinished_releases(asfuid: str) -> list[tuple[str, str, 
list[sql.Release]]]:
diff --git a/atr/models/api.py b/atr/models/api.py
index 4be4f96..e4dcb59 100644
--- a/atr/models/api.py
+++ b/atr/models/api.py
@@ -72,6 +72,8 @@ class DistributeSshRegisterArgs(schema.Strict):
     jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=")
     ssh_key: str = schema.example("ssh-ed25519 
AAAAC3NzaC1lZDI1NTEgH5C9okWi0dh25AAAAIOMqqnkVzrm0SdG6UOoqKLsabl9GKJl")
     phase: str = schema.Field(strict=False, default="compose", 
json_schema_extra={"examples": ["compose", "finish"]})
+    asf_uid: str = schema.example("user")
+    project_name: str = schema.example("tooling")
     version: str = schema.example("0.0.1")
 
 
diff --git a/atr/post/distribution.py b/atr/post/distribution.py
index f5aea27..706bafa 100644
--- a/atr/post/distribution.py
+++ b/atr/post/distribution.py
@@ -21,8 +21,10 @@ from typing import Final
 
 import atr.blueprints.post as post
 import atr.db as db
+import atr.db.interaction as interaction
 import atr.get as get
 import atr.models.distribution as distribution
+import atr.models.sql as sql
 import atr.shared as shared
 import atr.storage as storage
 import atr.web as web
@@ -63,7 +65,14 @@ async def automate_form_process_page(
     release, committee = await 
shared.distribution.release_validated_and_committee(
         project, version, staging=staging, release_policy=True
     )
-
+    phase = interaction.TrustedProjectPhase.COMPOSE
+    match release.phase:
+        case sql.ReleasePhase.RELEASE_PREVIEW:
+            phase = interaction.TrustedProjectPhase.FINISH
+        case sql.ReleasePhase.RELEASE_CANDIDATE:
+            phase = interaction.TrustedProjectPhase.VOTE
+        case sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT:
+            phase = interaction.TrustedProjectPhase.COMPOSE
     async with 
storage.write_as_committee_member(committee_name=committee.name) as w:
         try:
             await w.distributions.automate(
@@ -73,6 +82,7 @@ async def automate_form_process_page(
                 dd.owner_namespace,
                 project,
                 version,
+                phase.value,
                 release.latest_revision_number,
                 dd.package,
                 dd.version,
diff --git a/atr/storage/writers/distributions.py 
b/atr/storage/writers/distributions.py
index d74404b..9179eed 100644
--- a/atr/storage/writers/distributions.py
+++ b/atr/storage/writers/distributions.py
@@ -105,6 +105,7 @@ class CommitteeMember(CommitteeParticipant):
         owner_namespace: str | None,
         project_name: str,
         version_name: str,
+        phase: str,
         revision_number: str | None,
         package: str,
         version: str,
@@ -119,6 +120,7 @@ class CommitteeMember(CommitteeParticipant):
                 version=version,
                 project_name=project_name,
                 version_name=version_name,
+                phase=phase,
                 platform=platform.name,
                 staging=staging,
                 asf_uid=self.__asf_uid,
diff --git a/atr/tasks/gha.py b/atr/tasks/gha.py
index 09741bc..115e5c4 100644
--- a/atr/tasks/gha.py
+++ b/atr/tasks/gha.py
@@ -48,6 +48,7 @@ class DistributionWorkflow(schema.Strict):
     staging: bool = schema.description("Whether this is a staging 
distribution")
     project_name: str = schema.description("Project name in ATR")
     version_name: str = schema.description("Version name in ATR")
+    phase: str = schema.description("Release phase in ATR")
     asf_uid: str = schema.description("ASF UID of the user triggering the 
workflow")
     committee_name: str = schema.description("Committee name in ATR")
     platform: str = schema.description("Distribution platform")
@@ -67,7 +68,9 @@ async def trigger_workflow(args: DistributionWorkflow, *, 
task_id: int | None =
         "ref": "main",
         "inputs": {
             "atr-id": unique_id,
+            "asf-uid": args.asf_uid,
             "project": args.project_name,
+            "phase": args.phase,
             "version": args.version_name,
             "distribution-owner-namespace": args.namespace,
             "distribution-package": args.package,


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

Reply via email to