feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(reports): --report-md and an automatic GitHub step summary - #1043

Merged
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md
Aug 10, 2026
Merged

feat(reports): --report-md and an automatic GitHub step summary#1043
Chemaclass merged 3 commits into
mainfrom
feat/1015-report-md

Conversation

@Chemaclass

@ChemaclassChemaclass commented Aug 10, 2026

Copy link
Copy Markdown
Member

🤔 Background

Related #1015

Every existing report format targets a machine, and the HTML one has to be uploaded as an artifact and downloaded to be read. Nothing targeted the page a developer looks at first: the pull request.

💡 Changes

  • --report-md <file> writes a Markdown summary: verdict, counts table, and each failure with its file:line and message. Coverage and slowest-tests sections appear only when that data exists.
  • Inside GitHub Actions there is nothing to configure: with GITHUB_STEP_SUMMARY set and no explicit path, the summary is appended to it and renders on the job page. Appended, never written, since that file belongs to the whole job.
  • Failure messages are fenced and ANSI-stripped; test names are escaped so |, *, _ or a backtick cannot break the table.
  • Only the outermost run writes the step summary, matching the annotations: the variable is inherited by every child, so a nested run would otherwise append its fixtures' results to the parent's job page.

🩹 Follow-up fix in this branch

The coverage percentage in the summary was read before the hit records were finalized, and before a --parallel run's per-worker data was aggregated, so it reported 0% for a covered run under --parallel and a lower-than-console figure sequentially. The coverage numbers are now computed before the summary is written; the console and file reports still render where they did. Covered by test_the_coverage_percentage_matches_the_console_report.

✅ Build & Verify

The earlier block on this PR is gone: the standalone size budget was raised to 544 KiB on main in #1046. The artifact built from this branch is 523306 bytes, inside the budget.

@ChemaclassChemaclass added the enhancement New feature or request label Aug 10, 2026
@ChemaclassChemaclass self-assigned this Aug 10, 2026
Every existing report format targets a machine, and the HTML one has to
be uploaded and downloaded to be read. Nothing targeted the page a
developer actually looks at first.
The summary carries the verdict, a counts table and each failure with its
file:line and message. Coverage and slowest-tests sections appear only
when that data exists. Failure messages go inside a fence with ANSI
stripped so they render verbatim, and test names are escaped so a name
containing a pipe, asterisk, underscore or backtick cannot break the
table.
With GITHUB_STEP_SUMMARY set and no explicit path, the summary is
appended there. Appended, never written: that file belongs to the whole
job, so truncating it would discard the other steps' output. Only the
outermost run writes it, for the same reason the annotations do -- the
variable is inherited by every child, so a nested run would append its
own fixtures' results to the parent's job page.
Generation moved ahead of print_profile_and_reset, which deletes the
profile records the summary reads, and load_spooled moved with it so a
--parallel run still reports the rows its workers spooled (#1004).
Closes#1015
GITHUB_STEP_SUMMARY is set on every GitHub Actions runner, which makes
the Markdown summary a third reason to collect rows. These tests ask
whether a file report was configured, so the ambient CI environment has
to be pinned off for the answer to mean anything.
…nsole nor parallel
The summary read the coverage percentage before the hit records were
finalized, and before a parallel run's per-worker data was aggregated, so
it reported 0% for a covered run under --parallel and a low figure
sequentially. Compute the coverage numbers before the summary is written;
the reports still render where they did.
@Chemaclass
Chemaclass merged commit eab6b9a into mainAug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1015-report-md branch August 10, 2026 20:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Chemaclass