@quenty/cli-output-helpers
Version:
Helpers to generate Nevermore package and game templates
113 lines • 3.78 kB
JavaScript
import { isCI } from '../../cli-utils.js';
import { BaseReporter, } from '../reporter.js';
import { formatGithubTableBody, formatGithubErrorBody, formatGithubNoTestsBody, } from './formatting.js';
import { postOrUpdateCommentAsync, postOrUpdateCommentSectionAsync, } from './github-api.js';
export { summarizeError } from './formatting.js';
/**
* Maintains a live PR comment that updates as jobs progress.
* The table grid is stable — same rows throughout, only status changes.
* Updates are throttled to avoid GitHub API rate limits.
*
* Also used for post-hoc posting from a LoadedStateTracker (call stopAsync directly).
*/
export class GithubCommentTableReporter extends BaseReporter {
_state;
_config;
_concurrency;
_updateTimer;
_updatePending = false;
_disposed = false;
_error;
_noTestsMessage;
static THROTTLE_MS = 10_000;
constructor(state, config, concurrency) {
super();
this._state = state;
this._config = config;
this._concurrency = concurrency ?? 1;
}
/**
* Set an error message to post instead of results.
* When set, stopAsync() posts a failure comment rather than a results table.
*/
setError(error) {
this._error = error;
}
/**
* Set an informational message when no tests were discovered.
* When set, stopAsync() posts a neutral comment rather than a results table.
*/
setNoTestsRun(message) {
this._noTestsMessage = message;
}
async startAsync() {
if (!_isGithubCommentEnabled())
return;
await this._postUpdateAsync();
}
onPackageStart(_name) {
this._scheduleUpdate();
}
onPackagePhaseChange(_name, _phase) {
this._scheduleUpdate();
}
onPackageProgressUpdate(_name, _progress) {
this._scheduleUpdate();
}
onPackageResult(_result) {
this._scheduleUpdate();
}
async stopAsync() {
this._disposed = true;
if (this._updateTimer) {
clearTimeout(this._updateTimer);
this._updateTimer = undefined;
}
if (!_isGithubCommentEnabled())
return;
if (this._error) {
await this._postCommentAsync(formatGithubErrorBody(this._config, this._error));
}
else if (this._noTestsMessage) {
await this._postCommentAsync(formatGithubNoTestsBody(this._config, this._noTestsMessage));
}
else if (this._state) {
await this._postUpdateAsync();
}
}
_scheduleUpdate() {
if (!_isGithubCommentEnabled() || this._disposed)
return;
if (this._updateTimer) {
this._updatePending = true;
return;
}
this._updateTimer = setTimeout(async () => {
await this._postUpdateAsync();
this._updateTimer = undefined;
if (this._updatePending && !this._disposed) {
this._updatePending = false;
this._scheduleUpdate();
}
}, GithubCommentTableReporter.THROTTLE_MS);
this._updateTimer.unref();
}
async _postUpdateAsync() {
if (!this._state)
return;
const body = formatGithubTableBody(this._state, this._config, this._concurrency);
await this._postCommentAsync(body);
}
async _postCommentAsync(body) {
if (this._config.sectionId) {
await postOrUpdateCommentSectionAsync(this._config.sectionId, body);
}
else {
await postOrUpdateCommentAsync(this._config.commentMarker, body);
}
}
}
function _isGithubCommentEnabled() {
return isCI() && !!process.env.GITHUB_TOKEN;
}
//# sourceMappingURL=comment-table-reporter.js.map