From f610967bd1ed134f3eeeb601764bacf26a6bcb1d Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 25 Apr 2026 12:10:34 +0200 Subject: [PATCH 1/4] Add generated summary action output --- README.md | 1 + action.yml | 2 ++ dist/index.js | 2 ++ src/main.ts | 2 ++ 4 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 81d04a5..a7e4674 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ jobs: | time | Test execution time [ms] | | url | Check run URL | | url_html | Check run URL HTML | +| summary | Generated test report summary in Markdown format | | slug_prefix| Random anchor links slug prefix generated for the summary headers | ## Supported formats diff --git a/action.yml b/action.yml index 577b0c3..ef1aeff 100644 --- a/action.yml +++ b/action.yml @@ -130,6 +130,8 @@ outputs: description: Check run URL url_html: description: Check run URL HTML + summary: + description: Generated test report summary in Markdown format slug_prefix: description: Random prefix added to generated report anchor slugs for this action run runs: diff --git a/dist/index.js b/dist/index.js index 2847890..b4a075b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -59089,6 +59089,7 @@ class TestReporter { }, shortSummary); info('Summary content:'); info(summary); + setOutput('summary', summary); await summary_summary.addRaw(summary).write(); } else { @@ -59119,6 +59120,7 @@ class TestReporter { }); info('Creating annotations'); const annotations = getAnnotations(results, this.maxAnnotations); + setOutput('summary', summary); const isFailed = this.failOnError && results.some(tr => tr.result === 'failed'); const conclusion = isFailed ? 'failure' : 'success'; info(`Updating check run conclusion (${conclusion}) and output`); diff --git a/src/main.ts b/src/main.ts index eb1b3a5..f6cfcc0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -221,6 +221,7 @@ class TestReporter { core.info('Summary content:') core.info(summary) + core.setOutput('summary', summary) await core.summary.addRaw(summary).write() } else { core.info(`Creating check run ${name}`) @@ -252,6 +253,7 @@ class TestReporter { core.info('Creating annotations') const annotations = getAnnotations(results, this.maxAnnotations) + core.setOutput('summary', summary) const isFailed = this.failOnError && results.some(tr => tr.result === 'failed') const conclusion = isFailed ? 'failure' : 'success' From 49ad12d837ddc68517d419b7faa3a666345cd134 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 25 Apr 2026 13:57:07 +0200 Subject: [PATCH 2/4] Add changelog for `summary` output --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b107e0..815a17f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 3.1.0 * Feature: Add `list-files` input to control test report file listing https://github.com/dorny/test-reporter/pull/773 +* Feature: Add `summary` output with the generated summary in Markdown format https://github.com/dorny/test-reporter/pull/772 ## 3.0.0 * Feature: Use NodeJS 24 LTS as default runtime https://github.com/dorny/test-reporter/pull/738 From bd45c7a5596c6d34c60c5ca27233c05e2de7e6e1 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 25 Apr 2026 14:20:21 +0200 Subject: [PATCH 3/4] Refactor summary output to use a temporary file --- CHANGELOG.md | 2 +- README.md | 2 +- action.yml | 4 ++-- src/main.ts | 15 +++++++++++++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 815a17f..7835fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 3.1.0 * Feature: Add `list-files` input to control test report file listing https://github.com/dorny/test-reporter/pull/773 -* Feature: Add `summary` output with the generated summary in Markdown format https://github.com/dorny/test-reporter/pull/772 +* Feature: Add `summary_file` output with the path to the generated summary in Markdown format https://github.com/dorny/test-reporter/pull/772 ## 3.0.0 * Feature: Use NodeJS 24 LTS as default runtime https://github.com/dorny/test-reporter/pull/738 diff --git a/README.md b/README.md index a7e4674..f6624d8 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ jobs: | time | Test execution time [ms] | | url | Check run URL | | url_html | Check run URL HTML | -| summary | Generated test report summary in Markdown format | +| summary_file | Path to a file containing the generated test report summary in Markdown format | | slug_prefix| Random anchor links slug prefix generated for the summary headers | ## Supported formats diff --git a/action.yml b/action.yml index ef1aeff..fb11227 100644 --- a/action.yml +++ b/action.yml @@ -130,8 +130,8 @@ outputs: description: Check run URL url_html: description: Check run URL HTML - summary: - description: Generated test report summary in Markdown format + summary_file: + description: Path to a file containing the generated test report summary in Markdown format slug_prefix: description: Random prefix added to generated report anchor slugs for this action run runs: diff --git a/src/main.ts b/src/main.ts index f6cfcc0..62da4bc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,9 @@ import * as core from '@actions/core' import * as github from '@actions/github' import {GitHub} from '@actions/github/lib/utils' import {randomBytes} from 'node:crypto' +import {writeFileSync} from 'node:fs' +import {tmpdir} from 'node:os' +import {join} from 'node:path' import {ArtifactProvider} from './input-providers/artifact-provider.js' import {LocalFileProvider} from './input-providers/local-file-provider.js' @@ -221,7 +224,7 @@ class TestReporter { core.info('Summary content:') core.info(summary) - core.setOutput('summary', summary) + this.writeSummaryFile(summary) await core.summary.addRaw(summary).write() } else { core.info(`Creating check run ${name}`) @@ -253,7 +256,7 @@ class TestReporter { core.info('Creating annotations') const annotations = getAnnotations(results, this.maxAnnotations) - core.setOutput('summary', summary) + this.writeSummaryFile(summary) const isFailed = this.failOnError && results.some(tr => tr.result === 'failed') const conclusion = isFailed ? 'failure' : 'success' @@ -280,6 +283,14 @@ class TestReporter { return results } + writeSummaryFile(summary: string): void { + const dir = process.env.RUNNER_TEMP || tmpdir() + const file = join(dir, `test-reporter-summary-${randomBytes(8).toString('hex')}.md`) + writeFileSync(file, summary) + core.info(`Summary written to ${file}`) + core.setOutput('summary_file', file) + } + getParser(reporter: string, options: ParseOptions): TestParser { switch (reporter) { case 'dart-json': From 373689ed6bea431780db3a93fd31f97596b51d85 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 25 Apr 2026 14:20:38 +0200 Subject: [PATCH 4/4] chore: rebuild dist folder --- dist/index.js | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/dist/index.js b/dist/index.js index b4a075b..8f0b42f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -16015,7 +16015,7 @@ module.exports.fetch = async function fetch (init, options = undefined) { } module.exports.Headers = __nccwpck_require__(660).Headers module.exports.Response = __nccwpck_require__(9051).Response -module.exports.Request = __nccwpck_require__(2348).Request +module.exports.Request = __nccwpck_require__(9967).Request module.exports.FormData = __nccwpck_require__(5910).FormData module.exports.File = globalThis.File ?? (__nccwpck_require__(4573).File) module.exports.FileReader = __nccwpck_require__(8355).FileReader @@ -27430,7 +27430,7 @@ const { urlEquals, getFieldValues } = __nccwpck_require__(6798) const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3440) const { webidl } = __nccwpck_require__(5893) const { Response, cloneResponse, fromInnerResponse } = __nccwpck_require__(9051) -const { Request, fromInnerRequest } = __nccwpck_require__(2348) +const { Request, fromInnerRequest } = __nccwpck_require__(9967) const { kState } = __nccwpck_require__(3627) const { fetching } = __nccwpck_require__(4398) const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = __nccwpck_require__(3168) @@ -29744,7 +29744,7 @@ module.exports = { const { pipeline } = __nccwpck_require__(7075) const { fetching } = __nccwpck_require__(4398) -const { makeRequest } = __nccwpck_require__(2348) +const { makeRequest } = __nccwpck_require__(9967) const { webidl } = __nccwpck_require__(5893) const { EventSourceStream } = __nccwpck_require__(4031) const { parseMIMEType } = __nccwpck_require__(1900) @@ -33368,7 +33368,7 @@ const { fromInnerResponse } = __nccwpck_require__(9051) const { HeadersList } = __nccwpck_require__(660) -const { Request, cloneRequest } = __nccwpck_require__(2348) +const { Request, cloneRequest } = __nccwpck_require__(9967) const zlib = __nccwpck_require__(8522) const { bytesMatch, @@ -35632,7 +35632,7 @@ module.exports = { /***/ }), -/***/ 2348: +/***/ 9967: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { /* globals AbortController */ @@ -40814,7 +40814,7 @@ const { const { fireEvent, failWebsocketConnection, isClosing, isClosed, isEstablished, parseExtensions } = __nccwpck_require__(8625) const { channels } = __nccwpck_require__(2414) const { CloseEvent } = __nccwpck_require__(5188) -const { makeRequest } = __nccwpck_require__(2348) +const { makeRequest } = __nccwpck_require__(9967) const { fetching } = __nccwpck_require__(4398) const { Headers, getHeadersList } = __nccwpck_require__(660) const { getDecodeSplit } = __nccwpck_require__(3168) @@ -56445,6 +56445,12 @@ function getOctokit(token, options, ...additionalPlugins) { //# sourceMappingURL=github.js.map // EXTERNAL MODULE: external "node:crypto" var external_node_crypto_ = __nccwpck_require__(7598); +;// CONCATENATED MODULE: external "node:fs" +const external_node_fs_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs"); +;// CONCATENATED MODULE: external "node:os" +const external_node_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:os"); +;// CONCATENATED MODULE: external "node:path" +const external_node_path_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:path"); // EXTERNAL MODULE: ./node_modules/adm-zip/adm-zip.js var adm_zip = __nccwpck_require__(1316); // EXTERNAL MODULE: ./node_modules/picomatch/index.js @@ -58932,6 +58938,9 @@ class NetteTesterJunitParser { + + + @@ -59089,7 +59098,7 @@ class TestReporter { }, shortSummary); info('Summary content:'); info(summary); - setOutput('summary', summary); + this.writeSummaryFile(summary); await summary_summary.addRaw(summary).write(); } else { @@ -59120,7 +59129,7 @@ class TestReporter { }); info('Creating annotations'); const annotations = getAnnotations(results, this.maxAnnotations); - setOutput('summary', summary); + this.writeSummaryFile(summary); const isFailed = this.failOnError && results.some(tr => tr.result === 'failed'); const conclusion = isFailed ? 'failure' : 'success'; info(`Updating check run conclusion (${conclusion}) and output`); @@ -59143,6 +59152,13 @@ class TestReporter { } return results; } + writeSummaryFile(summary) { + const dir = process.env.RUNNER_TEMP || (0,external_node_os_namespaceObject.tmpdir)(); + const file = (0,external_node_path_namespaceObject.join)(dir, `test-reporter-summary-${(0,external_node_crypto_.randomBytes)(8).toString('hex')}.md`); + (0,external_node_fs_namespaceObject.writeFileSync)(file, summary); + info(`Summary written to ${file}`); + setOutput('summary_file', file); + } getParser(reporter, options) { switch (reporter) { case 'dart-json':