fix: beta resolver typecheck + build smoke check (#19060)
parent
71693cc24b
commit
9a64bdb539
108
script/beta.ts
108
script/beta.ts
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import { $ } from "bun"
|
||||
|
||||
const model = "opencode/gpt-5.3-codex"
|
||||
|
||||
interface PR {
|
||||
number: number
|
||||
title: string
|
||||
|
|
@ -50,20 +52,35 @@ async function cleanup() {
|
|||
} catch {}
|
||||
}
|
||||
|
||||
function lines(prs: PR[]) {
|
||||
return prs.map((x) => `- #${x.number}: ${x.title}`).join("\n") || "(none)"
|
||||
}
|
||||
|
||||
async function typecheck() {
|
||||
try {
|
||||
await $`bun typecheck`.cwd("packages/opencode")
|
||||
return true
|
||||
} catch (err) {
|
||||
console.log(`Typecheck failed: ${err}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function build() {
|
||||
try {
|
||||
await $`./script/build.ts --single`.cwd("packages/opencode")
|
||||
return true
|
||||
} catch (err) {
|
||||
console.log(`Build failed: ${err}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function fix(pr: PR, files: string[], prs: PR[], applied: number[], idx: number) {
|
||||
console.log(` Trying to auto-resolve ${files.length} conflict(s) with opencode...`)
|
||||
|
||||
const done =
|
||||
prs
|
||||
.filter((x) => applied.includes(x.number))
|
||||
.map((x) => `- #${x.number}: ${x.title}`)
|
||||
.join("\n") || "(none yet)"
|
||||
|
||||
const next =
|
||||
prs
|
||||
.slice(idx + 1)
|
||||
.map((x) => `- #${x.number}: ${x.title}`)
|
||||
.join("\n") || "(none)"
|
||||
const done = lines(prs.filter((x) => applied.includes(x.number)))
|
||||
const next = lines(prs.slice(idx + 1))
|
||||
|
||||
const prompt = [
|
||||
`Resolve the current git merge conflicts while merging PR #${pr.number} into the beta branch.`,
|
||||
|
|
@ -76,12 +93,14 @@ async function fix(pr: PR, files: string[], prs: PR[], applied: number[], idx: n
|
|||
"Prefer already-merged PRs over the base branch when resolving stacked conflicts.",
|
||||
"If a PR already deleted a file/directory, do not re-add it, instead apply changes in the new semantic location.",
|
||||
"If a PR already changed an import, keep that change.",
|
||||
"After resolving the conflicts, run `bun typecheck` in `packages/opencode`.",
|
||||
"Fix any merge-caused typecheck errors before finishing.",
|
||||
"Keep the merge in progress, do not abort the merge, and do not create a commit.",
|
||||
"When done, leave the working tree with no unmerged files.",
|
||||
"When done, leave the working tree with no unmerged files and a passing typecheck.",
|
||||
].join("\n")
|
||||
|
||||
try {
|
||||
await $`opencode run -m opencode/gpt-5.3-codex ${prompt}`
|
||||
await $`opencode run -m ${model} ${prompt}`
|
||||
} catch (err) {
|
||||
console.log(` opencode failed: ${err}`)
|
||||
return false
|
||||
|
|
@ -93,10 +112,66 @@ async function fix(pr: PR, files: string[], prs: PR[], applied: number[], idx: n
|
|||
return false
|
||||
}
|
||||
|
||||
if (!(await typecheck())) return false
|
||||
|
||||
console.log(" Conflicts resolved with opencode")
|
||||
return true
|
||||
}
|
||||
|
||||
async function smoke(prs: PR[], applied: number[]) {
|
||||
console.log("\nRunning final smoke check with opencode...")
|
||||
|
||||
const done = lines(prs.filter((x) => applied.includes(x.number)))
|
||||
const prompt = [
|
||||
"The beta merge batch is complete.",
|
||||
`Merged PRs on HEAD:\n${done}`,
|
||||
"Run `bun typecheck` in `packages/opencode`.",
|
||||
"Run `./script/build.ts --single` in `packages/opencode`.",
|
||||
"Fix any merge-caused issues until both commands pass.",
|
||||
"Do not create a commit.",
|
||||
].join("\n")
|
||||
|
||||
try {
|
||||
await $`opencode run -m ${model} ${prompt}`
|
||||
} catch (err) {
|
||||
console.log(`Smoke fix failed: ${err}`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!(await typecheck())) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!(await build())) {
|
||||
return false
|
||||
}
|
||||
|
||||
const out = await $`git status --porcelain`.text()
|
||||
if (!out.trim()) {
|
||||
console.log("Smoke check passed")
|
||||
return true
|
||||
}
|
||||
|
||||
try {
|
||||
await $`git add -A`
|
||||
await $`git commit -m "Fix beta integration"`
|
||||
} catch (err) {
|
||||
console.log(`Failed to commit smoke fixes: ${err}`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!(await typecheck())) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!(await build())) {
|
||||
return false
|
||||
}
|
||||
|
||||
console.log("Smoke check passed")
|
||||
return true
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("Fetching open PRs with beta label...")
|
||||
|
||||
|
|
@ -195,6 +270,13 @@ async function main() {
|
|||
throw new Error(`${failed.length} PR(s) failed to merge`)
|
||||
}
|
||||
|
||||
if (applied.length > 0) {
|
||||
const ok = await smoke(prs, applied)
|
||||
if (!ok) {
|
||||
throw new Error("Final smoke check failed")
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\nChecking if beta branch has changes...")
|
||||
await $`git fetch origin beta`
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue