Browse Source

fix: beta resolver typecheck + build smoke check (#19060)

Luke Parker 3 weeks ago
parent
commit
9a64bdb539
1 changed files with 95 additions and 13 deletions
  1. 95 13
      script/beta.ts

+ 95 - 13
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`