@link-assistant/hive-mind 1.35.7 → 1.35.8
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/CHANGELOG.md +9 -0
- package/package.json +1 -1
- package/src/solve.auto-pr.lib.mjs +47 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.35.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ca57154: fix: add retry with exponential backoff for PR verification after creation (Issue #1468)
|
|
8
|
+
- Add retry logic with exponential backoff (up to 5 attempts: 2s, 4s, 6s, 8s, 10s) to PR verification step in solve.auto-pr.lib.mjs to handle GitHub API eventual consistency
|
|
9
|
+
- Add case study with timeline reconstruction and root cause analysis
|
|
10
|
+
- Add 11 unit tests covering retry behavior, backoff timing, and edge cases
|
|
11
|
+
|
|
3
12
|
## 1.35.7
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1203,33 +1203,59 @@ ${prBody}`,
|
|
|
1203
1203
|
|
|
1204
1204
|
// CRITICAL: Verify the PR was actually created by querying GitHub API
|
|
1205
1205
|
// This is essential because gh pr create can return a URL but PR creation might have failed
|
|
1206
|
+
// Issue #1468: Use retry with exponential backoff because GitHub's API is eventually
|
|
1207
|
+
// consistent — a newly created PR may not be visible via gh pr view for several seconds.
|
|
1208
|
+
// This matches the existing retry pattern used for the compare API (lines 571-624).
|
|
1206
1209
|
await log(formatAligned('🔍', 'Verifying:', 'PR creation...'), { verbose: true });
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1210
|
+
|
|
1211
|
+
let prVerified = false;
|
|
1212
|
+
let verifyAttempts = 0;
|
|
1213
|
+
const maxVerifyAttempts = 5;
|
|
1214
|
+
let lastVerifyResult = null;
|
|
1215
|
+
|
|
1216
|
+
while (!prVerified && verifyAttempts < maxVerifyAttempts) {
|
|
1217
|
+
verifyAttempts++;
|
|
1218
|
+
const waitTime = Math.min(2000 * verifyAttempts, 10000); // 2s, 4s, 6s, 8s, 10s
|
|
1219
|
+
|
|
1220
|
+
if (verifyAttempts > 1) {
|
|
1221
|
+
await log(` Retry ${verifyAttempts}/${maxVerifyAttempts}: Waiting ${waitTime}ms for GitHub to propagate PR...`);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
1225
|
+
|
|
1226
|
+
lastVerifyResult = await $({
|
|
1227
|
+
silent: true,
|
|
1228
|
+
})`gh pr view ${localPrNumber} --repo ${owner}/${repo} --json number,url,state 2>&1`;
|
|
1229
|
+
|
|
1230
|
+
if (lastVerifyResult.code === 0) {
|
|
1231
|
+
try {
|
|
1232
|
+
const prData = JSON.parse(lastVerifyResult.stdout.toString().trim());
|
|
1233
|
+
if (prData.number && prData.url) {
|
|
1234
|
+
await log(formatAligned('✅', 'Verification:', `PR exists on GitHub (attempt ${verifyAttempts}/${maxVerifyAttempts})`), { verbose: true });
|
|
1235
|
+
// Update prUrl and localPrNumber from verified data
|
|
1236
|
+
prUrl = prData.url;
|
|
1237
|
+
localPrNumber = String(prData.number);
|
|
1238
|
+
prVerified = true;
|
|
1239
|
+
}
|
|
1240
|
+
} catch {
|
|
1241
|
+
// Parse failed, will retry
|
|
1242
|
+
if (argv.verbose) {
|
|
1243
|
+
await log(` Verify attempt ${verifyAttempts}: Could not parse PR data, retrying...`, { verbose: true });
|
|
1244
|
+
}
|
|
1221
1245
|
}
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1246
|
+
} else if (argv.verbose) {
|
|
1247
|
+
const attemptStderr = lastVerifyResult.stderr ? lastVerifyResult.stderr.toString().trim() : '';
|
|
1248
|
+
await log(` Verify attempt ${verifyAttempts}: PR not found yet${attemptStderr ? ` (${attemptStderr})` : ''}`, { verbose: true });
|
|
1225
1249
|
}
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
if (!prVerified) {
|
|
1253
|
+
// PR does not exist after all retries - gh pr create must have failed silently
|
|
1228
1254
|
// Issue #1462: Include gh pr create stderr for root cause diagnosis
|
|
1229
|
-
const verifyStderr =
|
|
1255
|
+
const verifyStderr = lastVerifyResult && lastVerifyResult.stderr ? lastVerifyResult.stderr.toString().trim() : '';
|
|
1230
1256
|
const stderrInfo = prCreateStderr ? ` (gh pr create stderr: ${prCreateStderr.trim()})` : '';
|
|
1231
1257
|
const verifyInfo = verifyStderr ? ` (gh pr view stderr: ${verifyStderr})` : '';
|
|
1232
|
-
throw new Error(`PR verification failed - gh pr create returned URL "${prUrl}" but PR #${localPrNumber} does not exist on GitHub${stderrInfo}${verifyInfo}`);
|
|
1258
|
+
throw new Error(`PR verification failed - gh pr create returned URL "${prUrl}" but PR #${localPrNumber} does not exist on GitHub after ${maxVerifyAttempts} verification attempts${stderrInfo}${verifyInfo}`);
|
|
1233
1259
|
}
|
|
1234
1260
|
// Store PR info globally for error handlers
|
|
1235
1261
|
global.createdPR = { number: localPrNumber, url: prUrl };
|