diff --git a/README.md b/README.md index 653dd6d..417a9d0 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,9 @@ jobs: # jest-junit reporter: '' - # Enables code annotations with error message and stack trace captured during test execution - annotations: 'true' + # Limits number of created annotations with error message and stack trace captured during test execution. + # Must be less or equal to 50. + max-annotations: '10' # Set action as failed if test report contain any failed test fail-on-error: 'true' diff --git a/action.yml b/action.yml index 7c79941..9154c15 100644 --- a/action.yml +++ b/action.yml @@ -4,14 +4,16 @@ description: | Supports .NET (xUnit, NUnit, MSTest), Dart, Flutter and JavaScript (JEST). author: Michal Dorner inputs: - annotations: - description: Enables code annotations with error message and stack trace captured during test execution - required: true - default: 'true' fail-on-error: description: Set this action as failed if test report contain any failed test required: true default: 'true' + max-annotations: + description: | + Limits number of created annotations with error message and stack trace captured during test execution. + Must be less or equal to 50. + required: true + default: '10' name: description: Name of the check run required: true @@ -19,7 +21,7 @@ inputs: description: | Coma separated list of paths to test reports Supports wildcards via [fast-glob](https://github.com/mrmlnc/fast-glob) - All matched files must be of same format + All matched result files must be of same format required: true reporter: description: | diff --git a/src/main.ts b/src/main.ts index 16ae666..6cb304a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,7 +8,7 @@ import {parseJestJunit} from './parsers/jest-junit/jest-junit-parser' import {FileContent, ParseOptions, ParseTestResult} from './parsers/parser-types' import {normalizeDirPath} from './utils/file-utils' import {listFiles} from './utils/git' -import {getCheckRunSha} from './utils/github-utils' +import {enforceCheckRunLimits, getCheckRunSha} from './utils/github-utils' async function run(): Promise { try { @@ -19,7 +19,7 @@ async function run(): Promise { } async function main(): Promise { - const annotations = core.getInput('annotations', {required: true}) === 'true' + const maxAnnotations = parseInt(core.getInput('max-annotations', {required: true})) const failOnError = core.getInput('fail-on-error', {required: true}) === 'true' const name = core.getInput('name', {required: true}) const path = core.getInput('path', {required: true}) @@ -27,6 +27,11 @@ async function main(): Promise { const token = core.getInput('token', {required: true}) const workDirInput = core.getInput('working-directory', {required: false}) + if (isNaN(maxAnnotations) || maxAnnotations < 0 || maxAnnotations > 50) { + core.setFailed(`Input parameter 'max-annotations' has invalid value`) + return + } + if (workDirInput) { core.info(`Changing directory to ${workDirInput}`) process.chdir(workDirInput) @@ -37,13 +42,14 @@ async function main(): Promise { const sha = getCheckRunSha() // We won't need tracked files if we are not going to create annotations + const annotations = maxAnnotations > 0 const trackedFiles = annotations ? await listFiles() : [] const opts: ParseOptions = { name, - annotations, trackedFiles, - workDir + workDir, + annotations } const parser = getParser(reporter) @@ -58,6 +64,8 @@ async function main(): Promise { const result = await parser(files, opts) const conclusion = result.success ? 'success' : 'failure' + enforceCheckRunLimits(result, maxAnnotations) + core.info(`Creating check run '${name}' with conclusion '${conclusion}'`) await octokit.checks.create({ head_sha: sha, diff --git a/src/utils/github-utils.ts b/src/utils/github-utils.ts index 381d596..a691492 100644 --- a/src/utils/github-utils.ts +++ b/src/utils/github-utils.ts @@ -1,6 +1,9 @@ import * as github from '@actions/github' import {EventPayloads} from '@octokit/webhooks' +import {TestResult} from '../parsers/parser-types' +import {ellipsis} from './markdown-utils' + export function getCheckRunSha(): string { if (github.context.payload.pull_request) { const pr = github.context.payload.pull_request as EventPayloads.WebhookPayloadPullRequestPullRequest @@ -9,3 +12,19 @@ export function getCheckRunSha(): string { return github.context.sha } + +export function enforceCheckRunLimits(result: TestResult, maxAnnotations: number): void { + const output = result.output + if (!output) { + return + } + + // Limit number of created annotations + output.annotations?.splice(maxAnnotations + 1) + + // Limit number of characters in annotation fields + for (const err of output.annotations ?? []) { + err.title = ellipsis(err.title || '', 255) + err.message = ellipsis(err.message, 65535) + } +} diff --git a/src/utils/markdown-utils.ts b/src/utils/markdown-utils.ts index f5110d2..d31f106 100644 --- a/src/utils/markdown-utils.ts +++ b/src/utils/markdown-utils.ts @@ -34,3 +34,11 @@ export function tableEscape(content: ToString): string { export function fixEol(text?: string): string { return text?.replace(/\r/g, '') ?? '' } + +export function ellipsis(text: string, maxLength: number): string { + if (text.length <= maxLength) { + return text + } + + return text.substr(0, maxLength - 3) + '...' +}