@vitest-evals/github-reporter 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -1
- package/dist/cli.js +232 -17
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +232 -17
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +94 -1
- package/dist/index.d.ts +94 -1
- package/dist/index.js +360 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +358 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22,7 +22,12 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
buildCheckAnnotations: () => buildCheckAnnotations,
|
|
24
24
|
collectEvalReport: () => collectEvalReport,
|
|
25
|
+
computePassRate: () => computePassRate,
|
|
26
|
+
evaluateEvalGate: () => evaluateEvalGate,
|
|
27
|
+
formatPercent: () => formatPercent,
|
|
25
28
|
publishCheckRun: () => publishCheckRun,
|
|
29
|
+
publishEvalReport: () => publishEvalReport,
|
|
30
|
+
renderGateWorkflowCommand: () => renderGateWorkflowCommand,
|
|
26
31
|
renderJobSummary: () => renderJobSummary,
|
|
27
32
|
renderWorkflowCommands: () => renderWorkflowCommands
|
|
28
33
|
});
|
|
@@ -297,9 +302,10 @@ var DEFAULT_MAX_CHECK_ANNOTATIONS = 50;
|
|
|
297
302
|
var MAX_CHECK_FIELD_LENGTH = 64e3;
|
|
298
303
|
function renderWorkflowCommands(report, options = {}) {
|
|
299
304
|
const maxAnnotations = options.maxAnnotations ?? DEFAULT_MAX_WORKFLOW_ANNOTATIONS;
|
|
305
|
+
const command = caseAnnotationCommand(options.gate);
|
|
300
306
|
return report.failures.filter(hasAnnotationLocation).slice(0, maxAnnotations).map(
|
|
301
307
|
(testCase) => formatWorkflowCommand({
|
|
302
|
-
command
|
|
308
|
+
command,
|
|
303
309
|
properties: {
|
|
304
310
|
file: testCase.displayFile,
|
|
305
311
|
line: String(testCase.location.line),
|
|
@@ -315,11 +321,12 @@ function buildCheckAnnotations(report, options = {}) {
|
|
|
315
321
|
options.maxAnnotations ?? DEFAULT_MAX_CHECK_ANNOTATIONS,
|
|
316
322
|
DEFAULT_MAX_CHECK_ANNOTATIONS
|
|
317
323
|
);
|
|
324
|
+
const annotationLevel = caseAnnotationLevel(options.gate);
|
|
318
325
|
return report.failures.filter(hasAnnotationLocation).slice(0, maxAnnotations).map((testCase) => ({
|
|
319
326
|
path: testCase.displayFile,
|
|
320
327
|
start_line: testCase.location.line,
|
|
321
328
|
end_line: testCase.location.line,
|
|
322
|
-
annotation_level:
|
|
329
|
+
annotation_level: annotationLevel,
|
|
323
330
|
title: truncate(
|
|
324
331
|
`${testCase.primaryFailure?.judgeName ?? "vitest-evals"} - ${testCase.displayName}`,
|
|
325
332
|
255
|
|
@@ -331,6 +338,12 @@ function buildCheckAnnotations(report, options = {}) {
|
|
|
331
338
|
raw_details: truncate(formatRawDetails(testCase), MAX_CHECK_FIELD_LENGTH)
|
|
332
339
|
}));
|
|
333
340
|
}
|
|
341
|
+
function caseAnnotationCommand(gate) {
|
|
342
|
+
return gate?.ok ? "warning" : "error";
|
|
343
|
+
}
|
|
344
|
+
function caseAnnotationLevel(gate) {
|
|
345
|
+
return gate?.ok ? "warning" : "failure";
|
|
346
|
+
}
|
|
334
347
|
function hasAnnotationLocation(testCase) {
|
|
335
348
|
return Boolean(testCase.location);
|
|
336
349
|
}
|
|
@@ -390,6 +403,164 @@ function formatWorkflowCommand({
|
|
|
390
403
|
return `::${command} ${renderedProperties}::${escapeCommandData(message)}`;
|
|
391
404
|
}
|
|
392
405
|
|
|
406
|
+
// src/gate.ts
|
|
407
|
+
function evaluateEvalGate(report, policy = {}) {
|
|
408
|
+
const minPassRate = resolveMinPassRate(policy);
|
|
409
|
+
const minScoreAverage = policy.minScoreAverage;
|
|
410
|
+
const enforced = minPassRate !== void 0 || minScoreAverage !== void 0 || policy.failOnFailures === true;
|
|
411
|
+
const passRate = computePassRate(report);
|
|
412
|
+
const counts = formatEvalCounts(report, passRate);
|
|
413
|
+
if (!enforced) {
|
|
414
|
+
const ok = report.status === "passed";
|
|
415
|
+
return {
|
|
416
|
+
ok,
|
|
417
|
+
status: ok ? "passed" : "failed",
|
|
418
|
+
enforced: false,
|
|
419
|
+
passRate,
|
|
420
|
+
title: defaultCheckTitle(report),
|
|
421
|
+
message: ok ? `eval report passed: ${counts}` : `eval report failed: ${counts}`
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
const nonEvalFailures = Math.max(
|
|
425
|
+
0,
|
|
426
|
+
report.totals.failed - report.totals.evalFailed
|
|
427
|
+
);
|
|
428
|
+
if (nonEvalFailures > 0) {
|
|
429
|
+
return {
|
|
430
|
+
ok: false,
|
|
431
|
+
status: "failed",
|
|
432
|
+
enforced: true,
|
|
433
|
+
passRate,
|
|
434
|
+
title: "Eval report hard failure",
|
|
435
|
+
message: `${formatNumber(nonEvalFailures)} non-eval test failure${nonEvalFailures === 1 ? "" : "s"}; ${counts}`
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
if (report.totals.evalTotal === 0) {
|
|
439
|
+
return {
|
|
440
|
+
ok: false,
|
|
441
|
+
status: "failed",
|
|
442
|
+
enforced: true,
|
|
443
|
+
passRate: null,
|
|
444
|
+
title: "Eval report hard failure",
|
|
445
|
+
message: "no eval cases were reported"
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
if (report.status === "failed" && report.totals.failed === 0 && report.failures.length === 0) {
|
|
449
|
+
return {
|
|
450
|
+
ok: false,
|
|
451
|
+
status: "failed",
|
|
452
|
+
enforced: true,
|
|
453
|
+
passRate,
|
|
454
|
+
title: "Eval report hard failure",
|
|
455
|
+
message: `vitest run failed without counted test failures; ${counts}`
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
if (minPassRate !== void 0 && (passRate === null || passRate + Number.EPSILON < minPassRate)) {
|
|
459
|
+
return {
|
|
460
|
+
ok: false,
|
|
461
|
+
status: "failed",
|
|
462
|
+
enforced: true,
|
|
463
|
+
passRate,
|
|
464
|
+
title: `Eval pass rate ${formatPercent(passRate)} \u2014 required ${formatPercent(minPassRate)}`,
|
|
465
|
+
message: `eval pass rate below floor: ${counts}; required >= ${formatPercent(minPassRate)}`
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
if (minScoreAverage !== void 0) {
|
|
469
|
+
const average = report.score?.average;
|
|
470
|
+
if (average === void 0 || !Number.isFinite(average)) {
|
|
471
|
+
return {
|
|
472
|
+
ok: false,
|
|
473
|
+
status: "failed",
|
|
474
|
+
enforced: true,
|
|
475
|
+
passRate,
|
|
476
|
+
title: "Eval score gate failed",
|
|
477
|
+
message: `no score average available; required avg score >= ${formatScore(minScoreAverage)}`
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
if (average + Number.EPSILON < minScoreAverage) {
|
|
481
|
+
return {
|
|
482
|
+
ok: false,
|
|
483
|
+
status: "failed",
|
|
484
|
+
enforced: true,
|
|
485
|
+
passRate,
|
|
486
|
+
title: `Avg score ${formatScore(average)} \u2014 required ${formatScore(minScoreAverage)}`,
|
|
487
|
+
message: `avg score below floor: ${counts}; required avg score >= ${formatScore(minScoreAverage)}`
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
ok: true,
|
|
493
|
+
status: "passed",
|
|
494
|
+
enforced: true,
|
|
495
|
+
passRate,
|
|
496
|
+
title: enforcedPassTitle(report, passRate, minPassRate, minScoreAverage),
|
|
497
|
+
message: `eval gate passed: ${counts}${formatFloorSuffix(minPassRate, minScoreAverage)}`
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function computePassRate(report) {
|
|
501
|
+
if (report.totals.evalTotal <= 0) {
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
return report.totals.evalPassed / report.totals.evalTotal;
|
|
505
|
+
}
|
|
506
|
+
function formatPercent(value) {
|
|
507
|
+
if (value == null || !Number.isFinite(value)) {
|
|
508
|
+
return "n/a";
|
|
509
|
+
}
|
|
510
|
+
return `${(value * 100).toFixed(1)}%`;
|
|
511
|
+
}
|
|
512
|
+
function renderGateWorkflowCommand(gate) {
|
|
513
|
+
if (gate.ok || !gate.enforced) {
|
|
514
|
+
return void 0;
|
|
515
|
+
}
|
|
516
|
+
return `::error title=${escapeCommandProperty(gate.title)}::${escapeCommandData(gate.message)}`;
|
|
517
|
+
}
|
|
518
|
+
function resolveMinPassRate(policy) {
|
|
519
|
+
const configured = policy.minPassRate;
|
|
520
|
+
if (policy.failOnFailures) {
|
|
521
|
+
if (configured === void 0) {
|
|
522
|
+
return 1;
|
|
523
|
+
}
|
|
524
|
+
return Math.max(configured, 1);
|
|
525
|
+
}
|
|
526
|
+
return configured;
|
|
527
|
+
}
|
|
528
|
+
function defaultCheckTitle(report) {
|
|
529
|
+
if (report.failures.length === 0 && report.status === "passed") {
|
|
530
|
+
return "No eval failures";
|
|
531
|
+
}
|
|
532
|
+
if (report.failures.length === 0) {
|
|
533
|
+
return "Vitest run failed";
|
|
534
|
+
}
|
|
535
|
+
return `${report.failures.length} eval failure${report.failures.length === 1 ? "" : "s"}`;
|
|
536
|
+
}
|
|
537
|
+
function enforcedPassTitle(report, passRate, minPassRate, minScoreAverage) {
|
|
538
|
+
if (minPassRate !== void 0) {
|
|
539
|
+
return `Eval pass rate ${formatPercent(passRate)} \u2014 floor ${formatPercent(minPassRate)}`;
|
|
540
|
+
}
|
|
541
|
+
if (minScoreAverage !== void 0) {
|
|
542
|
+
return `Avg score ${formatScore(report.score?.average)} \u2014 floor ${formatScore(minScoreAverage)}`;
|
|
543
|
+
}
|
|
544
|
+
return defaultCheckTitle(report);
|
|
545
|
+
}
|
|
546
|
+
function formatEvalCounts(report, passRate) {
|
|
547
|
+
const scoreText = report.score?.average === void 0 ? "n/a" : formatScore(report.score.average);
|
|
548
|
+
const passRateText = passRate === null ? "n/a" : formatPercent(passRate);
|
|
549
|
+
return `${formatNumber(report.totals.evalPassed)}/${formatNumber(
|
|
550
|
+
report.totals.evalTotal
|
|
551
|
+
)} passed (${passRateText}), avg score ${scoreText}`;
|
|
552
|
+
}
|
|
553
|
+
function formatFloorSuffix(minPassRate, minScoreAverage) {
|
|
554
|
+
const parts = [];
|
|
555
|
+
if (minPassRate !== void 0) {
|
|
556
|
+
parts.push(`pass rate floor ${formatPercent(minPassRate)}`);
|
|
557
|
+
}
|
|
558
|
+
if (minScoreAverage !== void 0) {
|
|
559
|
+
parts.push(`avg score floor ${formatScore(minScoreAverage)}`);
|
|
560
|
+
}
|
|
561
|
+
return parts.length === 0 ? "" : `; ${parts.join(", ")}`;
|
|
562
|
+
}
|
|
563
|
+
|
|
393
564
|
// src/summary.ts
|
|
394
565
|
var DEFAULT_MAX_FAILURES = 20;
|
|
395
566
|
var DEFAULT_MAX_REASON_CHARS = 8e3;
|
|
@@ -410,20 +581,22 @@ function renderJobSummary(report, options = {}) {
|
|
|
410
581
|
const lines = [
|
|
411
582
|
"# vitest-evals",
|
|
412
583
|
"",
|
|
413
|
-
...renderSummaryTable(report, nonEvalFailures),
|
|
584
|
+
...renderSummaryTable(report, nonEvalFailures, options.gate),
|
|
414
585
|
"",
|
|
415
586
|
...renderScoreDistribution(report),
|
|
416
587
|
"## Results",
|
|
417
588
|
""
|
|
418
589
|
];
|
|
419
590
|
if (report.failures.length > 0) {
|
|
420
|
-
|
|
591
|
+
const failureHeading = options.gate?.ok === true ? "### Quality Misses" : "### Failures";
|
|
592
|
+
lines.push(failureHeading, "");
|
|
421
593
|
failures.forEach((testCase, index) => {
|
|
422
594
|
lines.push(...renderFailureDetails(testCase, index + 1, options), "");
|
|
423
595
|
});
|
|
424
596
|
if (report.failures.length > failures.length) {
|
|
597
|
+
const omittedLabel = options.gate?.ok === true ? "quality misses" : "failures";
|
|
425
598
|
lines.push(
|
|
426
|
-
`${report.failures.length - failures.length} more
|
|
599
|
+
`${report.failures.length - failures.length} more ${omittedLabel} omitted from this summary.`,
|
|
427
600
|
""
|
|
428
601
|
);
|
|
429
602
|
}
|
|
@@ -439,9 +612,9 @@ function renderJobSummary(report, options = {}) {
|
|
|
439
612
|
function formatCountLine(passed, failed, total) {
|
|
440
613
|
return `${formatNumber(passed)} passed, ${formatNumber(failed)} failed, ${formatNumber(total)} total`;
|
|
441
614
|
}
|
|
442
|
-
function renderSummaryTable(report, nonEvalFailures) {
|
|
615
|
+
function renderSummaryTable(report, nonEvalFailures, gate) {
|
|
443
616
|
const rows = [
|
|
444
|
-
["Status", report.status],
|
|
617
|
+
["Status", gate?.status ?? report.status],
|
|
445
618
|
[
|
|
446
619
|
"Evals",
|
|
447
620
|
formatCountLine(
|
|
@@ -451,9 +624,20 @@ function renderSummaryTable(report, nonEvalFailures) {
|
|
|
451
624
|
)
|
|
452
625
|
]
|
|
453
626
|
];
|
|
627
|
+
if (gate?.passRate !== void 0 && gate.passRate !== null) {
|
|
628
|
+
rows.push(["Pass Rate", formatPercent(gate.passRate)]);
|
|
629
|
+
} else if (report.totals.evalTotal > 0) {
|
|
630
|
+
rows.push([
|
|
631
|
+
"Pass Rate",
|
|
632
|
+
formatPercent(report.totals.evalPassed / report.totals.evalTotal)
|
|
633
|
+
]);
|
|
634
|
+
}
|
|
454
635
|
if (report.score) {
|
|
455
636
|
rows.push(["Score", formatScoreSummary(report.score)]);
|
|
456
637
|
}
|
|
638
|
+
if (gate?.enforced) {
|
|
639
|
+
rows.push(["Gate", gate.message]);
|
|
640
|
+
}
|
|
457
641
|
if (nonEvalFailures > 0) {
|
|
458
642
|
rows.push([
|
|
459
643
|
"Other Failures",
|
|
@@ -730,23 +914,25 @@ async function publishCheckRun(report, options = {}) {
|
|
|
730
914
|
};
|
|
731
915
|
}
|
|
732
916
|
function buildCheckRunPayload(report, options) {
|
|
917
|
+
const gate = options.gate ?? evaluateEvalGate(report);
|
|
733
918
|
const annotations = buildCheckAnnotations(report, {
|
|
734
|
-
maxAnnotations: options.maxAnnotations
|
|
919
|
+
maxAnnotations: options.maxAnnotations,
|
|
920
|
+
gate
|
|
735
921
|
});
|
|
736
|
-
const title = report.failures.length === 0 && report.status === "passed" ? "No eval failures" : report.failures.length === 0 ? "Vitest run failed" : `${report.failures.length} eval failure${report.failures.length === 1 ? "" : "s"}`;
|
|
737
922
|
return {
|
|
738
923
|
status: "completed",
|
|
739
|
-
conclusion:
|
|
924
|
+
conclusion: gate.ok ? "success" : "failure",
|
|
740
925
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
741
926
|
output: {
|
|
742
|
-
title,
|
|
927
|
+
title: gate.title,
|
|
743
928
|
summary: truncateCheckSummary(
|
|
744
929
|
renderJobSummary(report, {
|
|
745
930
|
...options,
|
|
746
931
|
maxFailures: options.maxFailures ?? 5,
|
|
747
932
|
maxReasonChars: options.maxReasonChars ?? 4e3,
|
|
748
933
|
maxOutputChars: options.maxOutputChars ?? 2e3,
|
|
749
|
-
maxToolCalls: options.maxToolCalls ?? 10
|
|
934
|
+
maxToolCalls: options.maxToolCalls ?? 10,
|
|
935
|
+
gate
|
|
750
936
|
})
|
|
751
937
|
),
|
|
752
938
|
annotations
|
|
@@ -759,11 +945,173 @@ function truncateCheckSummary(summary) {
|
|
|
759
945
|
}
|
|
760
946
|
return `${summary.slice(0, MAX_CHECK_SUMMARY_LENGTH - CHECK_SUMMARY_TRUNCATION_SUFFIX.length).trimEnd()}${CHECK_SUMMARY_TRUNCATION_SUFFIX}`;
|
|
761
947
|
}
|
|
948
|
+
|
|
949
|
+
// src/report.ts
|
|
950
|
+
var import_promises = require("fs/promises");
|
|
951
|
+
var import_node = require("@vitest-evals/core/node");
|
|
952
|
+
|
|
953
|
+
// src/merge.ts
|
|
954
|
+
function mergeEvalReports(reports) {
|
|
955
|
+
const cases = reports.flatMap((report) => report.cases);
|
|
956
|
+
const failures = reports.flatMap((report) => report.failures);
|
|
957
|
+
const scoredCases = cases.map((testCase) => testCase.eval?.avgScore).filter(
|
|
958
|
+
(score) => typeof score === "number" && Number.isFinite(score)
|
|
959
|
+
);
|
|
960
|
+
const startedAtValues = reports.map((report) => report.startedAt).filter(
|
|
961
|
+
(startedAt2) => typeof startedAt2 === "number" && Number.isFinite(startedAt2)
|
|
962
|
+
);
|
|
963
|
+
const startedAt = startedAtValues.length > 0 ? Math.min(...startedAtValues) : void 0;
|
|
964
|
+
return {
|
|
965
|
+
status: reports.some((report) => report.status === "failed") ? "failed" : "passed",
|
|
966
|
+
startedAt,
|
|
967
|
+
durationMs: mergeDuration(reports),
|
|
968
|
+
totals: {
|
|
969
|
+
total: sum(reports, (report) => report.totals.total),
|
|
970
|
+
passed: sum(reports, (report) => report.totals.passed),
|
|
971
|
+
failed: sum(reports, (report) => report.totals.failed),
|
|
972
|
+
skipped: sum(reports, (report) => report.totals.skipped),
|
|
973
|
+
evalTotal: sum(reports, (report) => report.totals.evalTotal),
|
|
974
|
+
evalPassed: sum(reports, (report) => report.totals.evalPassed),
|
|
975
|
+
evalFailed: sum(reports, (report) => report.totals.evalFailed)
|
|
976
|
+
},
|
|
977
|
+
score: scoredCases.length > 0 ? {
|
|
978
|
+
average: scoredCases.reduce((total, score) => total + score, 0) / scoredCases.length,
|
|
979
|
+
minimum: Math.min(...scoredCases)
|
|
980
|
+
} : void 0,
|
|
981
|
+
usage: mergeUsage(reports.map((report) => report.usage)),
|
|
982
|
+
cases,
|
|
983
|
+
failures
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function mergeUsage(usages) {
|
|
987
|
+
return {
|
|
988
|
+
inputTokens: sum(usages, (usage) => usage.inputTokens),
|
|
989
|
+
outputTokens: sum(usages, (usage) => usage.outputTokens),
|
|
990
|
+
reasoningTokens: sum(usages, (usage) => usage.reasoningTokens),
|
|
991
|
+
totalTokens: sum(usages, (usage) => usage.totalTokens),
|
|
992
|
+
toolCalls: sum(usages, (usage) => usage.toolCalls)
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
function mergeDuration(reports) {
|
|
996
|
+
const durations = reports.map((report) => report.durationMs).filter(
|
|
997
|
+
(durationMs) => typeof durationMs === "number" && Number.isFinite(durationMs)
|
|
998
|
+
);
|
|
999
|
+
const intervals = reports.map((report) => {
|
|
1000
|
+
if (typeof report.startedAt !== "number" || !Number.isFinite(report.startedAt) || typeof report.durationMs !== "number" || !Number.isFinite(report.durationMs)) {
|
|
1001
|
+
return void 0;
|
|
1002
|
+
}
|
|
1003
|
+
return {
|
|
1004
|
+
start: report.startedAt,
|
|
1005
|
+
end: report.startedAt + report.durationMs
|
|
1006
|
+
};
|
|
1007
|
+
}).filter(
|
|
1008
|
+
(interval) => Boolean(interval)
|
|
1009
|
+
);
|
|
1010
|
+
if (intervals.length > 0 && intervals.length === durations.length) {
|
|
1011
|
+
return Math.max(...intervals.map((interval) => interval.end)) - Math.min(...intervals.map((interval) => interval.start));
|
|
1012
|
+
}
|
|
1013
|
+
return durations.length > 0 ? durations.reduce((total, durationMs) => total + durationMs, 0) : void 0;
|
|
1014
|
+
}
|
|
1015
|
+
function sum(items, select) {
|
|
1016
|
+
return items.reduce((total, item) => total + select(item), 0);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// src/report.ts
|
|
1020
|
+
async function publishEvalReport(options) {
|
|
1021
|
+
const resultFiles = await (0, import_node.resolveResultFiles)(options.resultPatterns, {
|
|
1022
|
+
cwd: options.cwd
|
|
1023
|
+
});
|
|
1024
|
+
if (resultFiles.length === 0) {
|
|
1025
|
+
throw new Error(
|
|
1026
|
+
`No eval result files matched: ${options.resultPatterns.join(", ")}`
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
const reports = await Promise.all(
|
|
1030
|
+
resultFiles.map(async (resultFile) => {
|
|
1031
|
+
const json = await (0, import_node.readVitestJsonReportFile)(resultFile);
|
|
1032
|
+
return collectEvalReport(json, {
|
|
1033
|
+
workspace: options.workspace
|
|
1034
|
+
});
|
|
1035
|
+
})
|
|
1036
|
+
);
|
|
1037
|
+
const report = mergeEvalReports(reports);
|
|
1038
|
+
const gate = evaluateEvalGate(report, {
|
|
1039
|
+
failOnFailures: options.failOnFailures,
|
|
1040
|
+
minPassRate: options.minPassRate,
|
|
1041
|
+
minScoreAverage: options.minScoreAverage
|
|
1042
|
+
});
|
|
1043
|
+
const summary = renderJobSummary(report, {
|
|
1044
|
+
maxFailures: options.maxFailures,
|
|
1045
|
+
maxOutputChars: options.maxOutputChars,
|
|
1046
|
+
maxReasonChars: options.maxReasonChars,
|
|
1047
|
+
maxToolCalls: options.maxToolCalls,
|
|
1048
|
+
gate
|
|
1049
|
+
});
|
|
1050
|
+
if (options.summaryEnabled !== false) {
|
|
1051
|
+
if (options.summaryPath) {
|
|
1052
|
+
await (0, import_promises.appendFile)(options.summaryPath, `${summary}
|
|
1053
|
+
`);
|
|
1054
|
+
} else {
|
|
1055
|
+
console.log(summary);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
if (options.annotations) {
|
|
1059
|
+
const gateCommand = renderGateWorkflowCommand(gate);
|
|
1060
|
+
if (gateCommand) {
|
|
1061
|
+
console.log(gateCommand);
|
|
1062
|
+
}
|
|
1063
|
+
for (const command of renderWorkflowCommands(report, {
|
|
1064
|
+
maxAnnotations: options.maxAnnotations,
|
|
1065
|
+
gate
|
|
1066
|
+
})) {
|
|
1067
|
+
console.log(command);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
let checkRun;
|
|
1071
|
+
if (options.checkRun) {
|
|
1072
|
+
try {
|
|
1073
|
+
checkRun = await publishCheckRun(report, {
|
|
1074
|
+
checkRunId: options.checkRunId,
|
|
1075
|
+
maxAnnotations: options.maxAnnotations,
|
|
1076
|
+
maxFailures: options.maxFailures,
|
|
1077
|
+
maxOutputChars: options.maxOutputChars,
|
|
1078
|
+
maxReasonChars: options.maxReasonChars,
|
|
1079
|
+
maxToolCalls: options.maxToolCalls,
|
|
1080
|
+
name: options.checkName,
|
|
1081
|
+
repository: options.repository,
|
|
1082
|
+
sha: options.sha,
|
|
1083
|
+
token: options.token,
|
|
1084
|
+
gate
|
|
1085
|
+
});
|
|
1086
|
+
if (checkRun.status === "skipped") {
|
|
1087
|
+
options.warn?.(`GitHub Check Run skipped: ${checkRun.reason}`);
|
|
1088
|
+
}
|
|
1089
|
+
} catch (error) {
|
|
1090
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1091
|
+
if (options.failOnCheckError) {
|
|
1092
|
+
throw error;
|
|
1093
|
+
}
|
|
1094
|
+
options.warn?.(message);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
return {
|
|
1098
|
+
report,
|
|
1099
|
+
resultFiles,
|
|
1100
|
+
gate,
|
|
1101
|
+
shouldFail: gate.enforced && !gate.ok,
|
|
1102
|
+
checkRun
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
762
1105
|
// Annotate the CommonJS export names for ESM import in node:
|
|
763
1106
|
0 && (module.exports = {
|
|
764
1107
|
buildCheckAnnotations,
|
|
765
1108
|
collectEvalReport,
|
|
1109
|
+
computePassRate,
|
|
1110
|
+
evaluateEvalGate,
|
|
1111
|
+
formatPercent,
|
|
766
1112
|
publishCheckRun,
|
|
1113
|
+
publishEvalReport,
|
|
1114
|
+
renderGateWorkflowCommand,
|
|
767
1115
|
renderJobSummary,
|
|
768
1116
|
renderWorkflowCommands
|
|
769
1117
|
});
|