diff --git a/.github/workflows/link-check.yml b/.github/workflows/link-check.yml index 71bd8d0..f0671ad 100644 --- a/.github/workflows/link-check.yml +++ b/.github/workflows/link-check.yml @@ -40,10 +40,11 @@ jobs: GH_TOKEN: ${{ github.token }} ISSUE_TITLE: "Link check: dead or moved links found" run: | + python scripts/link_check_issue.py existing=$(gh issue list --state open --json number,title \ --jq "[.[] | select(.title == \"$ISSUE_TITLE\") | .number] | first // empty") if [ -n "$existing" ]; then - gh issue comment "$existing" --body-file link-check-report.md + gh issue comment "$existing" --body-file link-check-issue.md else - gh issue create --title "$ISSUE_TITLE" --body-file link-check-report.md + gh issue create --title "$ISSUE_TITLE" --body-file link-check-issue.md fi diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index c3ca1b3..5dcc2cd 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -11,4 +11,5 @@ jobs: with: python-version: '3.x' - run: python scripts/validate.py + - run: python -m unittest discover -s tests -v - run: python scripts/search.py SQLite --json diff --git a/scripts/link_check_issue.py b/scripts/link_check_issue.py new file mode 100644 index 0000000..9718969 --- /dev/null +++ b/scripts/link_check_issue.py @@ -0,0 +1,25 @@ +"""Prepare a bounded issue preview without modifying the full reports.""" +import os +from pathlib import Path + + +def issue_body(report, run_url): + limit = 60000 + encoded = report.encode("utf-8") + if len(encoded) <= limit: + return report + notice = ( + "\n\nReport preview truncated. Full Markdown and JSON reports: " + f"{run_url}#artifacts\n" + ) + preview = encoded[:limit - len(notice.encode("utf-8"))].decode("utf-8", errors="ignore") + return preview + notice + + +if __name__ == "__main__": + run_url = ( + f"{os.environ['GITHUB_SERVER_URL']}/{os.environ['GITHUB_REPOSITORY']}" + f"/actions/runs/{os.environ['GITHUB_RUN_ID']}" + ) + report = Path("link-check-report.md").read_bytes().decode("utf-8") + Path("link-check-issue.md").write_bytes(issue_body(report, run_url).encode("utf-8")) diff --git a/tests/test_link_check_issue.py b/tests/test_link_check_issue.py new file mode 100644 index 0000000..ad75254 --- /dev/null +++ b/tests/test_link_check_issue.py @@ -0,0 +1,38 @@ +import os +import subprocess +import sys +import tempfile +import unittest +from pathlib import Path + +SCRIPTS = Path(__file__).resolve().parents[1] / "scripts" +sys.path.insert(0, str(SCRIPTS)) +from link_check_issue import issue_body + + +class LinkCheckIssueTests(unittest.TestCase): + def test_short_report_unchanged(self): + report = "# Link report\nAll findings: café 🌍\n" + self.assertEqual(issue_body(report, "https://example.com/run/1"), report) + + def test_large_reports_preserve_sources_and_trailing_notice(self): + for content in ("a" * 200000, "é🌍" * 100000): + with self.subTest(multibyte=content.startswith("é")), tempfile.TemporaryDirectory() as directory: + root = Path(directory) + report = root / "link-check-report.md" + results = root / "link-check-results.json" + report.write_bytes(content.encode("utf-8")) + results.write_bytes(b'{"findings": "unchanged"}\n') + originals = (report.read_bytes(), results.read_bytes()) + subprocess.run( + [sys.executable, str(SCRIPTS / "link_check_issue.py")], + cwd=root, check=True, + env={**os.environ, "GITHUB_SERVER_URL": "https://github.com", + "GITHUB_REPOSITORY": "owner/repo", "GITHUB_RUN_ID": "123"}, + ) + body = (root / "link-check-issue.md").read_bytes() + self.assertLessEqual(len(body), 60000) + preview, notice = body.decode("utf-8").split("\n\nReport preview truncated.") + self.assertTrue(content.startswith(preview)) + self.assertEqual(notice, " Full Markdown and JSON reports: https://github.com/owner/repo/actions/runs/123#artifacts\n") + self.assertEqual((report.read_bytes(), results.read_bytes()), originals)