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 106a01c  Integrate blocking check results into the user interface
106a01c is described below

commit 106a01c2208d18855514158b254f639b876de104
Author: Sean B. Palmer <[email protected]>
AuthorDate: Fri Feb 6 14:41:37 2026 +0000

    Integrate blocking check results into the user interface
---
 atr/static/css/atr.css                  |  4 ++++
 atr/storage/readers/releases.py         | 12 ++++++++++++
 atr/templates/report-selected-path.html | 33 +++++++++++++++++++++++++--------
 tests/e2e/compose/test_get.py           |  8 +++++---
 4 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/atr/static/css/atr.css b/atr/static/css/atr.css
index f006bcc..cae5755 100644
--- a/atr/static/css/atr.css
+++ b/atr/static/css/atr.css
@@ -564,3 +564,7 @@ td.atr-shrink {
 .atr-text-strike {
     text-decoration: line-through;
 }
+
+.atr-bg-blocking {
+    background-color: rgb(111 0 193 / 75%);
+}
diff --git a/atr/storage/readers/releases.py b/atr/storage/readers/releases.py
index 669fbfb..b2fe5b2 100644
--- a/atr/storage/readers/releases.py
+++ b/atr/storage/readers/releases.py
@@ -126,6 +126,18 @@ class GeneralPublic:
         await self.__successes(cs)
         await self.__warnings(cs)
         await self.__errors(cs)
+        await self.__blocking(cs)
+
+    async def __blocking(self, cs: types.ChecksSubset) -> None:
+        blocking = await self.__data.check_result(
+            release_name=cs.release.name,
+            revision_number=cs.latest_revision_number,
+            member_rel_path=None,
+            status=sql.CheckResultStatus.BLOCKING,
+        ).all()
+        for result in blocking:
+            if primary_rel_path := result.primary_rel_path:
+                cs.info.errors.setdefault(pathlib.Path(primary_rel_path), 
[]).append(result)
 
     async def __errors(self, cs: types.ChecksSubset) -> None:
         errors = await self.__data.check_result(
diff --git a/atr/templates/report-selected-path.html 
b/atr/templates/report-selected-path.html
index c6ddc96..bbd7b67 100644
--- a/atr/templates/report-selected-path.html
+++ b/atr/templates/report-selected-path.html
@@ -51,9 +51,10 @@
     <code>{{ package.filename }}</code>
   </div>
   {% if primary_results %}
+    {% set blocking_count = primary_results|selectattr("status.value", 
"equalto", "blocking")|list|length %}
     {% set status_counts = {
     "success": primary_results|selectattr("status.value", "equalto", 
"success")|list|length,
-    "failure": primary_results|selectattr("status.value", "equalto", 
"failure")|list|length,
+    "failure": (primary_results|selectattr("status.value", "equalto", 
"failure")|list|length) + blocking_count,
     "warning": primary_results|selectattr("status.value", "equalto", 
"warning")|list|length,
     "exception": primary_results|selectattr("status.value", "equalto", 
"exception")|list|length
     } %}
@@ -107,7 +108,7 @@
         </thead>
         <tbody>
           {% for primary_result in primary_results %}
-            <tr class="atr-result-primary atr-result-status-{{ 
primary_result.status.value }} {% if primary_result.status.value == 'success' 
and not all_primary_are_success %}atr-hide{% endif %}">
+            <tr class="atr-result-primary atr-result-status-{{ 'failure' if 
primary_result.status.value == 'blocking' else primary_result.status.value }} 
{% if primary_result.status.value == 'success' and not all_primary_are_success 
%}atr-hide{% endif %}">
               <th scope="row" class="align-middle fw-bold">{{ 
function_name_from_key(primary_result.checker) }}</th>
               <td class="align-middle text-break">
                 {% if primary_result.data is mapping and 
primary_result.data.keys()|length > 0 %}
@@ -213,9 +214,16 @@
               </td>
               <td class="align-middle text-center atr-sans">
                 <div class="d-inline-flex flex-column align-items-center 
gap-1">
-                  <span class="badge rounded-pill {% if 
primary_result.status.value == "success" %}bg-success {% elif 
primary_result.status.value == "failure" %}bg-danger {% elif 
primary_result.status.value == "warning" %}bg-warning {% elif 
primary_result.status.value == "exception" %}bg-danger {% else %}bg-secondary{% 
endif %}">
-                    {{ primary_result.status.value|title }}
+                  <span class="badge rounded-pill {% if 
primary_result.status.value == "success" %}bg-success {% elif 
primary_result.status.value == "failure" or primary_result.status.value == 
"blocking" %}bg-danger {% elif primary_result.status.value == "warning" 
%}bg-warning {% elif primary_result.status.value == "exception" %}bg-danger {% 
else %}bg-secondary{% endif %}">
+                    {{ "Failure" if primary_result.status.value == "blocking" 
else primary_result.status.value|title }}
                   </span>
+                  {% if primary_result.status.value == "blocking" %}
+                    <span class="badge rounded-pill atr-bg-blocking border 
small"
+                          title="You cannot release when there is a blocking 
check result"
+                          aria-label="You cannot release when there is a 
blocking check result">
+                      <i class="bi bi-shield-lock me-1"></i>Blocking
+                    </span>
+                  {% endif %}
                   {% if primary_result.cached %}
                     <span class="badge rounded-pill bg-secondary-subtle 
text-secondary-emphasis border border-secondary-subtle small"
                           title="Cached result"
@@ -239,7 +247,9 @@
       {% set member_status_counts = {"success": 0, "failure": 0, "warning": 0, 
"exception": 0} %}
       {% for path, m_results in member_results.items() %}
         {% for m_result in m_results %}
-          {% if m_result.status.value in member_status_counts %}
+          {% if m_result.status.value == "blocking" %}
+            {% set _ = member_status_counts.update({"failure": 
member_status_counts.failure + 1}) %}
+          {% elif m_result.status.value in member_status_counts %}
             {% set _ = member_status_counts.update({m_result.status.value: 
member_status_counts[m_result.status.value] + 1}) %}
           {% endif %}
         {% endfor %}
@@ -288,7 +298,7 @@
             {% for member_result in member_results_list %}
               {# The striping class here is now technically redundant because 
of the JS striping #}
               {# But we leave it here for clean initial page rendering #}
-              <tr class="atr-result-member atr-result-status-{{ 
member_result.status.value }} {% if member_result.status.value == 'success' and 
not all_member_are_success %}atr-hide{% endif %} {% if loop.index is odd 
%}page-member-visible-odd{% endif %} ">
+              <tr class="atr-result-member atr-result-status-{{ 'failure' if 
member_result.status.value == 'blocking' else member_result.status.value }} {% 
if member_result.status.value == 'success' and not all_member_are_success 
%}atr-hide{% endif %} {% if loop.index is odd %}page-member-visible-odd{% endif 
%} ">
                 <td class="align-middle">{{ member_rel_path }}</td>
                 <th scope="row" class="align-middle fw-bold">{{ 
function_name_from_key(member_result.checker) }}</th>
                 <td class="align-middle text-break">
@@ -296,9 +306,16 @@
                 </td>
                 <td class="align-middle text-center atr-sans">
                   <div class="d-inline-flex flex-column align-items-center 
gap-1">
-                    <span class="badge rounded-pill {% if 
member_result.status.value == "success" %}bg-success {% elif 
member_result.status.value == "failure" %}bg-danger {% elif 
member_result.status.value == "warning" %}bg-warning {% elif 
member_result.status.value == "exception" %}bg-danger {% else %}bg-secondary{% 
endif %}">
-                      {{ member_result.status.value|title }}
+                    <span class="badge rounded-pill {% if 
member_result.status.value == "success" %}bg-success {% elif 
member_result.status.value == "failure" or member_result.status.value == 
"blocking" %}bg-danger {% elif member_result.status.value == "warning" 
%}bg-warning {% elif member_result.status.value == "exception" %}bg-danger {% 
else %}bg-secondary{% endif %}">
+                      {{ "Failure" if member_result.status.value == "blocking" 
else member_result.status.value|title }}
                     </span>
+                    {% if member_result.status.value == "blocking" %}
+                      <span class="badge rounded-pill atr-bg-blocking border 
small"
+                            title="You cannot release when there is a blocking 
check result"
+                            aria-label="You cannot release when there is a 
blocking check result">
+                        <i class="bi bi-shield-lock me-1"></i>Blocking
+                      </span>
+                    {% endif %}
                     {% if member_result.cached %}
                       <span class="badge rounded-pill bg-secondary-subtle 
text-secondary-emphasis border border-secondary-subtle small"
                             title="Cached result"
diff --git a/tests/e2e/compose/test_get.py b/tests/e2e/compose/test_get.py
index edfd24a..4f68fbc 100644
--- a/tests/e2e/compose/test_get.py
+++ b/tests/e2e/compose/test_get.py
@@ -45,9 +45,11 @@ def test_ongoing_tasks_banner_has_task_count(page_compose: 
Page) -> None:
     restart_button = page_compose.get_by_role("button", name="Restart all 
checks")
     restart_button.click()
 
-    count_element = page_compose.locator("#ongoing-tasks-count")
-    expect(count_element).to_be_visible(timeout=10000)
-    expect(count_element).not_to_be_empty()
+    banner = page_compose.locator("#ongoing-tasks-banner")
+    expect(banner).to_be_visible(timeout=10000)
+
+    count_element = banner.locator("#ongoing-tasks-count")
+    expect(count_element).to_have_text(re.compile(r"\d+"))
 
 
 def test_ongoing_tasks_banner_has_warning_icon(page_compose: Page) -> None:


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

Reply via email to