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-releases-client.git


The following commit(s) were added to refs/heads/main by this push:
     new d24a7f0  Add a command to wait for release checks to complete
d24a7f0 is described below

commit d24a7f0409af21f731464d7c53f459677054d6ca
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Jul 14 15:16:30 2025 +0100

    Add a command to wait for release checks to complete
---
 Makefile                    |  3 ++-
 pyproject.toml              |  4 ++--
 src/atrclient/client.py     | 36 +++++++++++++++++++++++++++++++-----
 src/atrclient/models/api.py |  4 ++++
 src/atrclient/models/sql.py |  8 +++++---
 tests/cli_workflow.t        |  3 +++
 tests/test_all.py           |  2 +-
 uv.lock                     |  4 ++--
 8 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/Makefile b/Makefile
index d6ff104..334ff14 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,8 @@ bump: install
        rm -f uv.lock
        uv lock
 
-check:
+check: bump
+       @# Always bump to ensure that we check the exact current version
        git add -A
        uv run pre-commit run --all-files
        @# TODO: Move this to .pre-commit-config.yaml?
diff --git a/pyproject.toml b/pyproject.toml
index d08e9d5..74aa123 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ build-backend = "hatchling.build"
 
 [project]
 name            = "apache-trusted-releases"
-version         = "0.20250711.1954"
+version         = "0.20250714.1413"
 description     = "ATR CLI and Python API"
 readme          = "README.md"
 requires-python = ">=3.13"
@@ -72,4 +72,4 @@ select = [
 ]
 
 [tool.uv]
-exclude-newer = "2025-07-11T19:54:00Z"
+exclude-newer = "2025-07-14T14:13:00Z"
diff --git a/src/atrclient/client.py b/src/atrclient/client.py
index 463bd49..931e353 100755
--- a/src/atrclient/client.py
+++ b/src/atrclient/client.py
@@ -84,7 +84,7 @@ def app_checks_exceptions(
 ) -> None:
     jwt_value = config_jwt_usable()
     host, verify_ssl = config_host_get()
-    url = f"https://{host}/api/checks/{project}/{version}/{revision}";
+    url = f"https://{host}/api/checks/list/{project}/{version}/{revision}";
     results = asyncio.run(web_get(url, jwt_value, verify_ssl))
     if not is_json_list_of_dict(results):
         show_error_and_exit(f"Unexpected API response: {results}")
@@ -101,7 +101,7 @@ def app_checks_failures(
 ) -> None:
     jwt_value = config_jwt_usable()
     host, verify_ssl = config_host_get()
-    url = f"https://{host}/api/checks/{project}/{version}/{revision}";
+    url = f"https://{host}/api/checks/list/{project}/{version}/{revision}";
     results = asyncio.run(web_get(url, jwt_value, verify_ssl))
     if not is_json_list_of_dict(results):
         show_error_and_exit(f"Unexpected API response: {results}")
@@ -142,7 +142,7 @@ def app_checks_status(
         print("Checks are only performed during the draft phase.")
         return
 
-    url = f"https://{host}/api/checks/{project}/{version}/{revision}";
+    url = f"https://{host}/api/checks/list/{project}/{version}/{revision}";
     results = asyncio.run(web_get(url, jwt_value, verify_ssl))
 
     if not is_json_list_of_dict(results):
@@ -150,6 +150,32 @@ def app_checks_status(
     checks_display(results, verbose)
 
 
+@APP_CHECKS.command(name="wait", help="Wait for checks to be completed.")
+def app_checks_wait(
+    project: str,
+    version: str,
+    /,
+    revision: str | None = None,
+    timeout: Annotated[int, cyclopts.Parameter(alias="-t", name="--timeout")] 
= 60,
+) -> None:
+    jwt_value = config_jwt_usable()
+    host, verify_ssl = config_host_get()
+    while True:
+        url = 
f"https://{host}/api/checks/ongoing/{project}/{version}/{revision}";
+        count = asyncio.run(web_get(url, jwt_value, verify_ssl))
+        try:
+            count = models.api.ResultCount.model_validate(count)
+        except pydantic.ValidationError as e:
+            show_error_and_exit(f"Unexpected API response: {count}\n{e}")
+        if count.count == 0:
+            break
+        time.sleep(0.5)
+        timeout -= 1
+        if timeout <= 0:
+            show_error_and_exit("Timeout waiting for checks to complete.")
+    print("Checks completed.")
+
+
 @APP_CHECKS.command(name="warnings", help="Get check warnings for a release 
revision.")
 def app_checks_warnings(
     project: str,
@@ -160,7 +186,7 @@ def app_checks_warnings(
 ) -> None:
     jwt_value = config_jwt_usable()
     host, verify_ssl = config_host_get()
-    url = f"https://{host}/api/checks/{project}/{version}/{revision}";
+    url = f"https://{host}/api/checks/list/{project}/{version}/{revision}";
     results = asyncio.run(web_get(url, jwt_value, verify_ssl))
     if not is_json_list_of_dict(results):
         show_error_and_exit(f"Unexpected API response: {results}")
@@ -924,7 +950,7 @@ async def web_get(url: str, jwt_token: str, verify_ssl: 
bool = True) -> JSON:
                 text = await resp.text()
                 try:
                     error_data = json.loads(text)
-                    if isinstance(error_data, dict) and "error" in error_data:
+                    if isinstance(error_data, dict) and ("error" in 
error_data):
                         show_error_and_exit(error_data["error"])
                     else:
                         show_error_and_exit(f"Request failed: {resp.status} 
{text}")
diff --git a/src/atrclient/models/api.py b/src/atrclient/models/api.py
index 66be28c..f88f552 100644
--- a/src/atrclient/models/api.py
+++ b/src/atrclient/models/api.py
@@ -60,6 +60,10 @@ class ReleaseCreateRequest(schema.Strict):
     version: str
 
 
+class ResultCount(schema.Strict):
+    count: int
+
+
 class VoteStartRequest(schema.Strict):
     project_name: str
     version: str
diff --git a/src/atrclient/models/sql.py b/src/atrclient/models/sql.py
index 03fb6ad..e7caab7 100644
--- a/src/atrclient/models/sql.py
+++ b/src/atrclient/models/sql.py
@@ -24,7 +24,7 @@
 
 import datetime
 import enum
-from typing import Any, Optional
+from typing import Any, Final, Optional
 
 import pydantic
 import sqlalchemy
@@ -834,8 +834,7 @@ def validate_instrumented_attribute(obj: Any) -> 
orm.InstrumentedAttribute:
     return obj
 
 
-# https://github.com/fastapi/sqlmodel/issues/240#issuecomment-2074161775
-Release._latest_revision_number = orm.column_property(
+RELEASE_LATEST_REVISION_NUMBER: Final = orm.column_property(
     sqlalchemy.select(validate_instrumented_attribute(Revision.number))
     .where(validate_instrumented_attribute(Revision.release_name) == 
Release.name)
     .order_by(validate_instrumented_attribute(Revision.seq).desc())
@@ -843,3 +842,6 @@ Release._latest_revision_number = orm.column_property(
     .correlate_except(Revision)
     .scalar_subquery(),
 )
+
+# https://github.com/fastapi/sqlmodel/issues/240#issuecomment-2074161775
+Release._latest_revision_number = RELEASE_LATEST_REVISION_NUMBER
diff --git a/tests/cli_workflow.t b/tests/cli_workflow.t
index 1aa379c..398634d 100644
--- a/tests/cli_workflow.t
+++ b/tests/cli_workflow.t
@@ -26,5 +26,8 @@ $ atr config path
 $ atr upload tooling-test-example 0.3+cli atr-client.conf <!config_rel_path!>
 <.skip.>created<.skip.>
 
+$ atr checks wait tooling-test-example 0.3+cli
+Checks completed.
+
 * atr draft delete tooling-test-example 0.3+cli
 <.etc.>
diff --git a/tests/test_all.py b/tests/test_all.py
index 51d59b3..c5d2f9c 100755
--- a/tests/test_all.py
+++ b/tests/test_all.py
@@ -82,7 +82,7 @@ def test_app_checks_status_verbose(capsys: 
pytest.CaptureFixture[str], fixture_c
     client.app_set("tokens.jwt", "dummy_jwt_token")
 
     release_url = "https://example.invalid/api/releases/test-project";
-    checks_url = "https://example.invalid/api/checks/test-project/2.3.1/00003";
+    checks_url = 
"https://example.invalid/api/checks/list/test-project/2.3.1/00003";
 
     release_payload = {
         "data": [
diff --git a/uv.lock b/uv.lock
index 851f3d2..a5aa3bd 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2,7 +2,7 @@ version = 1
 requires-python = ">=3.13"
 
 [options]
-exclude-newer = "2025-07-11T19:54:00Z"
+exclude-newer = "2025-07-14T14:13:00Z"
 
 [[package]]
 name = "aiohappyeyeballs"
@@ -83,7 +83,7 @@ wheels = [
 
 [[package]]
 name = "apache-trusted-releases"
-version = "0.20250711.1954"
+version = "0.20250714.1413"
 source = { editable = "." }
 dependencies = [
     { name = "aiohttp" },


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

Reply via email to