C0: suggest mise run runner-logs in container-build-and-release
After dispatching, poll the Forgejo API for the run matching our head_sha and print `mise run runner-logs <N>` so the suggested monitor command is one copy-paste away. Falls back to the bare command if the poll times out. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0ceafc374d
commit
e6a6a6042e
2 changed files with 60 additions and 2 deletions
|
|
@ -0,0 +1 @@
|
|||
`container-build-and-release` now prints the specific `mise run runner-logs <N>` command after dispatching, polling the Forgejo API to resolve the run number for the commit it just triggered.
|
||||
|
|
@ -15,6 +15,7 @@ Dockerfile and Nix builds in a single workflow.
|
|||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
|
|
@ -48,6 +49,52 @@ def get_forge_token() -> str:
|
|||
return result.stdout.strip()
|
||||
|
||||
|
||||
def max_run_number(headers: dict[str, str]) -> int:
|
||||
"""Return the highest current run_number for WORKFLOW, or 0 if none."""
|
||||
resp = httpx.get(
|
||||
f"{FORGE_API}/repos/{REPO}/actions/tasks",
|
||||
params={"limit": 50},
|
||||
headers=headers,
|
||||
timeout=15,
|
||||
)
|
||||
if resp.status_code != 200:
|
||||
return 0
|
||||
runs = [
|
||||
t["run_number"]
|
||||
for t in resp.json().get("workflow_runs", [])
|
||||
if t.get("workflow_id") == WORKFLOW
|
||||
]
|
||||
return max(runs, default=0)
|
||||
|
||||
|
||||
def find_dispatched_run(
|
||||
ref: str, floor: int, headers: dict[str, str], timeout_s: int = 20
|
||||
) -> int | None:
|
||||
"""Poll the tasks endpoint for the run triggered by our dispatch.
|
||||
|
||||
Matches by head_sha + workflow + run_number > floor so we don't pick up
|
||||
an older build of the same commit or a concurrent unrelated dispatch.
|
||||
"""
|
||||
deadline = time.monotonic() + timeout_s
|
||||
while time.monotonic() < deadline:
|
||||
resp = httpx.get(
|
||||
f"{FORGE_API}/repos/{REPO}/actions/tasks",
|
||||
params={"limit": 20},
|
||||
headers=headers,
|
||||
timeout=15,
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
for task in resp.json().get("workflow_runs", []):
|
||||
if (
|
||||
task.get("head_sha") == ref
|
||||
and task.get("workflow_id") == WORKFLOW
|
||||
and task.get("run_number", 0) > floor
|
||||
):
|
||||
return task["run_number"]
|
||||
time.sleep(1)
|
||||
return None
|
||||
|
||||
|
||||
def list_containers() -> None:
|
||||
typer.echo("Available containers:")
|
||||
for d in sorted(Path("containers").iterdir()):
|
||||
|
|
@ -112,7 +159,8 @@ def main(
|
|||
if dry_run:
|
||||
typer.echo(f"[dry-run] Would dispatch {WORKFLOW}")
|
||||
typer.echo()
|
||||
typer.echo(f"Monitor builds at: {FORGE_ACTIONS}")
|
||||
typer.echo("Monitor builds with: mise run runner-logs")
|
||||
typer.echo(f" or visit: {FORGE_ACTIONS}")
|
||||
return
|
||||
|
||||
token = get_forge_token()
|
||||
|
|
@ -132,6 +180,10 @@ def main(
|
|||
typer.echo("Push your changes before triggering a build: git push origin main")
|
||||
raise typer.Exit(1)
|
||||
|
||||
# Snapshot the highest existing run_number so we can identify the one
|
||||
# our dispatch creates.
|
||||
floor = max_run_number(headers)
|
||||
|
||||
url = f"{FORGE_API}/repos/{REPO}/actions/workflows/{WORKFLOW}/dispatches"
|
||||
payload = {
|
||||
"ref": "main",
|
||||
|
|
@ -148,7 +200,12 @@ def main(
|
|||
raise typer.Exit(1)
|
||||
|
||||
typer.echo()
|
||||
typer.echo(f"Monitor builds at: {FORGE_ACTIONS}")
|
||||
run_number = find_dispatched_run(ref, floor, headers)
|
||||
if run_number is not None:
|
||||
typer.echo(f"Monitor builds with: mise run runner-logs {run_number}")
|
||||
else:
|
||||
typer.echo("Monitor builds with: mise run runner-logs")
|
||||
typer.echo(f" or visit: {FORGE_ACTIONS}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue