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]