UNPKG

@quenty/cli-output-helpers

Version:

Helpers to generate Nevermore package and game templates

101 lines (90 loc) 3.12 kB
import * as fs from 'fs/promises'; import { OutputHelper } from '../../outputHelper.js'; import { isCI } from '../../cli-utils.js'; import { BaseReporter } from '../reporter.js'; import { type IStateTracker } from '../state/state-tracker.js'; import { type GithubCommentTableConfig, formatGithubTableBody, formatGithubErrorBody, formatGithubNoTestsBody, } from './formatting.js'; /** * Writes batch results to the GitHub Actions job summary. * * Appends a markdown table to the file at $GITHUB_STEP_SUMMARY, which * GitHub renders on the workflow run summary page. Unlike the PR comment * reporter, this writes only at completion (no throttled live updates). */ export class GithubJobSummaryReporter extends BaseReporter { private _state: IStateTracker | undefined; private _config: GithubCommentTableConfig; private _concurrency: number; private _error: string | undefined; private _noTestsMessage: string | undefined; constructor( state: IStateTracker | undefined, config: GithubCommentTableConfig, concurrency?: number ) { super(); this._state = state; this._config = config; this._concurrency = concurrency ?? 1; } /** * Set an error message to write instead of results. * When set, stopAsync() writes a failure summary rather than a results table. */ setError(error: string): void { this._error = error; } /** * Set an informational message when no tests were discovered. * When set, stopAsync() writes a neutral summary rather than a results table. */ setNoTestsRun(message: string): void { this._noTestsMessage = message; } override async stopAsync(): Promise<void> { if (!_isJobSummaryEnabled()) return; let body: string; if (this._error) { body = formatGithubErrorBody(this._config, this._error); } else if (this._noTestsMessage) { body = formatGithubNoTestsBody(this._config, this._noTestsMessage); } else if (this._state) { body = formatGithubTableBody( this._state, this._config, this._concurrency ); } else { return; } // Strip the HTML comment marker and ## heading — the GitHub Actions // job summary page already provides its own section header. body = _stripCommentHeader(body, this._config.commentMarker); const summaryPath = process.env.GITHUB_STEP_SUMMARY!; try { await fs.appendFile(summaryPath, body); OutputHelper.info('Written results to GitHub job summary.'); } catch (err) { OutputHelper.warn( `Failed to write job summary: ${err instanceof Error ? err.message : String(err)}` ); } } } function _isJobSummaryEnabled(): boolean { return isCI() && !!process.env.GITHUB_STEP_SUMMARY; } /** Remove the comment marker line and the `## Heading` line from formatted output. */ function _stripCommentHeader(body: string, commentMarker: string): string { let result = body; if (result.startsWith(commentMarker + '\n')) { result = result.slice(commentMarker.length + 1); } result = result.replace(/^## .+\n\n/, ''); return result; }