This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git
The following commit(s) were added to refs/heads/main by this push:
new ac62339 Add a route to show check results for candidate draft files
ac62339 is described below
commit ac623397a125b00f5063e28b95fcdd8e92709156
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Mar 25 16:00:00 2025 +0200
Add a route to show check results for candidate draft files
---
atr/routes/files.py | 66 ++++++++++++++++++++++++++++++++++++++----
atr/templates/files-check.html | 24 +++++----------
atr/templates/files-list.html | 14 ++++-----
3 files changed, 75 insertions(+), 29 deletions(-)
diff --git a/atr/routes/files.py b/atr/routes/files.py
index 54307f1..d515634 100644
--- a/atr/routes/files.py
+++ b/atr/routes/files.py
@@ -20,6 +20,7 @@
from __future__ import annotations
import asyncio
+import datetime
import logging
import pathlib
import re
@@ -354,7 +355,7 @@ async def root_files_list(session: CommitterSession,
project_name: str, version_
path_warnings = {}
path_errors = {}
path_modified = {}
- path_tasks: dict[pathlib.Path, dict[str, Any]] = {}
+ path_tasks: dict[pathlib.Path, int] = {}
for path in paths:
# Get template and substitutions
elements = {
@@ -390,14 +391,15 @@ async def root_files_list(session: CommitterSession,
project_name: str, version_
# Get tasks
tasks = await data.task(
- status=models.TaskStatus.COMPLETED,
release_name=f"{project_name}-{version_name}",
path=str(path),
modified=path_modified[path],
).all()
- path_tasks[path] = {}
- for task in tasks:
- path_tasks[path][task.task_type] = task.result
+ path_tasks[path] = sum(
+ 1
+ for task in tasks
+ if (task.status == models.TaskStatus.COMPLETED) or (task.status ==
models.TaskStatus.FAILED)
+ )
return await quart.render_template(
"files-list.html",
@@ -416,3 +418,57 @@ async def root_files_list(session: CommitterSession,
project_name: str, version_
modified=path_modified,
tasks=path_tasks,
)
+
+
+@committer_route("/files/checks/<project_name>/<version_name>/<path:file_path>")
+async def root_files_checks(session: CommitterSession, project_name: str,
version_name: str, file_path: str) -> str:
+ """Show the status of all checks for a specific file."""
+ # Check that the user has access to the project
+ if not any((p.name == project_name) for p in (await
session.user_projects)):
+ raise base.ASFQuartException("You do not have access to this project",
errorcode=403)
+
+ async with db.session() as data:
+ # Check that the release exists
+ release = await data.release(name=f"{project_name}-{version_name}",
_project=True).demand(
+ base.ASFQuartException("Release does not exist", errorcode=404)
+ )
+
+ full_path = str(util.get_candidate_draft_dir() / project_name /
version_name / file_path)
+
+ # Check that the file exists
+ if not await aiofiles.os.path.exists(full_path):
+ raise base.ASFQuartException("File does not exist", errorcode=404)
+
+ modified = int(await aiofiles.os.path.getmtime(full_path))
+ file_size = await aiofiles.os.path.getsize(full_path)
+
+ # Get the tasks for this file
+ tasks = await data.task(
+ release_name=f"{project_name}-{version_name}",
+ path=str(file_path),
+ modified=modified,
+ ).all()
+
+ # This shows all tasks, including repeated tasks
+ # TODO: Only show the most recent task for each task type
+ all_tasks_completed = all(
+ task.status in (models.TaskStatus.COMPLETED,
models.TaskStatus.FAILED) for task in tasks
+ )
+
+ file_data = {
+ "filename": pathlib.Path(file_path).name,
+ "bytes_size": file_size,
+ "uploaded": datetime.datetime.fromtimestamp(modified, tz=datetime.UTC),
+ }
+
+ return await quart.render_template(
+ "files-check.html",
+ project_name=project_name,
+ version_name=version_name,
+ file_path=file_path,
+ package=file_data,
+ release=release,
+ tasks=tasks,
+ all_tasks_completed=all_tasks_completed,
+ format_file_size=routes.format_file_size,
+ )
diff --git a/atr/templates/files-check.html b/atr/templates/files-check.html
index 13f6a77..d14cf17 100644
--- a/atr/templates/files-check.html
+++ b/atr/templates/files-check.html
@@ -1,24 +1,22 @@
{% extends "layouts/base.html" %}
{% block title %}
- Package check status ~ ATR
+ File check status ~ ATR
{% endblock title %}
{% block description %}
- View the status and results of package verification tasks.
+ View the status and results of file verification tasks.
{% endblock description %}
{% block content %}
- <a href="{{ url_for('root_candidate_review') }}" class="back-link">← Back to
Release Candidates</a>
+ <a href="{{ url_for('root_files_list', project_name=project_name,
version_name=version_name) }}"
+ class="back-link">← Back to Files List</a>
<div class="p-3 mb-4 bg-light border rounded">
- <h2 class="mt-0">Package details</h2>
+ <h2 class="mt-0">File details</h2>
<p>
<strong>Filename:</strong> {{ package.filename }}
</p>
- <p>
- <strong>Type:</strong> {{ package.artifact_type }}
- </p>
<p>
<strong>Size:</strong> {{ format_file_size(package.bytes_size) }}
</p>
@@ -73,15 +71,7 @@
<div class="d-flex gap-3 mb-3">
<button type="button" onclick="toggleAllDetails()" class="btn
btn-secondary">Toggle all details</button>
{% if tasks and all_tasks_completed %}
- <form method="post"
- action="{{ url_for('root_package_check_restart') }}"
- class="m-0">
- <input type="hidden"
- name="artifact_sha3"
- value="{{ package.artifact_sha3 }}" />
- <input type="hidden" name="release_name" value="{{ release.name }}" />
- <button type="submit" class="btn btn-primary">Restart all
checks</button>
- </form>
+ <!-- Currently there's no direct way to restart file checks through the
UI -->
{% endif %}
</div>
@@ -197,7 +187,7 @@
</div>
{% endfor %}
{% else %}
- <p>No verification tasks found for this package.</p>
+ <p>No verification tasks found for this file.</p>
{% endif %}
</div>
{% endblock content %}
diff --git a/atr/templates/files-list.html b/atr/templates/files-list.html
index beede3f..fbfb805 100644
--- a/atr/templates/files-list.html
+++ b/atr/templates/files-list.html
@@ -5,12 +5,12 @@
{% endblock title %}
{% block description %}
- View the files for the {{ project_name }} {{ version_name }} release.
+ View the files for the {{ project_name }} {{ version_name }} candidate draft.
{% endblock description %}
{% block content %}
<h1>Files for {{ release.project.display_name }} {{ version_name }}</h1>
- <p class="intro">This page shows the files for the {{ project_name }} {{
version_name }} release.</p>
+ <p class="intro">This page shows the files for the {{ project_name }} {{
version_name }} candidate draft.</p>
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
@@ -26,7 +26,7 @@
<strong>Version:</strong> {{ version_name }}
</p>
<p>
- <strong>Full name:</strong> {{ release.name }}
+ <strong>Label:</strong> {{ release.name }}
</p>
</div>
<div class="col-md-6">
@@ -82,10 +82,10 @@
</td>
<td>
{% if path in tasks %}
- {% for task_type, task_result in tasks[path].items() %}
- <pre>{{ task_type }}</pre>
- <pre>{{ task_result }}</pre>
- {% endfor %}
+ <a href="{{ url_for('root_files_checks',
project_name=project_name, version_name=version_name, file_path=path) }}"
+ class="btn btn-sm btn-outline-primary">View {{
tasks[path] }} check(s)</a>
+ {% else %}
+ No tasks
{% endif %}
</td>
</tr>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]