You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by ar...@apache.org on 2026/08/05 08:56:25 UTC
(tooling-trusted-releases) branch arm updated: #1488 - allow archiving project with archived releases
This is an automated email from the ASF dual-hosted git repository.
alitheg pushed a commit to branch arm
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/arm by this push:
new fc8f7829 #1488 - allow archiving project with archived releases
fc8f7829 is described below
commit fc8f78297cf5a95e83e32c2ef86ad4b5981f0841
Author: Alastair McFarlane <ar...@apache.org>
AuthorDate: Wed Aug 5 09:55:55 2026 +0100
#1488 - allow archiving project with archived releases
---
atr/db/interaction.py | 15 ++++++++++++---
atr/get/projects.py | 10 +++++-----
atr/post/projects.py | 7 +++++--
3 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/atr/db/interaction.py b/atr/db/interaction.py
index bd126fd1..31b6bd46 100644
--- a/atr/db/interaction.py
+++ b/atr/db/interaction.py
@@ -565,12 +565,21 @@ def project_order_key(project: sql.Project, latest_release: datetime.datetime |
async def project_release_counts(data: db.Session) -> dict[str, tuple[int, int]]:
via = sql.validate_instrumented_attribute
- non_draft_case = sqlalchemy.case((via(sql.Release.phase) != sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT, 1), else_=0)
+ active_case = sqlalchemy.case(
+ (
+ sqlalchemy.and_(
+ via(sql.Release.phase) != sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT,
+ via(sql.Release.is_archived).is_(False),
+ ),
+ 1,
+ ),
+ else_=0,
+ )
query = sqlmodel.select(
- sql.Release.project_key, sqlalchemy.func.count(), sqlalchemy.func.sum(non_draft_case)
+ sql.Release.project_key, sqlalchemy.func.count(), sqlalchemy.func.sum(active_case)
).group_by(via(sql.Release.project_key))
result = await data.execute(query)
- return {key: (total, non_draft) for key, total, non_draft in result.all()}
+ return {key: (total, active) for key, total, active in result.all()}
async def release_completed_svn_publish_task(
diff --git a/atr/get/projects.py b/atr/get/projects.py
index a0267b70..8c4d134d 100644
--- a/atr/get/projects.py
+++ b/atr/get/projects.py
@@ -188,7 +188,7 @@ async def projects(session: web.Committer, _projects: Literal["projects"]) -> st
continue
if project.committee and committee_project_counts[str(project.committee.key)] <= 1:
continue
- total_releases, non_draft_releases = release_counts.get(str(project.key), (0, 0))
+ total_releases, active_releases = release_counts.get(str(project.key), (0, 0))
if total_releases == 0:
action_forms[str(project.key)] = await form.render(
model_cls=shared.projects.DeleteSelectedProject,
@@ -203,7 +203,7 @@ async def projects(session: web.Committer, _projects: Literal["projects"]) -> st
" ready to delete only if the vote passes, and you must then return to complete it."
),
)
- elif non_draft_releases == 0:
+ elif active_releases == 0:
action_forms[str(project.key)] = await form.render(
model_cls=shared.projects.ArchiveSelectedProject,
action=util.as_url(post.projects.archive),
@@ -215,7 +215,7 @@ async def projects(session: web.Committer, _projects: Literal["projects"]) -> st
confirm=(
"This starts a binding CAP approval vote by the committee PMC. ATR will mark the project"
" ready to archive only if the vote passes, and you must then return to complete it, which"
- " deletes the draft releases and retires the project."
+ " deletes any draft releases and retires the project."
),
)
@@ -553,7 +553,7 @@ async def _delete_form(project: sql.Project) -> htm.Element | None:
),
empty=True,
)
- elif all(r.phase == sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT for r in releases):
+ elif not any((r.phase != sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT) and (not r.is_archived) for r in releases):
delete_form = await form.render(
model_cls=shared.projects.ArchiveSelectedProject,
action=util.as_url(post.projects.archive),
@@ -565,7 +565,7 @@ async def _delete_form(project: sql.Project) -> htm.Element | None:
confirm=(
"This starts a binding CAP approval vote by the committee PMC. ATR will mark the project"
" ready to archive only if the vote passes, and you must then return to complete it, which"
- " deletes the draft releases and retires the project."
+ " deletes any draft releases and retires the project."
),
)
return delete_form
diff --git a/atr/post/projects.py b/atr/post/projects.py
index e6435353..6bb7f78a 100644
--- a/atr/post/projects.py
+++ b/atr/post/projects.py
@@ -188,8 +188,11 @@ def _action_eligibility_error(
return None
if (not completing) and (not releases):
return f"Project '{project.key}' has no releases to archive."
- if not all(r.phase == sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT for r in releases):
- return f"Project '{project.key}' has non-draft releases and cannot be archived."
+ active_releases = [
+ r for r in releases if (r.phase != sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT) and (not r.is_archived)
+ ]
+ if active_releases:
+ return f"Project '{project.key}' has active releases and cannot be archived."
if not completing:
return None
new_drafts = [r for r in releases if (requested_at is None) or (r.created > requested_at)]
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org