@@ -81,6 +81,39 @@ async function build() {
8181 }
8282}
8383
84+ async function validate ( ) {
85+ if ( ! ( await typecheck ( ) ) ) return false
86+ if ( ! ( await build ( ) ) ) return false
87+ return true
88+ }
89+
90+ async function commitSmokeChanges ( ) {
91+ const out = await $ `git status --porcelain` . text ( )
92+ if ( ! out . trim ( ) ) {
93+ console . log ( "Smoke check passed" )
94+ return true
95+ }
96+
97+ try {
98+ await $ `git add -A`
99+ await $ `git commit -m "Fix beta integration"`
100+ } catch ( err ) {
101+ console . log ( `Failed to commit smoke fixes: ${ err } ` )
102+ return false
103+ }
104+
105+ if ( ! ( await validate ( ) ) ) return false
106+
107+ const left = await $ `git status --porcelain` . text ( )
108+ if ( ! left . trim ( ) ) {
109+ console . log ( "Smoke check passed" )
110+ return true
111+ }
112+
113+ console . log ( `Smoke check left uncommitted changes:\n${ left } ` )
114+ return false
115+ }
116+
84117async function install ( ) {
85118 console . log ( " Regenerating bun.lock..." )
86119
@@ -143,11 +176,15 @@ async function fix(pr: PR, files: string[], prs: PR[], applied: number[], idx: n
143176}
144177
145178async function smoke ( prs : PR [ ] , applied : number [ ] ) {
146- console . log ( "\nRunning final smoke check with opencode..." )
179+ console . log ( "\nRunning final smoke check..." )
180+
181+ if ( await validate ( ) ) return commitSmokeChanges ( )
182+
183+ console . log ( "\nTrying to fix final smoke check with opencode..." )
147184
148185 const done = lines ( prs . filter ( ( x ) => applied . includes ( x . number ) ) )
149186 const prompt = [
150- "The beta merge batch is complete." ,
187+ "The beta merge batch is complete, but the deterministic final smoke check failed ." ,
151188 `Merged PRs on HEAD:\n${ done } ` ,
152189 "Run `bun typecheck` at the repo root." ,
153190 "Run `./script/build.ts --single` in `packages/opencode`." ,
@@ -162,38 +199,8 @@ async function smoke(prs: PR[], applied: number[]) {
162199 return false
163200 }
164201
165- if ( ! ( await typecheck ( ) ) ) {
166- return false
167- }
168-
169- if ( ! ( await build ( ) ) ) {
170- return false
171- }
172-
173- const out = await $ `git status --porcelain` . text ( )
174- if ( ! out . trim ( ) ) {
175- console . log ( "Smoke check passed" )
176- return true
177- }
178-
179- try {
180- await $ `git add -A`
181- await $ `git commit -m "Fix beta integration"`
182- } catch ( err ) {
183- console . log ( `Failed to commit smoke fixes: ${ err } ` )
184- return false
185- }
186-
187- if ( ! ( await typecheck ( ) ) ) {
188- return false
189- }
190-
191- if ( ! ( await build ( ) ) ) {
192- return false
193- }
194-
195- console . log ( "Smoke check passed" )
196- return true
202+ if ( ! ( await validate ( ) ) ) return false
203+ return commitSmokeChanges ( )
197204}
198205
199206async function main ( ) {
@@ -294,17 +301,13 @@ async function main() {
294301 throw new Error ( `${ failed . length } PR(s) failed to merge` )
295302 }
296303
297- if ( applied . length > 0 ) {
298- console . log ( "\nSkipping final smoke check" )
299- }
300-
301304 console . log ( "\nChecking if beta branch has changes..." )
302305 await $ `git fetch origin beta`
303306
304- const localTree = await $ `git rev-parse beta^{tree}` . text ( )
307+ const localTree = ( await $ `git rev-parse beta^{tree}` . text ( ) ) . trim ( )
305308 const remoteTrees = ( await $ `git log origin/dev..origin/beta --format=%T` . text ( ) ) . split ( "\n" )
306309
307- const matchIdx = remoteTrees . indexOf ( localTree . trim ( ) )
310+ const matchIdx = remoteTrees . indexOf ( localTree )
308311 if ( matchIdx !== - 1 ) {
309312 if ( matchIdx !== 0 ) {
310313 console . log ( `Beta branch contains this sync, but additional commits exist after it. Leaving beta branch as is.` )
@@ -314,7 +317,23 @@ async function main() {
314317 return
315318 }
316319
317- console . log ( "Force pushing beta branch..." )
320+ if ( ! ( await smoke ( prs , applied ) ) ) throw new Error ( "Final smoke check failed" )
321+
322+ await $ `git fetch origin beta`
323+
324+ const validatedTree = ( await $ `git rev-parse beta^{tree}` . text ( ) ) . trim ( )
325+ const remoteTreesAfterSmoke = ( await $ `git log origin/dev..origin/beta --format=%T` . text ( ) ) . split ( "\n" )
326+ const matchIdxAfterSmoke = remoteTreesAfterSmoke . indexOf ( validatedTree )
327+ if ( matchIdxAfterSmoke !== - 1 ) {
328+ if ( matchIdxAfterSmoke !== 0 ) {
329+ console . log ( `Beta branch contains this validated sync, but additional commits exist after it. Leaving beta branch as is.` )
330+ } else {
331+ console . log ( "Validated beta branch now matches remote contents, no push needed" )
332+ }
333+ return
334+ }
335+
336+ console . log ( "Force pushing validated beta branch..." )
318337 await $ `git push origin beta --force --no-verify`
319338
320339 console . log ( "Successfully synced beta branch" )
0 commit comments