asf-tooling commented on issue #751:
URL: 
https://github.com/apache/tooling-trusted-releases/issues/751#issuecomment-4404066604

   <!-- gofannon-issue-triage-bot v2 -->
   
   **Automated triage** — analyzed at `main@837830e8`
   
   **Type:** `discussion`  •  **Classification:** `no_action`  •  
**Confidence:** `high`
   **Application domain(s):** `release_lifecycle`, `distribution_publishing`
   
   ### Summary
   This is an active investigation/RFC about whether ATR should support remote 
promotion of staged artifacts on third-party distribution platforms. @dave2wave 
established a platform capability matrix and noted the investigation should 
ultimately fill in DistributionPlatformValue fields in sql.py. @andrewmusselman 
posted a comprehensive investigation document (April 14) and followed up with 
corrections and a schema proposal (May 1). The team has not yet converged on a 
final implementation decision — the most recent comment is still an RFC 
requesting review.
   
   ### Where this lives in the code today
   
   #### `atr/storage/writers/distributions.py` — 
`CommitteeMember.__upgrade_staging_to_final` (lines 272-301)
   _currently does this_
   Already handles upgrading a staging distribution record to final within 
ATR's database — the local-side of 'promotion' is partially implemented, but 
this does NOT perform remote promotion on the third-party platform.
   
   ```python
       async def __upgrade_staging_to_final(
           self,
           release_key: models.safe.ReleaseKey,
           platform: models.sql.DistributionPlatform,
           owner_namespace: str | None,
           package: str,
           version: str,
           pending: bool,
           upload_date: datetime.datetime | None,
           api_url: str | None,
           web_url: str | None,
       ) -> models.sql.Distribution | None:
           tag = f"{release_key} {platform} {owner_namespace or ''} {package} 
{version}"
           existing = await self.__data.distribution(
               release_key=str(release_key),
               platform=platform,
               owner_namespace=(owner_namespace or ""),
               package=package,
               version=version,
           ).demand(RuntimeError(f"Distribution {tag} not found"))
           if existing.staging:
               existing.staging = False
               existing.pending = pending
               existing.upload_date = upload_date
               existing.api_url = api_url
               existing.web_url = web_url
               existing.created_by = self.__asf_uid
               await self.__data.commit()
               return existing
           return None
   ```
   
   #### `atr/storage/writers/distributions.py` — `CommitteeMember.record` 
(lines 143-181)
   _currently does this_
   The record method already checks if a production recording should upgrade a 
staging record rather than creating a new one — this is the ATR-internal side 
of promotion logic.
   
   ```python
       async def record(
           self,
           release_key: models.safe.ReleaseKey,
           platform: models.sql.DistributionPlatform,
           owner_namespace: models.safe.Alphanumeric | None,
           package: models.safe.Alphanumeric,
           version: models.safe.VersionKey,
           staging: bool,
           pending: bool,
           upload_date: datetime.datetime | None,
           api_url: str | None = None,
           web_url: str | None = None,
       ) -> tuple[models.sql.Distribution, bool]:
           namespace = str(owner_namespace) if owner_namespace else ""
           existing = await self.__data.distribution(
               str(release_key), platform, namespace, str(package), str(version)
           ).get()
           ...
           # If we're doing production and existing was for staging, upgrade it
           if (not staging) and existing.staging:
               upgraded = await self.__upgrade_staging_to_final(
                   release_key,
                   platform,
                   namespace,
                   str(package),
                   str(version),
                   pending,
                   upload_date,
                   api_url,
                   web_url,
               )
               if upgraded is not None:
                   self.__write_as.append_to_audit_log(
                       asf_uid=self.__asf_uid,
                       operation="distribution_upgrade",
                       release_key=str(release_key),
                       platform=platform.name,
                   )
                   return upgraded, False
   ```
   
   #### `atr/shared/distribution.py` — `DistributionPlatform` (lines 78-86)
   _currently does this_
   The current set of distribution platforms — no HEX/Erlang member exists yet, 
as @andrewmusselman noted in review.
   
   ```python
   class DistributionPlatform(enum.Enum):
       """Wrapper enum for distribution platforms."""
   
       ARTIFACT_HUB = "Artifact Hub"
       DOCKER_HUB = "Docker Hub"
       MAVEN = "Maven Central"
       NPM = "npm"
       NPM_SCOPED = "npm (scoped)"
       PYPI = "PyPI"
   ```
   
   #### `atr/shared/distribution.py` — `_template_url` (lines 439-458)
   _currently does this_
   Shows that staging URL support is currently limited to ArtifactHub, PyPI, 
and Maven — relevant to the investigation's question of which platforms support 
staging/promotion.
   
   ```python
   def _template_url(
       dd: distribution.Data,
       staging: bool | None = None,
   ) -> str:
       if staging is False:
           return dd.platform.value.template_url
   
       supported = {
           sql.DistributionPlatform.ARTIFACT_HUB,
           sql.DistributionPlatform.PYPI,
           sql.DistributionPlatform.MAVEN,
       }
       if dd.platform not in supported:
           raise RuntimeError("Staging is currently supported only for 
ArtifactHub, PyPI and Maven Central.")
   
       template_url = dd.platform.value.template_staging_url
       if template_url is None:
           raise RuntimeError("This platform does not provide a staging API 
endpoint.")
   
       return template_url
   ```
   
   #### `atr/tasks/distribution.py` — `status_check` (lines 30-43)
   _currently does this_
   Background task that retries pending distributions — would need modification 
if remote promotion were added as a new distribution lifecycle step.
   
   ```python
   @checks.with_model(args.DistributionStatusCheckArgs)
   async def status_check(
       task_args: args.DistributionStatusCheckArgs, *, task_id: int | None = 
None
   ) -> results.Results | None:
       log.info("Checking pending recorded distributions")
       dists = []
       async with db.session() as data:
           dists = await data.distribution(
               pending=True, _with_release=True, _with_release_project=True, 
_limit=_BATCH_SIZE
           ).all()
       for dist in dists:
           name = f"{dist.platform} {dist.owner_namespace} {dist.package} 
{dist.version}"
           dd = dist.distribution_data()
           ...
   ```
   
   #### `atr/models/distribution.py` — `Metadata` (lines 111-115)
   _extension point_
   Distribution metadata model — @dave2wave noted this class would need to be 
extended with promotion-related fields if the investigation concludes promotion 
should be supported.
   
   ```python
   class Metadata(schema.Strict):
       api_url: str
       result: basic.JSON
       upload_date: datetime.datetime
       web_url: str | None
   ```
   
   ### Proposed approach
   This issue is an open investigation/RFC with active discussion as of 7 days 
ago. The team is not yet ready for implementation. @andrewmusselman's most 
recent comment (May 1) provides a detailed review of the investigation document 
with corrections and a narrower schema proposal, and is explicitly labeled 
'RFC' awaiting review from @sbp, @dave2wave, and @alitheg. The headline 
conclusion from the investigation is: skip Maven promotion (continue using 
RAO), no-op for PyPI/Hex/Artifact Hub, and promotion is a marginal win only for 
Docker Hub and npm (via dist-tags) and GitHub Releases (prerelease→release). No 
implementation patches should be proposed until the RFC is resolved and the 
team converges on which platforms to implement promotion for, and whether the 
complexity tradeoff is worth it.
   
   ### Open questions
   - The team hasn't decided which platforms (if any) warrant implementing 
remote promotion — this is the core question of the RFC.
   - Whether a `has_promotion` or `supports_remote_promote` field should be 
added to DistributionPlatformValue in sql.py, and what its semantics would be.
   - Whether Hex/Erlang should be added as a DistributionPlatform enum member 
as a prerequisite or separate issue.
   - Whether the revision-tracking caveat (ensuring promoted files match those 
voted on) requires new schema fields to record which revision was staged.
   - @andrewmusselman's full schema proposal was truncated — the complete 
proposal needs to be reviewed by the team.
   
   _The agent reviewed this issue and is not proposing patches in this run. 
Review the existing-code citations and open questions above before deciding 
next steps._
   
   ### Files examined
   - `atr/get/finish.py`
   - `atr/get/distribution.py`
   - `atr/models/distribution.py`
   - `atr/post/distribution.py`
   - `atr/post/finish.py`
   - `atr/shared/distribution.py`
   - `atr/storage/writers/distributions.py`
   - `atr/tasks/distribution.py`
   
   ---
   *Draft from a triage agent. A human reviewer should validate before merging 
any change. The agent did not run tests or verify diffs apply.*


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to