diff --git a/scripts/check_deliberate_break.py b/scripts/check_deliberate_break.py index 6c1e1bca1..6d51f9224 100644 --- a/scripts/check_deliberate_break.py +++ b/scripts/check_deliberate_break.py @@ -68,6 +68,13 @@ def _json_result(verdict: str, **fields: object) -> dict[str, object]: return {"verdict": verdict, **fields} +def _subprocess_output_text(value: str | bytes | None) -> str | None: + """Normalize captured subprocess output for JSON result payloads.""" + if isinstance(value, bytes): + return value.decode(errors="replace") + return value + + def _write_github_output(**fields: str) -> None: output_path = os.environ.get("GITHUB_OUTPUT") if not output_path: @@ -823,8 +830,8 @@ def verify_spec( reason="archive-command-failed", command=list(exc.cmd) if isinstance(exc.cmd, (tuple, list)) else str(exc.cmd), returncode=exc.returncode, - stdout=exc.stdout, - stderr=exc.stderr, + stdout=_subprocess_output_text(exc.stdout), + stderr=_subprocess_output_text(exc.stderr), ) except OSError as exc: return _json_result( diff --git a/templates/consumer-repo/scripts/check_deliberate_break.py b/templates/consumer-repo/scripts/check_deliberate_break.py index 6c1e1bca1..6d51f9224 100644 --- a/templates/consumer-repo/scripts/check_deliberate_break.py +++ b/templates/consumer-repo/scripts/check_deliberate_break.py @@ -68,6 +68,13 @@ def _json_result(verdict: str, **fields: object) -> dict[str, object]: return {"verdict": verdict, **fields} +def _subprocess_output_text(value: str | bytes | None) -> str | None: + """Normalize captured subprocess output for JSON result payloads.""" + if isinstance(value, bytes): + return value.decode(errors="replace") + return value + + def _write_github_output(**fields: str) -> None: output_path = os.environ.get("GITHUB_OUTPUT") if not output_path: @@ -823,8 +830,8 @@ def verify_spec( reason="archive-command-failed", command=list(exc.cmd) if isinstance(exc.cmd, (tuple, list)) else str(exc.cmd), returncode=exc.returncode, - stdout=exc.stdout, - stderr=exc.stderr, + stdout=_subprocess_output_text(exc.stdout), + stderr=_subprocess_output_text(exc.stderr), ) except OSError as exc: return _json_result( diff --git a/tests/scripts/test_check_deliberate_break.py b/tests/scripts/test_check_deliberate_break.py index 13fb35e92..829c92632 100644 --- a/tests/scripts/test_check_deliberate_break.py +++ b/tests/scripts/test_check_deliberate_break.py @@ -1,3 +1,4 @@ +import json import os import subprocess import sys @@ -1286,8 +1287,8 @@ def test_base_archive_command_failure_is_not_dependency_failure(tmp_path, monkey error = subprocess.CalledProcessError( 17, ["git", "archive", base], - output="archive output", - stderr="bad ref", + output=b"archive output", + stderr=b"bad ref", ) monkeypatch.setattr( deliberate_break, @@ -1305,6 +1306,7 @@ def test_base_archive_command_failure_is_not_dependency_failure(tmp_path, monkey "stdout": "archive output", "stderr": "bad ref", } + json.dumps(result) def test_base_setup_failure_is_not_dependency_failure(tmp_path, monkeypatch) -> None: