opencode-magi 0.0.0-dev-20260722060754 → 0.0.0-dev-20260722111427
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.
|
@@ -52,6 +52,14 @@ export const MergeQueueStatusDocument = gql `
|
|
|
52
52
|
mergeQueueEntry {
|
|
53
53
|
id
|
|
54
54
|
}
|
|
55
|
+
timelineItems(last: 1, itemTypes: REMOVED_FROM_MERGE_QUEUE_EVENT) {
|
|
56
|
+
nodes {
|
|
57
|
+
... on RemovedFromMergeQueueEvent {
|
|
58
|
+
createdAt
|
|
59
|
+
reason
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
}
|
|
@@ -232,9 +232,10 @@ export async function automate() {
|
|
|
232
232
|
if (action === "merge" && this.config.review.merge.queue) {
|
|
233
233
|
const octokit = await this.magi.createOctokit(this.config, this.context.abort, account);
|
|
234
234
|
const graphql = this.magi.createGraphql(octokit);
|
|
235
|
+
const enqueuedAt = new Date().toISOString();
|
|
235
236
|
await graphql.enqueuePullRequest({ id: this.state.pr.metadata.node_id });
|
|
236
237
|
await this.updateEvent(`Waiting for merge queue.`);
|
|
237
|
-
const result = await waitMergeQueue.call(this);
|
|
238
|
+
const result = await waitMergeQueue.call(this, enqueuedAt);
|
|
238
239
|
if (result === "CONFLICT")
|
|
239
240
|
return result;
|
|
240
241
|
}
|
|
@@ -358,8 +359,10 @@ function getCheckTime(check) {
|
|
|
358
359
|
return Number.isNaN(time) ? prev : Math.max(prev, time);
|
|
359
360
|
}, 0);
|
|
360
361
|
}
|
|
361
|
-
async function waitMergeQueue(leftMergeQueue = false) {
|
|
362
|
+
async function waitMergeQueue(enqueuedAt, leftMergeQueue = false, retries = 0) {
|
|
362
363
|
this.context.abort.throwIfAborted();
|
|
364
|
+
if (!this.state.pr?.metadata)
|
|
365
|
+
throw new MagiError("blocked", "PR metadata not found.");
|
|
363
366
|
const { repository } = await this.graphql.mergeQueueStatus({
|
|
364
367
|
owner: this.config.github.owner,
|
|
365
368
|
pr: this.number,
|
|
@@ -367,20 +370,33 @@ async function waitMergeQueue(leftMergeQueue = false) {
|
|
|
367
370
|
});
|
|
368
371
|
if (!repository?.pullRequest)
|
|
369
372
|
throw new MagiError("blocked", "Could not fetch merge queue status.");
|
|
370
|
-
const { isInMergeQueue, mergeQueueEntry, state } = repository.pullRequest;
|
|
373
|
+
const { isInMergeQueue, mergeQueueEntry, state, timelineItems } = repository.pullRequest;
|
|
371
374
|
if (state === "MERGED")
|
|
372
375
|
return "MERGED";
|
|
373
376
|
const nextLeftMergeQueue = state === "OPEN" && !isInMergeQueue && !mergeQueueEntry;
|
|
374
377
|
if (leftMergeQueue && nextLeftMergeQueue) {
|
|
375
378
|
if (await isConflict.call(this)) {
|
|
376
379
|
await this.updateState({ pr: { automation: "CONFLICT" } });
|
|
377
|
-
await this.updateEvent(
|
|
380
|
+
await this.updateEvent("Merge automation found conflicts.");
|
|
378
381
|
return "CONFLICT";
|
|
379
382
|
}
|
|
383
|
+
const removedFromQueue = timelineItems.nodes?.at(-1);
|
|
384
|
+
if (removedFromQueue?.reason === "failed_checks" &&
|
|
385
|
+
Date.parse(removedFromQueue.createdAt) >= Date.parse(enqueuedAt)) {
|
|
386
|
+
if (retries >= this.config.review.checks.retryFailedJobs)
|
|
387
|
+
throw new MagiError("blocked", `PR left the merge queue after failed checks exceeded ${retries} retries.`);
|
|
388
|
+
const attempt = retries + 1;
|
|
389
|
+
const nextEnqueuedAt = new Date().toISOString();
|
|
390
|
+
await this.updateEvent(`Attempt ${attempt} failed to merge from the merge queue. Retrying...`);
|
|
391
|
+
await this.graphql.enqueuePullRequest({
|
|
392
|
+
id: this.state.pr.metadata.node_id,
|
|
393
|
+
});
|
|
394
|
+
return await waitMergeQueue.call(this, nextEnqueuedAt, false, attempt);
|
|
395
|
+
}
|
|
380
396
|
throw new MagiError("blocked", `PR left the merge queue before merging.`);
|
|
381
397
|
}
|
|
382
398
|
await wait(30_000, this.context.abort);
|
|
383
|
-
return await waitMergeQueue.call(this, nextLeftMergeQueue);
|
|
399
|
+
return await waitMergeQueue.call(this, enqueuedAt, nextLeftMergeQueue, retries);
|
|
384
400
|
}
|
|
385
401
|
async function isConflict() {
|
|
386
402
|
if (!this.state.worktree)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-magi",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260722111427",
|
|
4
4
|
"description": "Multi-agent PR review and merge orchestration plugin for OpenCode.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Hirotomo Yamada <hirotomo.yamada@avap.co.jp>",
|