22
33interface PR {
44 number : number
5- headRefName : string
6- headRefOid : string
7- createdAt : string
8- isDraft : boolean
95 title : string
106}
117
128async function main ( ) {
139 console . log ( "Fetching open contributor PRs..." )
1410
15- const prsResult =
16- await $ `gh pr list --label contributor --state open --json number,headRefName,headRefOid,createdAt,isDraft,title --limit 100` . nothrow ( )
11+ const prsResult = await $ `gh pr list --label contributor --state open --json number,title --limit 100` . nothrow ( )
1712 if ( prsResult . exitCode !== 0 ) {
1813 throw new Error ( `Failed to fetch PRs: ${ prsResult . stderr } ` )
1914 }
2015
21- const allPRs : PR [ ] = JSON . parse ( prsResult . stdout )
22- const prs = allPRs . filter ( ( pr ) => ! pr . isDraft )
23-
24- console . log ( `Found ${ prs . length } open non-draft contributor PRs` )
16+ const prs : PR [ ] = JSON . parse ( prsResult . stdout )
17+ console . log ( `Found ${ prs . length } open contributor PRs` )
2518
2619 console . log ( "Fetching latest dev branch..." )
2720 const fetchDev = await $ `git fetch origin dev` . nothrow ( )
@@ -41,81 +34,60 @@ async function main() {
4134 for ( const pr of prs ) {
4235 console . log ( `\nProcessing PR #${ pr . number } : ${ pr . title } ` )
4336
44- // Fetch the PR
45- const fetchPR = await $ `git fetch origin pull/${ pr . number } /head:pr-${ pr . number } ` . nothrow ( )
46- if ( fetchPR . exitCode !== 0 ) {
47- console . log ( ` Failed to fetch PR #${ pr . number } , skipping` )
48- skipped . push ( { number : pr . number , reason : "Failed to fetch" } )
37+ // Get the diff from GitHub
38+ console . log ( ` Getting diff...` )
39+ const diffResult = await $ `gh pr diff ${ pr . number } ` . nothrow ( )
40+ if ( diffResult . exitCode !== 0 ) {
41+ console . log ( ` Failed to get diff` )
42+ skipped . push ( { number : pr . number , reason : `Failed to get diff: ${ diffResult . stderr } ` } )
4943 continue
5044 }
5145
52- // Find merge base and get diff from base to PR head (just the PR's changes)
53- console . log ( ` Finding merge base for PR #${ pr . number } ...` )
54- const mergeBaseResult = await $ `git merge-base dev pr-${ pr . number } ` . nothrow ( )
55- if ( mergeBaseResult . exitCode !== 0 || ! mergeBaseResult . stdout . trim ( ) ) {
56- console . log ( ` Failed to find merge base for PR #${ pr . number } ` )
57- skipped . push ( { number : pr . number , reason : "Failed to find merge base" } )
58- continue
59- }
60- const mergeBase = mergeBaseResult . stdout . trim ( )
61-
62- console . log ( ` Getting diff for PR #${ pr . number } ...` )
63- const diff = await $ `git diff ${ mergeBase } ..pr-${ pr . number } ` . nothrow ( )
64- if ( diff . exitCode !== 0 ) {
65- console . log ( ` Failed to get diff for PR #${ pr . number } ` )
66- console . log ( ` Error: ${ diff . stderr } ` )
67- skipped . push ( { number : pr . number , reason : `Failed to get diff: ${ diff . stderr } ` } )
68- continue
69- }
70-
71- if ( ! diff . stdout . trim ( ) ) {
72- console . log ( ` No changes in PR #${ pr . number } , skipping` )
46+ if ( ! diffResult . stdout . trim ( ) ) {
47+ console . log ( ` No changes, skipping` )
7348 skipped . push ( { number : pr . number , reason : "No changes" } )
7449 continue
7550 }
7651
77- // Apply the diff
78- console . log ( ` Applying diff for PR # ${ pr . number } ...` )
79- const apply = await Bun . spawn ( [ "git" , "apply" ] , {
80- stdin : new TextEncoder ( ) . encode ( diff . stdout ) ,
52+ // Try to apply the diff
53+ console . log ( ` Applying...` )
54+ const apply = await Bun . spawn ( [ "git" , "apply" , "--3way" ] , {
55+ stdin : new TextEncoder ( ) . encode ( diffResult . stdout ) ,
8156 stdout : "pipe" ,
8257 stderr : "pipe" ,
8358 } )
8459 const applyExit = await apply . exited
8560 const applyStderr = await Bun . readableStreamToText ( apply . stderr )
8661
8762 if ( applyExit !== 0 ) {
88- console . log ( ` Failed to apply diff for PR #${ pr . number } ` )
89- console . log ( ` Error: ${ applyStderr } ` )
63+ console . log ( ` Failed to apply (conflicts)` )
9064 await $ `git checkout -- .` . nothrow ( )
91- skipped . push ( { number : pr . number , reason : `Failed to apply diff: ${ applyStderr } ` } )
65+ await $ `git clean -fd` . nothrow ( )
66+ skipped . push ( { number : pr . number , reason : "Has conflicts" } )
9267 continue
9368 }
9469
95- // Stage all changes
70+ // Stage and commit
9671 const add = await $ `git add -A` . nothrow ( )
9772 if ( add . exitCode !== 0 ) {
98- console . log ( ` Failed to stage changes for PR # ${ pr . number } ` )
73+ console . log ( ` Failed to stage` )
9974 await $ `git checkout -- .` . nothrow ( )
75+ await $ `git clean -fd` . nothrow ( )
10076 skipped . push ( { number : pr . number , reason : "Failed to stage" } )
10177 continue
10278 }
10379
104- // Commit
10580 const commitMsg = `Apply PR #${ pr . number } : ${ pr . title } `
106- const commit = await Bun . spawn ( [ "git" , "commit" , "-m" , commitMsg ] , { stdout : "pipe" , stderr : "pipe" } )
107- const commitExit = await commit . exited
108- const commitStderr = await Bun . readableStreamToText ( commit . stderr )
109-
110- if ( commitExit !== 0 ) {
111- console . log ( ` Failed to commit PR #${ pr . number } ` )
112- console . log ( ` Error: ${ commitStderr } ` )
81+ const commit = await $ `git commit -m ${ commitMsg } ` . nothrow ( )
82+ if ( commit . exitCode !== 0 ) {
83+ console . log ( ` Failed to commit` )
11384 await $ `git checkout -- .` . nothrow ( )
114- skipped . push ( { number : pr . number , reason : `Commit failed: ${ commitStderr } ` } )
85+ await $ `git clean -fd` . nothrow ( )
86+ skipped . push ( { number : pr . number , reason : `Commit failed: ${ commit . stderr } ` } )
11587 continue
11688 }
11789
118- console . log ( ` Successfully applied PR # ${ pr . number } ` )
90+ console . log ( ` Applied successfully ` )
11991 applied . push ( pr . number )
12092 }
12193
0 commit comments