mirror of
https://github.com/dorny/test-reporter.git
synced 2025-12-16 06:17:10 +01:00
Enforce Check Run API limits
This commit is contained in:
parent
fdd3509024
commit
7af0073fa3
5 changed files with 49 additions and 11 deletions
|
|
@ -61,8 +61,9 @@ jobs:
|
||||||
# jest-junit
|
# jest-junit
|
||||||
reporter: ''
|
reporter: ''
|
||||||
|
|
||||||
# Enables code annotations with error message and stack trace captured during test execution
|
# Limits number of created annotations with error message and stack trace captured during test execution.
|
||||||
annotations: 'true'
|
# Must be less or equal to 50.
|
||||||
|
max-annotations: '10'
|
||||||
|
|
||||||
# Set action as failed if test report contain any failed test
|
# Set action as failed if test report contain any failed test
|
||||||
fail-on-error: 'true'
|
fail-on-error: 'true'
|
||||||
|
|
|
||||||
12
action.yml
12
action.yml
|
|
@ -4,14 +4,16 @@ description: |
|
||||||
Supports .NET (xUnit, NUnit, MSTest), Dart, Flutter and JavaScript (JEST).
|
Supports .NET (xUnit, NUnit, MSTest), Dart, Flutter and JavaScript (JEST).
|
||||||
author: Michal Dorner <dorner.michal@gmail.com>
|
author: Michal Dorner <dorner.michal@gmail.com>
|
||||||
inputs:
|
inputs:
|
||||||
annotations:
|
|
||||||
description: Enables code annotations with error message and stack trace captured during test execution
|
|
||||||
required: true
|
|
||||||
default: 'true'
|
|
||||||
fail-on-error:
|
fail-on-error:
|
||||||
description: Set this action as failed if test report contain any failed test
|
description: Set this action as failed if test report contain any failed test
|
||||||
required: true
|
required: true
|
||||||
default: '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:
|
name:
|
||||||
description: Name of the check run
|
description: Name of the check run
|
||||||
required: true
|
required: true
|
||||||
|
|
@ -19,7 +21,7 @@ inputs:
|
||||||
description: |
|
description: |
|
||||||
Coma separated list of paths to test reports
|
Coma separated list of paths to test reports
|
||||||
Supports wildcards via [fast-glob](https://github.com/mrmlnc/fast-glob)
|
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
|
required: true
|
||||||
reporter:
|
reporter:
|
||||||
description: |
|
description: |
|
||||||
|
|
|
||||||
16
src/main.ts
16
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 {FileContent, ParseOptions, ParseTestResult} from './parsers/parser-types'
|
||||||
import {normalizeDirPath} from './utils/file-utils'
|
import {normalizeDirPath} from './utils/file-utils'
|
||||||
import {listFiles} from './utils/git'
|
import {listFiles} from './utils/git'
|
||||||
import {getCheckRunSha} from './utils/github-utils'
|
import {enforceCheckRunLimits, getCheckRunSha} from './utils/github-utils'
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
|
@ -19,7 +19,7 @@ async function run(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
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 failOnError = core.getInput('fail-on-error', {required: true}) === 'true'
|
||||||
const name = core.getInput('name', {required: true})
|
const name = core.getInput('name', {required: true})
|
||||||
const path = core.getInput('path', {required: true})
|
const path = core.getInput('path', {required: true})
|
||||||
|
|
@ -27,6 +27,11 @@ async function main(): Promise<void> {
|
||||||
const token = core.getInput('token', {required: true})
|
const token = core.getInput('token', {required: true})
|
||||||
const workDirInput = core.getInput('working-directory', {required: false})
|
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) {
|
if (workDirInput) {
|
||||||
core.info(`Changing directory to ${workDirInput}`)
|
core.info(`Changing directory to ${workDirInput}`)
|
||||||
process.chdir(workDirInput)
|
process.chdir(workDirInput)
|
||||||
|
|
@ -37,13 +42,14 @@ async function main(): Promise<void> {
|
||||||
const sha = getCheckRunSha()
|
const sha = getCheckRunSha()
|
||||||
|
|
||||||
// We won't need tracked files if we are not going to create annotations
|
// We won't need tracked files if we are not going to create annotations
|
||||||
|
const annotations = maxAnnotations > 0
|
||||||
const trackedFiles = annotations ? await listFiles() : []
|
const trackedFiles = annotations ? await listFiles() : []
|
||||||
|
|
||||||
const opts: ParseOptions = {
|
const opts: ParseOptions = {
|
||||||
name,
|
name,
|
||||||
annotations,
|
|
||||||
trackedFiles,
|
trackedFiles,
|
||||||
workDir
|
workDir,
|
||||||
|
annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
const parser = getParser(reporter)
|
const parser = getParser(reporter)
|
||||||
|
|
@ -58,6 +64,8 @@ async function main(): Promise<void> {
|
||||||
const result = await parser(files, opts)
|
const result = await parser(files, opts)
|
||||||
const conclusion = result.success ? 'success' : 'failure'
|
const conclusion = result.success ? 'success' : 'failure'
|
||||||
|
|
||||||
|
enforceCheckRunLimits(result, maxAnnotations)
|
||||||
|
|
||||||
core.info(`Creating check run '${name}' with conclusion '${conclusion}'`)
|
core.info(`Creating check run '${name}' with conclusion '${conclusion}'`)
|
||||||
await octokit.checks.create({
|
await octokit.checks.create({
|
||||||
head_sha: sha,
|
head_sha: sha,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import {EventPayloads} from '@octokit/webhooks'
|
import {EventPayloads} from '@octokit/webhooks'
|
||||||
|
|
||||||
|
import {TestResult} from '../parsers/parser-types'
|
||||||
|
import {ellipsis} from './markdown-utils'
|
||||||
|
|
||||||
export function getCheckRunSha(): string {
|
export function getCheckRunSha(): string {
|
||||||
if (github.context.payload.pull_request) {
|
if (github.context.payload.pull_request) {
|
||||||
const pr = github.context.payload.pull_request as EventPayloads.WebhookPayloadPullRequestPullRequest
|
const pr = github.context.payload.pull_request as EventPayloads.WebhookPayloadPullRequestPullRequest
|
||||||
|
|
@ -9,3 +12,19 @@ export function getCheckRunSha(): string {
|
||||||
|
|
||||||
return github.context.sha
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,11 @@ export function tableEscape(content: ToString): string {
|
||||||
export function fixEol(text?: string): string {
|
export function fixEol(text?: string): string {
|
||||||
return text?.replace(/\r/g, '') ?? ''
|
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) + '...'
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue