also looking at this
fix(ci): give the repair loop the guard it already had
#1407
10 files
+229
-34
| @@ -3,7 +3,7 @@ | ||
| 3 | 3 | import type { GitProvider } from '../src/git/provider' |
| 4 | 4 | import type { ReviewFinding } from '../src/review/findings' |
| 5 | 5 | import type { ReviewFormat } from '../src/review/local' |
| 6 | import type { BuddyConfig } from '../src/types' | |
| 6 | import type { BuddyConfig, PullRequest } from '../src/types' | |
| 7 | 7 | import fs from 'node:fs' |
| 8 | 8 | import process from 'node:process' |
| 9 | 9 | import { CLI } from '@stacksjs/clapp' |
| @@ -1354,10 +1354,22 @@ cli | ||
| 1354 | 1354 | } |
| 1355 | 1355 | |
| 1356 | 1356 | const { attemptFix } = await import('../src/ci') |
| 1357 | const { parseFixAttempts, upsertFixAttempts } = await import('../src/ci/attempts') | |
| 1357 | 1358 | const { createAiClient } = await import('../src/ai') |
| 1358 | 1359 | |
| 1360 | // The guard in attemptFix can only stop a loop if it is told how many | |
| 1361 | // attempts came before, and a CI job remembers nothing between runs. | |
| 1362 | const prNumber = options.pr ? Number.parseInt(options.pr, 10) : undefined | |
| 1363 | let pullRequest: PullRequest | undefined | |
| 1364 | if (prNumber) { | |
| 1365 | const open = await provider.getPullRequests('open') | |
| 1366 | pullRequest = open.find(candidate => candidate.number === prNumber) | |
| 1367 | } | |
| 1368 | const priorAttempts = parseFixAttempts(pullRequest?.body)?.attempts ?? 0 | |
| 1369 | ||
| 1359 | 1370 | const outcome = await attemptFix({ |
| 1360 | 1371 | log, |
| 1372 | priorAttempts, | |
| 1361 | 1373 | workspace: process.cwd(), |
| 1362 | 1374 | baseBranch: config.repository?.baseBranch ?? 'main', |
| 1363 | 1375 | ai: createAiClient(config, logger), |
| @@ -1384,10 +1396,23 @@ cli | ||
| 1384 | 1396 | |
| 1385 | 1397 | logger.info(`\n${outcome.report}\n`) |
| 1386 | 1398 | |
| 1387 | const prNumber = options.pr ? Number.parseInt(options.pr, 10) : undefined | |
| 1388 | if (prNumber && !options.dryRun) | |
| 1399 | if (prNumber && !options.dryRun) { | |
| 1389 | 1400 | await provider.createComment(prNumber, outcome.report) |
| 1390 | 1401 | |
| 1402 | // Only a real attempt counts. Recording the ones the guard already | |
| 1403 | // refused would march the counter up without anything being tried. | |
| 1404 | if (outcome.action !== 'skipped' && pullRequest) { | |
| 1405 | try { | |
| 1406 | await provider.updatePullRequest(prNumber, { | |
| 1407 | body: upsertFixAttempts(pullRequest.body, priorAttempts + 1), | |
| 1408 | }) | |
| 1409 | } | |
| 1410 | catch (error) { | |
| 1411 | logger.warn(`Could not record the fix attempt on PR #${prNumber}: ${error instanceof Error ? error.message : String(error)}`) | |
| 1412 | } | |
| 1413 | } | |
| 1414 | } | |
| 1415 | ||
| 1391 | 1416 | logger.success(`✅ ${outcome.action}${outcome.fixed ? ' (fixed)' : ''}`) |
| 1392 | 1417 | } |
| 1393 | 1418 | catch (error) { |