Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cf6b93b
feat(ci): add e2e duration charts
universal-itengineer May 18, 2026
4e194aa
fix(ci): log chart render errors and tighten e2e report install
universal-itengineer May 18, 2026
a40e567
fix(ci, observability): keep Loop thread reply when chart upload fails
universal-itengineer May 18, 2026
d93883b
refactor(ci, observability): align messenger report with main + chart…
universal-itengineer May 18, 2026
ea29baa
fix adding graph for report
universal-itengineer May 19, 2026
098b0c5
feat(ci, observability): replace e2e cluster chart set with five new …
universal-itengineer May 20, 2026
509a01a
refactor(ci, observability): focus e2e charts on failures and durations
universal-itengineer May 20, 2026
e7d1249
refactor(ci, observability): remove duplicate e2e failed-slow chart
universal-itengineer May 20, 2026
3c0031a
refactor(ci, observability): use duration gradient for slowest specs …
universal-itengineer May 20, 2026
76d8ab2
refactor(ci, observability): clarify e2e chart titles and layout
universal-itengineer May 20, 2026
08636d5
refactor(ci, observability): widen slowest specs chart output
universal-itengineer May 20, 2026
90ff63f
refactor(ci, observability): add margin to slowest specs chart
universal-itengineer May 20, 2026
464e767
fix(ci, observability): keep small duration bucket counts visible
universal-itengineer May 20, 2026
2c8b1af
refactor(ci, observability): separate slowest e2e charts from messenger
universal-itengineer May 21, 2026
9dadce9
fix(ci, observability): write slowest charts to tmp charts
universal-itengineer May 21, 2026
bf31aec
refactor(ci, observability): move e2e charts to python
universal-itengineer May 22, 2026
0e0db2a
fix(ci, observability): apply e2e chart review fixes
universal-itengineer May 22, 2026
078539a
fix formatting
universal-itengineer May 22, 2026
ac3e0eb
fix formatting 2
universal-itengineer May 22, 2026
a37a2ca
fix formatting 3
universal-itengineer May 22, 2026
c8f8600
resovle comments
universal-itengineer May 25, 2026
19c639c
rm tmp folder
universal-itengineer May 26, 2026
1d6d242
resolve comments
universal-itengineer May 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/scripts/js/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"printWidth": 120
}
10 changes: 10 additions & 0 deletions .github/scripts/js/e2e/report/cluster-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ async function readStageJobUrlsFromApi(github, context, config, core) {
* metrics: ReturnType<typeof zeroMetrics>,
* failedTests: string[],
* failedTestDetails: Array<{name: string, reason: string}>,
* specTimings: Array<Record<string, any>>,
* suiteTotalMs: number,
* startedAt: null,
* source: string,
* }} Empty parsed-report payload.
Expand All @@ -187,6 +189,8 @@ function emptyParsedReport(source) {
metrics: zeroMetrics(),
failedTests: [],
failedTestDetails: [],
specTimings: [],
suiteTotalMs: 0,
startedAt: null,
source,
};
Expand Down Expand Up @@ -217,6 +221,8 @@ const ginkgoOutputSource = {
* metrics: ReturnType<typeof zeroMetrics>,
* failedTests: string[],
* failedTestDetails: Array<{name: string, reason: string}>,
* specTimings: Array<Record<string, any>>,
* suiteTotalMs: number,
* startedAt: string|null,
* }} parse Parser function for the source content.
* @property {function(string): RegExp} pattern Builds the file-name regex for the source.
Expand Down Expand Up @@ -252,6 +258,8 @@ function findGinkgoSource(config, source) {
* metrics: ReturnType<typeof zeroMetrics>,
* failedTests: string[],
* failedTestDetails: Array<{name: string, reason: string}>,
* specTimings: Array<Record<string, any>>,
* suiteTotalMs: number,
* startedAt: string|null,
* source: string,
* }} Parsed report payload with a source tag.
Expand Down Expand Up @@ -320,6 +328,8 @@ function buildReportPayload({
metrics: parsedReport.metrics,
failedTests: parsedReport.failedTests,
failedTestDetails: parsedReport.failedTestDetails,
specTimings: parsedReport.specTimings || [],
suiteTotalMs: parsedReport.suiteTotalMs || 0,
sourceReport: sourcePath,
reportSource: parsedReport.source,
};
Expand Down
40 changes: 37 additions & 3 deletions .github/scripts/js/e2e/report/cluster-report.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,11 +454,43 @@ describe("cluster-report", () => {
reason: "timed out waiting for VM to become ready",
},
]);
expect(report.suiteTotalMs).toBe(1800000);
expect(report.specTimings).toEqual([
{
name: "passes",
group: "Suite",
state: "passed",
runtimeMs: 60000,
labels: [],
},
{
name: "fails & burns",
group: "Suite",
state: "failed",
runtimeMs: 60000,
labels: ["Slow"],
},
{
name: "errors <loudly>",
group: "Other",
state: "errors",
runtimeMs: 60000,
labels: [],
},
{
name: "skipped",
group: "Top-level Its",
state: "skipped",
runtimeMs: 60000,
labels: [],
},
]);
expect(report.reportSource).toBe("ginkgo-json");
expect(report.sourceReport).toBe(rawReportPath);
expect(JSON.parse(fs.readFileSync(reportFile, "utf8")).reportKind).toBe(
"tests"
);
const persistedReport = JSON.parse(fs.readFileSync(reportFile, "utf8"));
expect(persistedReport.reportKind).toBe("tests");
expect(persistedReport.specTimings).toEqual(report.specTimings);
expect(persistedReport.suiteTotalMs).toBe(1800000);
expect(core.setOutput).toHaveBeenCalledWith("report_file", reportFile);
expect(core.setOutput).toHaveBeenCalledWith("report_kind", "tests");
expect(core.setOutput).toHaveBeenCalledWith("status", "failure");
Expand Down Expand Up @@ -828,6 +860,8 @@ describe("cluster-report", () => {
successRate: 92.78,
});
expect(parsed.startedAt).toBe("2026-04-28T03:11:27.708387575Z");
expect(parsed.specTimings).toHaveLength(131);
expect(parsed.suiteTotalMs).toBe(1800000);
expect(parsed.failedTests).toHaveLength(7);
expect(parsed.failedTests).toContain(
"[It] VirtualMachineOperationRestore restores a virtual machine from a snapshot BestEffort restore mode; automatic restart approval mode; manual run policy [Slow]"
Expand Down
22 changes: 16 additions & 6 deletions .github/scripts/js/e2e/report/messenger-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const fs = require("fs");

const { listMatchingFiles } = require("./shared/fs-utils");
const { REPORT_FILE_PATTERN } = require("./shared/report-model");
const { getClusterChartFiles } = require("./messenger/chart-files");
const { makeThreadedReportInLoop } = require("./messenger/loop-client");
const { readMessengerConfigFromEnv } = require("./messenger/config");
const {
Expand Down Expand Up @@ -103,12 +104,15 @@ function readReports(reportsDir, configuredClusters, core) {
* @param {MessengerMessagesParams} params Message rendering inputs.
* @returns {{
* message: string,
* threadMessages: string[]
* threadMessages: Array<{message: string, files: Array<Record<string, any>>}>
* }} Rendered markdown payloads.
*/
function buildMessengerMessages({ reportsDir, configuredClusters, core }) {
async function buildMessengerMessages({ reportsDir, configuredClusters, core }) {
const orderedReports = readReports(reportsDir, configuredClusters, core);
const threadMessages = buildThreadMessages(orderedReports);
const threadMessages = await buildThreadMessages(orderedReports, {
getClusterChartFiles,
core,
});
return {
message: buildMainMessage(orderedReports),
threadMessages,
Expand All @@ -122,26 +126,32 @@ function buildMessengerMessages({ reportsDir, configuredClusters, core }) {
* @param {RenderMessengerReportParams} params GitHub script dependencies.
* @returns {Promise<{
* message: string,
* threadMessages: string[]
* threadMessages: Array<{message: string, files: Array<Record<string, any>>}>
* }>} Rendered messages.
*/
async function renderMessengerReport({ core, reportsDir }) {
const config = readMessengerConfigFromEnv();
const { message, threadMessages } = buildMessengerMessages({
const { message, threadMessages } = await buildMessengerMessages({
reportsDir: reportsDir || config.reportsDir,
configuredClusters: config.configuredClusters,
core,
});

core.info(message);
core.setOutput("message", message);
core.setOutput("thread_messages", JSON.stringify(threadMessages));
core.setOutput(
"thread_messages",
JSON.stringify(threadMessages.map((threadMessage) => threadMessage.message))
);

if (config.loop) {
try {
await makeThreadedReportInLoop({ message, threadMessages, loop: config.loop }, core);
} catch (error) {
core.warning(`Unable to deliver report to Loop API: ${error.message}`);
if (config.loop.strictDelivery) {
throw error;
}
}
}

Expand Down
Loading
Loading