This commit is contained in:
Jon Peterson 2025-10-25 11:54:26 +02:00 committed by GitHub
commit cd5c8fa09c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 111 additions and 18 deletions

View file

@ -0,0 +1,83 @@
import {
DEFAULT_OPTIONS,
getByteLength,
getReport,
MAX_ACTIONS_SUMMARY_LENGTH,
trimReport
} from '../../src/report/get-report'
import {TestCaseResult, TestGroupResult, TestRunResult, TestSuiteResult} from '../../src/test-results'
// space reserved for closing backticks and newlines
const ALWAYS_RESERVED_SPACE = 5
describe('trimReport', () => {
const TEST_LINE_CHAR = '----'
const TEST_LINE_LEN = getByteLength(`${TEST_LINE_CHAR}\n`)
const MAX_LEN_REPORT: string[] = []
for (let i = 0; i < MAX_ACTIONS_SUMMARY_LENGTH / 5; i++) {
MAX_LEN_REPORT.push(TEST_LINE_CHAR)
}
it('trims reports that exceed Github limits', () => {
const trimmed = trimReport(MAX_LEN_REPORT, 0, DEFAULT_OPTIONS)
const trimmedLength = getByteLength(trimmed)
expect(trimmed.endsWith('has been trimmed**')).toBe(true) // assert was trimmed
expectToBeWithinRangeOfCeiling(trimmedLength, MAX_ACTIONS_SUMMARY_LENGTH - ALWAYS_RESERVED_SPACE, TEST_LINE_LEN)
})
it('reserves space for prepended string', () => {
const prependStringLen = 10
const trimmed = trimReport(MAX_LEN_REPORT, prependStringLen, DEFAULT_OPTIONS)
const trimmedLength = getByteLength(trimmed)
expect(trimmed.endsWith('has been trimmed**')).toBe(true) // assert was trimmed
expectToBeWithinRangeOfCeiling(
trimmedLength,
MAX_ACTIONS_SUMMARY_LENGTH - ALWAYS_RESERVED_SPACE - prependStringLen,
TEST_LINE_LEN
)
})
})
describe('getReport', () => {
const testCases: TestCaseResult[] = []
const testCaseString = '-------------------------' // 25 chars long
const FAILURE_ROW_LEN = getByteLength(`${testCaseString}\n`)
for (let i = 0; i < MAX_ACTIONS_SUMMARY_LENGTH / 30; i++) {
testCases.push(new TestCaseResult(testCaseString, 'failed', 1))
}
const MAX_LEN_RESULT = [
new TestRunResult('run', [new TestSuiteResult('suite', [new TestGroupResult('group', testCases)])])
]
it('trims reports that exceed Github limits', () => {
const trimmed = getReport(MAX_LEN_RESULT, DEFAULT_OPTIONS)
const trimmedLength = getByteLength(trimmed)
expect(trimmed.endsWith('has been trimmed**')).toBe(true) // assert was trimmed
expectToBeWithinRangeOfCeiling(trimmedLength, MAX_ACTIONS_SUMMARY_LENGTH - ALWAYS_RESERVED_SPACE, FAILURE_ROW_LEN)
})
it('reserves space for prepended string', () => {
const prependString = `1 passed, 1 failed and 1 skipped`
const prependStringLen = getByteLength(prependString)
const trimmed = getReport(MAX_LEN_RESULT, DEFAULT_OPTIONS, prependString)
const trimmedLength = getByteLength(trimmed)
expect(trimmed.endsWith('has been trimmed**')).toBe(true) // assert was trimmed
expectToBeWithinRangeOfCeiling(
trimmedLength,
MAX_ACTIONS_SUMMARY_LENGTH - ALWAYS_RESERVED_SPACE - prependStringLen,
FAILURE_ROW_LEN
)
})
})
/**
* Asserts a subject number is between a ceiling value and a range below it (inclusive)
*/
function expectToBeWithinRangeOfCeiling(subject: number, ceiling: number, range: number): void {
expect(subject).toBeLessThanOrEqual(ceiling)
expect(subject).toBeGreaterThanOrEqual(ceiling - range)
}

View file

@ -175,19 +175,24 @@ class TestReporter {
let baseUrl = ''
if (this.useActionsSummary) {
const summary = getReport(results, {
listSuites,
listTests,
baseUrl,
onlySummary,
useActionsSummary,
badgeTitle,
reportTitle
})
const summaryPrepend = `# ${shortSummary}\n`
const summary = getReport(
results,
{
listSuites,
listTests,
baseUrl,
onlySummary,
useActionsSummary,
badgeTitle,
reportTitle
},
summaryPrepend
)
core.info('Summary content:')
core.info(summary)
core.summary.addRaw(`# ${shortSummary}`)
core.summary.addRaw(summaryPrepend)
await core.summary.addRaw(summary).write()
} else {
core.info(`Creating check run ${name}`)

View file

@ -6,7 +6,7 @@ import {getFirstNonEmptyLine} from '../utils/parse-utils'
import {slug} from '../utils/slugger'
const MAX_REPORT_LENGTH = 65535
const MAX_ACTIONS_SUMMARY_LENGTH = 1048576
export const MAX_ACTIONS_SUMMARY_LENGTH = 1048576
export interface ReportOptions {
listSuites: 'all' | 'failed' | 'none'
@ -28,16 +28,21 @@ export const DEFAULT_OPTIONS: ReportOptions = {
reportTitle: ''
}
export function getReport(results: TestRunResult[], options: ReportOptions = DEFAULT_OPTIONS): string {
export function getReport(
results: TestRunResult[],
options: ReportOptions = DEFAULT_OPTIONS,
prependString?: string
): string {
core.info('Generating check run summary')
applySort(results)
const opts = {...options}
const prependStringLen = getByteLength(prependString || '')
let lines = renderReport(results, opts)
let report = lines.join('\n')
if (getByteLength(report) <= getMaxReportLength(options)) {
if (getByteLength(report) + prependStringLen <= getMaxReportLength(options)) {
return report
}
@ -46,24 +51,24 @@ export function getReport(results: TestRunResult[], options: ReportOptions = DEF
opts.listTests = 'failed'
lines = renderReport(results, opts)
report = lines.join('\n')
if (getByteLength(report) <= getMaxReportLength(options)) {
if (getByteLength(report) + prependStringLen <= getMaxReportLength(options)) {
return report
}
}
core.warning(`Test report summary exceeded limit of ${getMaxReportLength(options)} bytes and will be trimmed`)
return trimReport(lines, options)
return trimReport(lines, prependStringLen, options)
}
function getMaxReportLength(options: ReportOptions = DEFAULT_OPTIONS): number {
return options.useActionsSummary ? MAX_ACTIONS_SUMMARY_LENGTH : MAX_REPORT_LENGTH
}
function trimReport(lines: string[], options: ReportOptions): string {
export function trimReport(lines: string[], prependStringLen: number, options: ReportOptions): string {
const closingBlock = '```'
const errorMsg = `**Report exceeded GitHub limit of ${getMaxReportLength(options)} bytes and has been trimmed**`
const maxErrorMsgLength = closingBlock.length + errorMsg.length + 2
const maxReportLength = getMaxReportLength(options) - maxErrorMsgLength
const maxReportLength = getMaxReportLength(options) - maxErrorMsgLength - prependStringLen
let reportLength = 0
let codeBlock = false
@ -97,7 +102,7 @@ function applySort(results: TestRunResult[]): void {
}
}
function getByteLength(text: string): number {
export function getByteLength(text: string): number {
return Buffer.byteLength(text, 'utf8')
}