mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:00:44 +00:00
ci: remove runner caps after timing review
This commit is contained in:
@@ -70,6 +70,28 @@ function getLatestCiRunId() {
|
||||
return String(runId);
|
||||
}
|
||||
|
||||
function listRecentSuccessfulCiRuns(limit) {
|
||||
const raw = execFileSync(
|
||||
"gh",
|
||||
[
|
||||
"run",
|
||||
"list",
|
||||
"--branch",
|
||||
"main",
|
||||
"--workflow",
|
||||
"CI",
|
||||
"--limit",
|
||||
String(Math.max(limit * 4, limit)),
|
||||
"--json",
|
||||
"databaseId,headSha,status,conclusion",
|
||||
],
|
||||
{ encoding: "utf8" },
|
||||
);
|
||||
return JSON.parse(raw)
|
||||
.filter((run) => run.status === "completed" && run.conclusion === "success")
|
||||
.slice(0, limit);
|
||||
}
|
||||
|
||||
function loadRun(runId) {
|
||||
return JSON.parse(
|
||||
execFileSync(
|
||||
@@ -82,6 +104,62 @@ function loadRun(runId) {
|
||||
);
|
||||
}
|
||||
|
||||
function summarizeJobs(run) {
|
||||
const created = parseTime(run.createdAt);
|
||||
const updated = parseTime(run.updatedAt);
|
||||
const jobs = (run.jobs ?? [])
|
||||
.filter((job) => !job.name?.startsWith("matrix."))
|
||||
.map((job) => {
|
||||
const started = parseTime(job.startedAt);
|
||||
const completed = parseTime(job.completedAt);
|
||||
return {
|
||||
conclusion: job.conclusion ?? "",
|
||||
durationSeconds: secondsBetween(started, completed),
|
||||
name: job.name,
|
||||
queueSeconds: secondsBetween(created, started),
|
||||
started,
|
||||
completed,
|
||||
status: job.status,
|
||||
};
|
||||
})
|
||||
.filter((job) => job.started !== null && job.completed !== null);
|
||||
const successfulDurations = jobs
|
||||
.filter((job) => job.status === "completed" && job.conclusion === "success")
|
||||
.map((job) => job.durationSeconds)
|
||||
.filter((duration) => duration !== null);
|
||||
const firstStart = Math.min(...jobs.map((job) => job.started));
|
||||
const lastComplete = Math.max(...jobs.map((job) => job.completed));
|
||||
|
||||
return {
|
||||
avgDurationSeconds:
|
||||
successfulDurations.length === 0
|
||||
? null
|
||||
: Math.round(
|
||||
successfulDurations.reduce((sum, duration) => sum + duration, 0) /
|
||||
successfulDurations.length,
|
||||
),
|
||||
executionWindowSeconds:
|
||||
Number.isFinite(firstStart) && Number.isFinite(lastComplete)
|
||||
? secondsBetween(firstStart, lastComplete)
|
||||
: null,
|
||||
firstQueueSeconds: Number.isFinite(firstStart) ? secondsBetween(created, firstStart) : null,
|
||||
jobCount: successfulDurations.length,
|
||||
maxDurationSeconds: successfulDurations.length === 0 ? null : Math.max(...successfulDurations),
|
||||
p90DurationSeconds: percentile(successfulDurations, 0.9),
|
||||
p95DurationSeconds: percentile(successfulDurations, 0.95),
|
||||
wallSeconds: secondsBetween(created, updated),
|
||||
};
|
||||
}
|
||||
|
||||
function percentile(values, percentileValue) {
|
||||
if (values.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const sorted = [...values].toSorted((left, right) => left - right);
|
||||
const index = Math.min(sorted.length - 1, Math.ceil(sorted.length * percentileValue) - 1);
|
||||
return sorted[index];
|
||||
}
|
||||
|
||||
function printSection(title, jobs, metric) {
|
||||
console.log(title);
|
||||
for (const job of jobs) {
|
||||
@@ -93,12 +171,39 @@ function printSection(title, jobs, metric) {
|
||||
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const recentIndex = args.indexOf("--recent");
|
||||
const limitIndex = args.indexOf("--limit");
|
||||
const limit =
|
||||
limitIndex === -1 ? 15 : Math.max(1, Number.parseInt(args[limitIndex + 1] ?? "", 10) || 15);
|
||||
if (recentIndex !== -1) {
|
||||
const recentLimit = Math.max(1, Number.parseInt(args[recentIndex + 1] ?? "", 10) || 10);
|
||||
for (const run of listRecentSuccessfulCiRuns(recentLimit)) {
|
||||
const summary = summarizeJobs(loadRun(run.databaseId));
|
||||
console.log(
|
||||
[
|
||||
`CI run ${run.databaseId}`,
|
||||
run.headSha.slice(0, 10),
|
||||
`wall=${formatSeconds(summary.wallSeconds)}`,
|
||||
`exec=${formatSeconds(summary.executionWindowSeconds)}`,
|
||||
`firstQueue=${formatSeconds(summary.firstQueueSeconds)}`,
|
||||
`jobs=${summary.jobCount}`,
|
||||
`avg=${formatSeconds(summary.avgDurationSeconds)}`,
|
||||
`p90=${formatSeconds(summary.p90DurationSeconds)}`,
|
||||
`p95=${formatSeconds(summary.p95DurationSeconds)}`,
|
||||
`max=${formatSeconds(summary.maxDurationSeconds)}`,
|
||||
].join(" "),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const runId =
|
||||
args.find((arg, index) => index !== limitIndex && index !== limitIndex + 1) ??
|
||||
getLatestCiRunId();
|
||||
args.find(
|
||||
(arg, index) =>
|
||||
index !== limitIndex &&
|
||||
index !== limitIndex + 1 &&
|
||||
index !== recentIndex &&
|
||||
index !== recentIndex + 1,
|
||||
) ?? getLatestCiRunId();
|
||||
const summary = summarizeRunTimings(loadRun(runId), limit);
|
||||
|
||||
console.log(
|
||||
|
||||
Reference in New Issue
Block a user