patchrelay 0.32.2 → 0.32.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.32.2",
4
- "commit": "a1095c2643be",
5
- "builtAt": "2026-04-01T21:58:19.644Z"
3
+ "version": "0.32.3",
4
+ "commit": "fbdb9010e964",
5
+ "builtAt": "2026-04-01T22:29:47.921Z"
6
6
  }
@@ -59,6 +59,17 @@ function buildPrStatusSummary(issue, issueContext) {
59
59
  else if (checkState) {
60
60
  summary.push(checkState);
61
61
  }
62
+ if (issue.prChecksSummary?.total) {
63
+ if (issue.prChecksSummary.failed > 0) {
64
+ summary.push(`${issue.prChecksSummary.failed}/${issue.prChecksSummary.total} checks failing`);
65
+ }
66
+ else if (issue.prChecksSummary.pending > 0) {
67
+ summary.push(`${issue.prChecksSummary.completed}/${issue.prChecksSummary.total} checks settled`);
68
+ }
69
+ else {
70
+ summary.push(`${issue.prChecksSummary.passed}/${issue.prChecksSummary.total} checks passed`);
71
+ }
72
+ }
62
73
  if (reviewState) {
63
74
  summary.push(`review ${reviewState}`);
64
75
  }
@@ -86,22 +97,31 @@ function resolvePrimaryBlocker(issue, issueContext) {
86
97
  color: "yellow",
87
98
  };
88
99
  }
89
- if (issue.prCheckStatus === "failed") {
90
- const failedCheck = issueContext?.latestFailureCheckName ?? issue.latestFailureCheckName;
100
+ if (issue.prCheckStatus === "failed" || issue.prCheckStatus === "failure") {
101
+ const failedChecks = issue.prChecksSummary?.failedNames ?? [];
102
+ const failedCheck = issueContext?.latestFailureCheckName
103
+ ?? issue.latestFailureCheckName
104
+ ?? (failedChecks.length > 0 ? failedChecks.slice(0, 2).join(", ") : undefined);
91
105
  return {
92
106
  text: failedCheck ? `Blocked by failed check: ${failedCheck}` : "Blocked by failed PR checks",
93
107
  color: "red",
94
108
  };
95
109
  }
110
+ if (issue.prCheckStatus === "pending" || issue.prCheckStatus === "in_progress" || issue.prCheckStatus === "queued") {
111
+ return { text: "Waiting for PR checks to finish", color: "yellow" };
112
+ }
96
113
  if (issue.prReviewState === "changes_requested") {
97
114
  return { text: "Blocked by requested review changes", color: "yellow" };
98
115
  }
99
- if (issue.prNumber !== undefined && !issue.prReviewState && issue.factoryState !== "done") {
100
- return { text: "Blocked pending review approval", color: "yellow" };
116
+ if (issue.factoryState === "repairing_queue") {
117
+ return { text: "Blocked by merge queue refresh failure", color: "yellow" };
101
118
  }
102
119
  if (issue.factoryState === "awaiting_queue") {
103
120
  return { text: "Waiting in merge queue", color: "yellow" };
104
121
  }
122
+ if (issue.prNumber !== undefined && !issue.prReviewState && issue.factoryState !== "done") {
123
+ return { text: "Blocked pending review approval", color: "yellow" };
124
+ }
105
125
  return null;
106
126
  }
107
127
  function ElapsedTime({ startedAt }) {
@@ -148,10 +148,10 @@ function buildChecksProgressChip(issue) {
148
148
  if (!summary || summary.total <= 0)
149
149
  return null;
150
150
  const text = summary.failed > 0
151
- ? `checks ${summary.completed}/${summary.total} failed`
151
+ ? `checks ${summary.failed}/${summary.total} failed`
152
152
  : summary.pending > 0
153
- ? `checks ${summary.completed}/${summary.total} running`
154
- : `checks ${summary.completed}/${summary.total} passed`;
153
+ ? `checks ${summary.completed}/${summary.total} settled`
154
+ : `checks ${summary.passed}/${summary.total} passed`;
155
155
  const color = summary.failed > 0 ? "red" : summary.pending > 0 ? "yellow" : "green";
156
156
  return { text, color };
157
157
  }
@@ -181,22 +181,31 @@ function buildPrimaryBlocker(issue) {
181
181
  color: "yellow",
182
182
  };
183
183
  }
184
- if (issue.prCheckStatus === "failed") {
185
- const failedCheck = issue.latestFailureCheckName ?? "PR checks";
184
+ if (issue.prCheckStatus === "failed" || issue.prCheckStatus === "failure") {
185
+ const failedChecks = issue.prChecksSummary?.failedNames ?? [];
186
+ const failedCheck = issue.latestFailureCheckName
187
+ ?? (failedChecks.length > 0 ? failedChecks.slice(0, 2).join(", ") : undefined)
188
+ ?? "PR checks";
186
189
  return {
187
190
  text: `${failedCheck} failed`,
188
191
  color: "red",
189
192
  };
190
193
  }
194
+ if (issue.prCheckStatus === "pending" || issue.prCheckStatus === "in_progress" || issue.prCheckStatus === "queued") {
195
+ return {
196
+ text: "Waiting for PR checks to finish",
197
+ color: "yellow",
198
+ };
199
+ }
191
200
  if (issue.prReviewState === "changes_requested") {
192
201
  return {
193
202
  text: "Review changes requested",
194
203
  color: "yellow",
195
204
  };
196
205
  }
197
- if (issue.prNumber !== undefined && !issue.prReviewState && issue.factoryState !== "done") {
206
+ if (issue.factoryState === "repairing_queue") {
198
207
  return {
199
- text: "Waiting for review approval",
208
+ text: "Merge queue reported a branch refresh failure",
200
209
  color: "yellow",
201
210
  };
202
211
  }
@@ -206,6 +215,12 @@ function buildPrimaryBlocker(issue) {
206
215
  color: "yellow",
207
216
  };
208
217
  }
218
+ if (issue.prNumber !== undefined && !issue.prReviewState && issue.factoryState !== "done") {
219
+ return {
220
+ text: "Waiting for review approval",
221
+ color: "yellow",
222
+ };
223
+ }
209
224
  return null;
210
225
  }
211
226
  function buildPipelineProgress(issue) {
package/dist/service.js CHANGED
@@ -35,22 +35,26 @@ function extractStatusNote(summaryJson, reportJson) {
35
35
  }
36
36
  return undefined;
37
37
  }
38
- function parseCiSnapshotSummary(snapshotJson) {
38
+ export function parseCiSnapshotSummary(snapshotJson) {
39
39
  if (!snapshotJson)
40
40
  return undefined;
41
41
  try {
42
42
  const snapshot = JSON.parse(snapshotJson);
43
- const checks = Array.isArray(snapshot.checks) ? snapshot.checks : [];
43
+ const rawChecks = Array.isArray(snapshot.checks) ? snapshot.checks : [];
44
+ const checks = collapseEffectiveChecks(rawChecks);
44
45
  if (checks.length === 0)
45
46
  return undefined;
46
47
  let passed = 0;
47
48
  let failed = 0;
48
49
  let pending = 0;
50
+ const failedNames = [];
49
51
  for (const check of checks) {
50
52
  if (check.status === "success")
51
53
  passed++;
52
- else if (check.status === "failure")
54
+ else if (check.status === "failure") {
53
55
  failed++;
56
+ failedNames.push(check.name);
57
+ }
54
58
  else
55
59
  pending++;
56
60
  }
@@ -61,12 +65,23 @@ function parseCiSnapshotSummary(snapshotJson) {
61
65
  failed,
62
66
  pending,
63
67
  overall: snapshot.gateCheckStatus,
68
+ ...(failedNames.length > 0 ? { failedNames } : {}),
64
69
  };
65
70
  }
66
71
  catch {
67
72
  return undefined;
68
73
  }
69
74
  }
75
+ function collapseEffectiveChecks(checks) {
76
+ const effective = new Map();
77
+ for (const check of checks) {
78
+ const name = typeof check?.name === "string" ? check.name.trim() : "";
79
+ if (!name || effective.has(name))
80
+ continue;
81
+ effective.set(name, check);
82
+ }
83
+ return [...effective.values()];
84
+ }
70
85
  export class PatchRelayService {
71
86
  config;
72
87
  db;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.32.2",
3
+ "version": "0.32.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {