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 41a9f63  Add debugging for a CI problem
41a9f63 is described below

commit 41a9f63890d4e037b72e2b8fef19ce3ff4d84e38
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Jan 5 15:25:57 2026 +0000

    Add debugging for a CI problem
---
 atr/get/checks.py  | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 playwright/test.py | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/atr/get/checks.py b/atr/get/checks.py
index 1781b2f..ec4cbb3 100644
--- a/atr/get/checks.py
+++ b/atr/get/checks.py
@@ -24,6 +24,7 @@ import htpy
 import quart
 
 import atr.blueprints.get as get
+import atr.config as config
 import atr.db as db
 import atr.db.interaction as interaction
 import atr.form as form
@@ -165,6 +166,58 @@ async def selected_revision(
     checks_summary_elem = shared._render_checks_summary(info, project_name, 
version_name)
     checks_summary_html = str(checks_summary_elem) if checks_summary_elem else 
""
 
+    debug_and_allow_tests = (config.get_mode() == config.Mode.Debug) and 
config.get().ALLOW_TESTS
+    debug_path = quart.request.args.get("debug_path")
+    debug = None
+    if debug_and_allow_tests and debug_path and info is not None:
+        debug_path_obj = pathlib.Path(debug_path)
+        successes = info.successes.get(debug_path_obj, [])
+        warnings = info.warnings.get(debug_path_obj, [])
+        errors = info.errors.get(debug_path_obj, [])
+        ignored_errors = [cr for cr in info.ignored_errors if 
cr.primary_rel_path == debug_path]
+        ignored_warnings = [cr for cr in info.ignored_warnings if 
cr.primary_rel_path == debug_path]
+
+        def summarise(results: list[sql.CheckResult]) -> dict[str, object]:
+            return {
+                "count": len(results),
+                "checkers": sorted({cr.checker for cr in results}),
+                "messages": [cr.message for cr in results[:5]],
+            }
+
+        async with db.session() as data:
+            tasks_for_path = (
+                await data.task(
+                    project_name=project_name,
+                    version_name=version_name,
+                    revision_number=revision_number,
+                    primary_rel_path=debug_path,
+                )
+                .order_by(sql.Task.id)
+                .all()
+            )
+
+        debug_tasks = [
+            {
+                "id": t.id,
+                "type": t.task_type.value,
+                "status": t.status.value,
+                "error": t.error,
+                "started": t.started.isoformat() if t.started else None,
+                "completed": t.completed.isoformat() if t.completed else None,
+            }
+            for t in tasks_for_path
+        ]
+
+        debug = {
+            "path": debug_path,
+            "success": summarise(successes),
+            "warning": summarise(warnings),
+            "error": summarise(errors),
+            "ignored_error": summarise(ignored_errors),
+            "ignored_warning": summarise(ignored_warnings),
+            "tasks": debug_tasks,
+        }
+
     delete_file_forms: dict[str, str] = {}
     if release.phase == sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT:
         for path in paths:
@@ -202,6 +255,7 @@ async def selected_revision(
             "ongoing": ongoing_count,
             "checks_summary_html": checks_summary_html,
             "files_table_html": files_table_html,
+            "debug": debug,
         }
     )
 
diff --git a/playwright/test.py b/playwright/test.py
index ebe6fc2..4217984 100755
--- a/playwright/test.py
+++ b/playwright/test.py
@@ -622,7 +622,36 @@ def test_checks_02_license_files(page: Page, credentials: 
Credentials) -> None:
     row_locator = page.locator(f"tr:has(:text('{filename_targz}'))")
     evaluate_link_title = f"Show report for {filename_targz}"
     evaluate_link_locator = 
row_locator.locator(f'a[title="{evaluate_link_title}"]')
-    expect(evaluate_link_locator).to_be_visible()
+    try:
+        expect(evaluate_link_locator).to_be_visible()
+    except AssertionError:
+        logging.error(f"Did not find expected 'Show report' link for 
{filename_targz} on {compose_path}")
+        row_html = row_locator.first.inner_html()
+        logging.error(f"Row HTML for {filename_targz}:\n{row_html}")
+        links = row_locator.locator("a").all()
+        for i, link in enumerate(links[:10]):
+            href = link.get_attribute("href")
+            title = link.get_attribute("title")
+            text = link.inner_text()
+            logging.error(f"Row link {i}: text={text!r} title={title!r} 
href={href!r}")
+
+        revision_link_locator = 
page.locator(f'a[href^="/revisions/{project_name}/{version_name}#"]')
+        if revision_link_locator.is_visible(timeout=1000):
+            revision_href = revision_link_locator.get_attribute("href")
+            if revision_href:
+                revision = revision_href.split("#", 1)[-1]
+                debug_url = (
+                    
f"{ATR_BASE_URL}/checks/{project_name}/{version_name}/{revision}?debug_path={filename_targz}"
+                )
+                debug_response = page.request.get(debug_url)
+                logging.error(f"Debug checks response status: 
{debug_response.status}")
+                logging.error(f"Debug checks response 
body:\n{debug_response.text()}")
+
+        server_logs_url = f"{ATR_BASE_URL}/admin/logs"
+        server_logs_response = page.request.get(server_logs_url)
+        logging.error(f"Server logs response status: 
{server_logs_response.status}")
+        logging.error(f"Server logs response 
body:\n{server_logs_response.text()}")
+        raise
 
     logging.info(f"Clicking 'Show report' link for {filename_targz}")
     evaluate_link_locator.click()


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

Reply via email to