merge-steward 0.10.1 → 0.10.2
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/dist/watch/dashboard-model.js +47 -13
- package/package.json +1 -1
|
@@ -3,6 +3,39 @@ import { formatDuration, humanStatus, nextStepLabel, relativeTime, summarizeQueu
|
|
|
3
3
|
const RECENT_EVICTION_MS = 60 * 60 * 1_000;
|
|
4
4
|
const STUCK_ENTRY_MS = 25 * 60 * 1_000;
|
|
5
5
|
const OFFLINE_STALE_MS = 10 * 1_000;
|
|
6
|
+
function isLaterEntry(left, right) {
|
|
7
|
+
if (left.position !== right.position) {
|
|
8
|
+
return left.position > right.position;
|
|
9
|
+
}
|
|
10
|
+
return new Date(left.updatedAt).getTime() >= new Date(right.updatedAt).getTime();
|
|
11
|
+
}
|
|
12
|
+
function getLatestEntries(snapshot) {
|
|
13
|
+
if (!snapshot) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const byPR = new Map();
|
|
17
|
+
for (const entry of snapshot.entries) {
|
|
18
|
+
const existing = byPR.get(entry.prNumber);
|
|
19
|
+
if (!existing || isLaterEntry(entry, existing)) {
|
|
20
|
+
byPR.set(entry.prNumber, entry);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return [...byPR.values()].sort((a, b) => a.position - b.position);
|
|
24
|
+
}
|
|
25
|
+
function getMostRecentActivityAt(snapshot) {
|
|
26
|
+
const latestEntries = getLatestEntries(snapshot);
|
|
27
|
+
if (latestEntries.length === 0) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return latestEntries.reduce((latest, entry) => {
|
|
31
|
+
if (!latest) {
|
|
32
|
+
return entry.updatedAt;
|
|
33
|
+
}
|
|
34
|
+
return new Date(entry.updatedAt).getTime() > new Date(latest).getTime()
|
|
35
|
+
? entry.updatedAt
|
|
36
|
+
: latest;
|
|
37
|
+
}, undefined);
|
|
38
|
+
}
|
|
6
39
|
export function matchRepoRef(repo, repoRef) {
|
|
7
40
|
if (!repoRef) {
|
|
8
41
|
return false;
|
|
@@ -22,10 +55,7 @@ export function getChainEntries(snapshot) {
|
|
|
22
55
|
return buildChainEntries(snapshot.entries);
|
|
23
56
|
}
|
|
24
57
|
export function getActiveEntries(snapshot) {
|
|
25
|
-
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
return snapshot.entries.filter((entry) => (entry.status !== "merged" && entry.status !== "evicted" && entry.status !== "dequeued"));
|
|
58
|
+
return getLatestEntries(snapshot).filter((entry) => (entry.status !== "merged" && entry.status !== "evicted" && entry.status !== "dequeued"));
|
|
29
59
|
}
|
|
30
60
|
export function getDefaultEntryId(snapshot, filter, preferredPrNumber) {
|
|
31
61
|
if (!snapshot) {
|
|
@@ -81,7 +111,7 @@ export function getRepoHealth(repo, now = Date.now()) {
|
|
|
81
111
|
};
|
|
82
112
|
}
|
|
83
113
|
}
|
|
84
|
-
const recentEvicted = snapshot.
|
|
114
|
+
const recentEvicted = getLatestEntries(snapshot).find((entry) => (entry.status === "evicted"
|
|
85
115
|
&& now - new Date(entry.updatedAt).getTime() <= RECENT_EVICTION_MS));
|
|
86
116
|
if (recentEvicted) {
|
|
87
117
|
return {
|
|
@@ -106,7 +136,7 @@ export function getRepoHealth(repo, now = Date.now()) {
|
|
|
106
136
|
label: "Idle",
|
|
107
137
|
color: "green",
|
|
108
138
|
detail: snapshot.summary.total > 0
|
|
109
|
-
? `No active queue work right now. Last activity was ${relativeTime(snapshot
|
|
139
|
+
? `No active queue work right now. Last activity was ${relativeTime(getMostRecentActivityAt(snapshot))} ago.`
|
|
110
140
|
: "No pull requests are queued right now.",
|
|
111
141
|
};
|
|
112
142
|
}
|
|
@@ -143,19 +173,23 @@ export function projectStatsSummary(snapshot) {
|
|
|
143
173
|
if (!snapshot) {
|
|
144
174
|
return "No queue data yet.";
|
|
145
175
|
}
|
|
146
|
-
const
|
|
176
|
+
const latestEntries = getLatestEntries(snapshot);
|
|
147
177
|
const activeEntries = getActiveEntries(snapshot);
|
|
148
178
|
const avgWaitMs = activeEntries.length > 0
|
|
149
179
|
? activeEntries.reduce((sum, entry) => sum + (Date.now() - new Date(entry.enqueuedAt).getTime()), 0) / activeEntries.length
|
|
150
180
|
: 0;
|
|
181
|
+
const queued = latestEntries.filter((entry) => entry.status === "queued").length;
|
|
182
|
+
const validating = latestEntries.filter((entry) => entry.status === "validating" || entry.status === "preparing_head").length;
|
|
183
|
+
const merging = latestEntries.filter((entry) => entry.status === "merging").length;
|
|
184
|
+
const evicted = latestEntries.filter((entry) => entry.status === "evicted").length;
|
|
151
185
|
const parts = [
|
|
152
|
-
`${
|
|
153
|
-
`${
|
|
154
|
-
`${
|
|
155
|
-
`${
|
|
186
|
+
`${activeEntries.length} active`,
|
|
187
|
+
`${queued} waiting`,
|
|
188
|
+
`${validating} testing`,
|
|
189
|
+
`${merging} merging`,
|
|
156
190
|
];
|
|
157
|
-
if (
|
|
158
|
-
parts.push(`${
|
|
191
|
+
if (evicted > 0) {
|
|
192
|
+
parts.push(`${evicted} need repair`);
|
|
159
193
|
}
|
|
160
194
|
if (avgWaitMs > 0) {
|
|
161
195
|
parts.push(`avg wait ${formatDuration(avgWaitMs)}`);
|