Skip to content

Commit bdfc2cf

Browse files
fix(ci): print lychee failure URLs in the job log
When LYCHEE_REPORT_DIR forces --format json, the console only showed the short permanent/transient summary. Echo the final failure table (source, URL, status) so broken links are visible without opening the report artifact. Fixes #3204.
1 parent 590a8bf commit bdfc2cf

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

‎ci/tools/retry_lychee.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,17 @@ def attempt_report(report: Path, attempt: int) -> Path:
135135

136136
def finish(report: Path, data: Report, exit_codes: list[int], message: str, *, warning: bool = False) -> None:
137137
"""Publish the final result without presenting recovered failures as current."""
138+
details = render_report(data)
138139
summary = f"## Documentation links\n\n{message}\n\n| Attempt | Exit code |\n| --- | --- |\n"
139140
summary += "".join(f"| {attempt} | {code} |\n" for attempt, code in enumerate(exit_codes, start=1))
140-
summary += f"\n### Final attempt\n\n{render_report(data)}\n"
141+
summary += f"\n### Final attempt\n\n{details}\n"
141142
report.with_suffix(".md").write_text(summary, encoding="utf-8")
143+
# CI console logs previously showed only the short message when LYCHEE_REPORT_DIR
144+
# forced --format json. Echo the final failure table so broken URLs are visible
145+
# without opening the uploaded report artifact (Fixes #3204).
142146
print(f"::warning::{message}" if warning else message, flush=True)
147+
if data.failures:
148+
print(details, flush=True)
143149
if summary_path := os.environ.get("GITHUB_STEP_SUMMARY"):
144150
with Path(summary_path).open("a", encoding="utf-8") as stream:
145151
stream.write(summary)

‎ci/tools/tests/test_retry_lychee.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,17 @@ def test_http_timeout_map_entries_are_retryable(tmp_path, code):
133133
],
134134
)
135135
@pytest.mark.agent_authored(model="gpt-6")
136-
def test_permanent_or_unknown_failures_stop_without_sleep_or_retry(tmp_path, monkeypatch, failure):
136+
def test_permanent_or_unknown_failures_stop_without_sleep_or_retry(tmp_path, monkeypatch, capsys, failure):
137137
report = tmp_path / "lychee.json"
138138
write_report(report, report_data(errors=[failure]))
139139
monkeypatch.setattr(retry_lychee.time, "sleep", lambda _delay: pytest.fail("Unexpected sleep"))
140140

141141
assert retry_lychee.retry_lychee(2, report, run_attempt=unexpected_retry) == 2
142142
assert "permanent or unclassified" in report.with_suffix(".md").read_text(encoding="utf-8")
143+
out = capsys.readouterr().out
144+
assert "permanent or unclassified" in out
145+
assert "| Source | URL | Status |" in out
146+
assert retry_lychee.escape_markdown(failure["url"]) in out
143147

144148

145149
@pytest.mark.agent_authored(model="gpt-6")

0 commit comments

Comments
 (0)