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 4cbc209 Store data posted from GitHub during upload
4cbc209 is described below
commit 4cbc2093cffa900e3400c55280b0435e05cd9edc
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Feb 3 19:59:35 2026 +0000
Store data posted from GitHub during upload
---
.gitignore | 1 +
atr/api/__init__.py | 2 ++
atr/attestable.py | 13 +++++++++++-
atr/models/sql.py | 3 +++
atr/ssh.py | 16 ++++++++++++++-
atr/storage/writers/ssh.py | 6 +++++-
migrations/versions/0047_2026.02.03_525fe161.py | 27 +++++++++++++++++++++++++
7 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index 7518006..4ab21d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ __pycache__/
.venv-uv/
.vscode/
*.pyc
+*.tmp.py
apptoken.txt
atr/_version.py
bootstrap/build/
diff --git a/atr/api/__init__.py b/atr/api/__init__.py
index b1041e6..e7705a2 100644
--- a/atr/api/__init__.py
+++ b/atr/api/__init__.py
@@ -273,6 +273,7 @@ async def distribute_ssh_register(data:
models.api.DistributeSshRegisterArgs) ->
payload["actor_id"],
release.project_name,
data.ssh_key,
+ payload,
)
return models.api.DistributeSshRegisterResults(
@@ -797,6 +798,7 @@ async def publisher_ssh_register(data:
models.api.PublisherSshRegisterArgs) -> D
payload["actor_id"],
project.name,
data.ssh_key,
+ payload,
)
return models.api.PublisherSshRegisterResults(
diff --git a/atr/attestable.py b/atr/attestable.py
index 01ed8ed..d576236 100644
--- a/atr/attestable.py
+++ b/atr/attestable.py
@@ -18,7 +18,7 @@
from __future__ import annotations
import json
-from typing import TYPE_CHECKING, Final
+from typing import TYPE_CHECKING, Any, Final
import aiofiles
import aiofiles.os
@@ -47,6 +47,17 @@ async def compute_file_hash(path: pathlib.Path) -> str:
return f"blake3:{hasher.hexdigest()}"
+def github_tp_payload_path(project_name: str, version_name: str,
revision_number: str) -> pathlib.Path:
+ return util.get_attestable_dir() / project_name / version_name /
f"{revision_number}.github-tp.json"
+
+
+async def github_tp_payload_write(
+ project_name: str, version_name: str, revision_number: str,
github_payload: dict[str, Any]
+) -> None:
+ payload_path = github_tp_payload_path(project_name, version_name,
revision_number)
+ await util.atomic_write_file(payload_path, json.dumps(github_payload,
indent=2))
+
+
async def load(
project_name: str,
version_name: str,
diff --git a/atr/models/sql.py b/atr/models/sql.py
index 0dc7780..61a5c62 100644
--- a/atr/models/sql.py
+++ b/atr/models/sql.py
@@ -442,6 +442,9 @@ class WorkflowSSHKey(sqlmodel.SQLModel, table=True):
asf_uid: str = sqlmodel.Field(index=True)
github_uid: str = sqlmodel.Field(index=True)
github_nid: int = sqlmodel.Field(index=True)
+ github_payload: dict[str, Any] = sqlmodel.Field(
+ default_factory=dict, sa_column=sqlalchemy.Column(sqlalchemy.JSON,
nullable=False)
+ )
expires: int = sqlmodel.Field()
diff --git a/atr/ssh.py b/atr/ssh.py
index 074ed37..b04031a 100644
--- a/atr/ssh.py
+++ b/atr/ssh.py
@@ -25,12 +25,13 @@ import os
import stat
import string
import time
-from typing import Final
+from typing import Any, Final
import aiofiles
import aiofiles.os
import asyncssh
+import atr.attestable as attestable
import atr.config as config
import atr.db as db
import atr.log as log
@@ -57,6 +58,7 @@ class SSHServer(asyncssh.SSHServer):
# Store connection for use in begin_auth
self._conn = conn
self._github_asf_uid: str | None = None
+ self._github_payload: dict[str, Any] | None = None
peer_addr = conn.get_extra_info("peername")[0]
log.info(f"SSH connection received from {peer_addr}")
@@ -130,6 +132,7 @@ class SSHServer(asyncssh.SSHServer):
return False
self._github_asf_uid = workflow_key.asf_uid
+ self._github_payload = workflow_key.github_payload
return True
def _get_asf_uid(self, process: asyncssh.SSHServerProcess) -> str:
@@ -140,6 +143,12 @@ class SSHServer(asyncssh.SSHServer):
return self._github_asf_uid
return username
+ def _get_github_payload(self, process: asyncssh.SSHServerProcess) ->
dict[str, Any] | None:
+ username = process.get_extra_info("username")
+ if username != "github":
+ return None
+ return self._github_payload
+
async def server_start() -> asyncssh.SSHAcceptor:
"""Start the SSH server."""
@@ -580,6 +589,11 @@ async def _step_07b_process_validated_rsync_write(
raise types.FailedError(f"rsync upload failed with exit status
{exit_status} for {for_revision}")
if creating.new is not None:
+ github_payload = server._get_github_payload(process)
+ if github_payload is not None:
+ await attestable.github_tp_payload_write(
+ project_name, version_name, creating.new.number,
github_payload
+ )
log.info(f"rsync upload successful for revision
{creating.new.number}")
host = config.get().APP_HOST
message = f"\nATR: Created revision {creating.new.number} of
{project_name} {version_name}\n"
diff --git a/atr/storage/writers/ssh.py b/atr/storage/writers/ssh.py
index 932d867..555a173 100644
--- a/atr/storage/writers/ssh.py
+++ b/atr/storage/writers/ssh.py
@@ -19,6 +19,7 @@
from __future__ import annotations
import time
+from typing import Any
import atr.db as db
import atr.models.sql as sql
@@ -83,7 +84,9 @@ class CommitteeParticipant(FoundationCommitter):
self.__asf_uid = asf_uid
self.__committee_name = committee_name
- async def add_workflow_key(self, github_uid: str, github_nid: int,
project_name: str, key: str) -> tuple[str, int]:
+ async def add_workflow_key(
+ self, github_uid: str, github_nid: int, project_name: str, key: str,
github_payload: dict[str, Any]
+ ) -> tuple[str, int]:
now = int(time.time())
# Twenty minutes to upload all files
ttl = 20 * 60
@@ -96,6 +99,7 @@ class CommitteeParticipant(FoundationCommitter):
asf_uid=self.__asf_uid,
github_uid=github_uid,
github_nid=github_nid,
+ github_payload=github_payload,
expires=expires,
)
self.__data.add(wsk)
diff --git a/migrations/versions/0047_2026.02.03_525fe161.py
b/migrations/versions/0047_2026.02.03_525fe161.py
new file mode 100644
index 0000000..a8b9ac4
--- /dev/null
+++ b/migrations/versions/0047_2026.02.03_525fe161.py
@@ -0,0 +1,27 @@
+"""Add a payload property to GitHub SSH keys
+
+Revision ID: 0047_2026.02.03_525fe161
+Revises: 0046_2026.01.30_72330898
+Create Date: 2026-02-03 19:49:11.922836+00:00
+"""
+
+from collections.abc import Sequence
+
+import sqlalchemy as sa
+from alembic import op
+
+# Revision identifiers, used by Alembic
+revision: str = "0047_2026.02.03_525fe161"
+down_revision: str | None = "0046_2026.01.30_72330898"
+branch_labels: str | Sequence[str] | None = None
+depends_on: str | Sequence[str] | None = None
+
+
+def upgrade() -> None:
+ with op.batch_alter_table("workflowsshkey", schema=None) as batch_op:
+ batch_op.add_column(sa.Column("github_payload", sa.JSON(),
nullable=False, server_default="{}"))
+
+
+def downgrade() -> None:
+ with op.batch_alter_table("workflowsshkey", schema=None) as batch_op:
+ batch_op.drop_column("github_payload")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]