fix(build): flush guest build output + put tail in failure message
On a non-zero build the guest stdout/stderr was written unflushed then a ClickException raised, so the cause was lost (only "build command failed (exit 1)" surfaced). _report_build_output now emits the output with markers, flushes both streams, and returns the last lines which are appended to the failure message — diagnosable even if act_runner buffering drops the body. Applied to Linux + Windows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,25 @@ def _sh_quote(value: str) -> str:
|
||||
return shlex.quote(value)
|
||||
|
||||
|
||||
def _report_build_output(stdout: str, stderr: str) -> str:
|
||||
"""Emit guest build stdout/stderr to the CI log, flushed.
|
||||
|
||||
Returns the last few lines for the failure message so the cause is
|
||||
visible even if stream buffering hides the body on a non-zero exit.
|
||||
"""
|
||||
click.echo("[build run] ----- build output -----")
|
||||
if stdout:
|
||||
sys.stdout.write(stdout if stdout.endswith("\n") else stdout + "\n")
|
||||
sys.stdout.flush()
|
||||
if stderr:
|
||||
sys.stderr.write(stderr if stderr.endswith("\n") else stderr + "\n")
|
||||
sys.stderr.flush()
|
||||
click.echo("[build run] ----- end build output -----")
|
||||
combined = (stderr or "").strip() or (stdout or "").strip()
|
||||
lines = combined.splitlines()
|
||||
return " | ".join(lines[-5:]) if lines else "(no build output)"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- Linux flow
|
||||
|
||||
|
||||
@@ -173,14 +192,10 @@ def _linux_build(
|
||||
full_cmd = f"{env_prefix}cd {_sh_quote(workdir)} && {cmd}"
|
||||
click.echo(f"[build run] running build (env vars redacted): cd {workdir} && {cmd}")
|
||||
result = t.run(full_cmd, check=False)
|
||||
# Stream guest stdout/stderr after the fact (paramiko buffers the channel).
|
||||
if result.stdout:
|
||||
sys.stdout.write(result.stdout)
|
||||
if result.stderr:
|
||||
sys.stderr.write(result.stderr)
|
||||
tail = _report_build_output(result.stdout, result.stderr)
|
||||
if result.returncode != 0:
|
||||
raise click.ClickException(
|
||||
f"build command failed (exit {result.returncode})"
|
||||
f"build command failed (exit {result.returncode}): {tail}"
|
||||
)
|
||||
|
||||
if skip_artifact:
|
||||
@@ -333,13 +348,10 @@ def _windows_build(
|
||||
"if ($null -eq $LASTEXITCODE) { exit 0 } else { exit $LASTEXITCODE }"
|
||||
)
|
||||
result = t.run(full_ps, check=False)
|
||||
if result.stdout:
|
||||
sys.stdout.write(result.stdout)
|
||||
if result.stderr:
|
||||
sys.stderr.write(result.stderr)
|
||||
tail = _report_build_output(result.stdout, result.stderr)
|
||||
if result.returncode != 0:
|
||||
raise click.ClickException(
|
||||
f"build command failed (exit {result.returncode})"
|
||||
f"build command failed (exit {result.returncode}): {tail}"
|
||||
)
|
||||
|
||||
if skip_artifact:
|
||||
|
||||
Reference in New Issue
Block a user