@@ -9,6 +9,11 @@ const yargs = require('yargs')
9
9
/** @type {any } */
10
10
const fetch = require ( 'node-fetch' )
11
11
12
+ const repoOwner = 'vercel'
13
+ const repoName = 'next.js'
14
+ const pullRequestLabels = [ 'type: react-sync' ]
15
+ const pullRequestReviewers = [ 'eps1lon' ]
16
+
12
17
const filesReferencingReactPeerDependencyVersion = [
13
18
'run-tests.js' ,
14
19
'packages/create-next-app/templates/index.ts' ,
@@ -155,9 +160,37 @@ async function main() {
155
160
const errors = [ ]
156
161
const argv = await yargs ( process . argv . slice ( 2 ) )
157
162
. version ( false )
163
+ . options ( 'actor' , {
164
+ type : 'string' ,
165
+ description :
166
+ 'Required with `--create-pull`. The actor (GitHub username) that runs this script. Will be used for notifications but not commit attribution.' ,
167
+ } )
168
+ . options ( 'create-pull' , {
169
+ default : false ,
170
+ type : 'boolean' ,
171
+ description : 'Create a Pull Request in vercel/next.js' ,
172
+ } )
173
+ . options ( 'commit' , {
174
+ default : true ,
175
+ type : 'boolean' ,
176
+ description : 'Will not create any commit' ,
177
+ } )
158
178
. options ( 'install' , { default : true , type : 'boolean' } )
159
179
. options ( 'version' , { default : null , type : 'string' } ) . argv
160
- const { install, version } = argv
180
+ const { actor, createPull, commit, install, version } = argv
181
+
182
+ if ( createPull && ! actor ) {
183
+ throw new Error (
184
+ `Pull Request cannot be created without a GitHub actor (received '${ String ( actor ) } '). ` +
185
+ 'Pass an actor via `--actor "some-actor"`.'
186
+ )
187
+ }
188
+ const githubToken = process . env . GITHUB_TOKEN
189
+ if ( createPull && ! githubToken ) {
190
+ throw new Error (
191
+ `Environment variable 'GITHUB_TOKEN' not specified but required when --create-pull is specified.`
192
+ )
193
+ }
161
194
162
195
let newVersionStr = version
163
196
if ( newVersionStr === null ) {
@@ -203,13 +236,21 @@ Or, run this command with no arguments to use the most recently published versio
203
236
noInstall : ! install ,
204
237
channel : 'experimental' ,
205
238
} )
239
+ if ( commit ) {
240
+ await execa ( 'git' , [ 'add' , '-A' ] )
241
+ await execa ( 'git' , [ 'commit' , '--message' , 'Update `react@experimental`' ] )
242
+ }
206
243
await sync ( {
207
244
newDateString,
208
245
newSha,
209
246
newVersionStr,
210
247
noInstall : ! install ,
211
248
channel : 'rc' ,
212
249
} )
250
+ if ( commit ) {
251
+ await execa ( 'git' , [ 'add' , '-A' ] )
252
+ await execa ( 'git' , [ 'commit' , '--message' , 'Update `react@rc`' ] )
253
+ }
213
254
214
255
const baseVersionInfo = extractInfoFromReactVersion ( baseVersionStr )
215
256
if ( ! baseVersionInfo ) {
@@ -269,6 +310,15 @@ Or, run this command with no arguments to use the most recently published versio
269
310
)
270
311
}
271
312
313
+ if ( commit ) {
314
+ await execa ( 'git' , [ 'add' , '-A' ] )
315
+ await execa ( 'git' , [
316
+ 'commit' ,
317
+ '--message' ,
318
+ 'Updated peer dependency references' ,
319
+ ] )
320
+ }
321
+
272
322
// Install the updated dependencies and build the vendored React files.
273
323
if ( ! install ) {
274
324
console . log ( 'Skipping install step because --no-install flag was passed.\n' )
@@ -300,34 +350,30 @@ Or, run this command with no arguments to use the most recently published versio
300
350
throw new Error ( 'Failed to run ncc.' )
301
351
}
302
352
353
+ if ( commit ) {
354
+ await execa ( 'git' , [ 'add' , '-A' ] )
355
+ await execa ( 'git' , [ 'commit' , '--message' , 'ncc-compiled' ] )
356
+ }
357
+
303
358
// Print extra newline after ncc output
304
359
console . log ( )
305
360
}
306
361
307
- console . log (
308
- `**breaking change for canary users: Bumps peer dependency of React from \`${ baseVersionStr } \` to \`${ newVersionStr } \`**`
309
- )
362
+ let prDescription = `**breaking change for canary users: Bumps peer dependency of React from \`${ baseVersionStr } \` to \`${ newVersionStr } \`**\n\n`
310
363
311
364
// Fetch the changelog from GitHub and print it to the console.
312
- console . log (
313
- `[diff facebook/react@${ baseSha } ...${ newSha } ](https://github.com/facebook/react/compare/${ baseSha } ...${ newSha } )`
314
- )
365
+ prDescription += `[diff facebook/react@${ baseSha } ...${ newSha } ](https://github.com/facebook/react/compare/${ baseSha } ...${ newSha } )\n\n`
315
366
try {
316
367
const changelog = await getChangelogFromGitHub ( baseSha , newSha )
317
368
if ( changelog === null ) {
318
- console . log (
319
- `GitHub reported no changes between ${ baseSha } and ${ newSha } .`
320
- )
369
+ prDescription += `GitHub reported no changes between ${ baseSha } and ${ newSha } .`
321
370
} else {
322
- console . log (
323
- `<details>\n<summary>React upstream changes</summary>\n\n${ changelog } \n\n</details>`
324
- )
371
+ prDescription += `<details>\n<summary>React upstream changes</summary>\n\n${ changelog } \n\n</details>`
325
372
}
326
373
} catch ( error ) {
327
374
console . error ( error )
328
- console . log (
375
+ prDescription +=
329
376
'\nFailed to fetch changelog from GitHub. Changes were applied, anyway.\n'
330
- )
331
377
}
332
378
333
379
if ( ! install ) {
@@ -343,13 +389,51 @@ Or run this command again without the --no-install flag to do both automatically
343
389
)
344
390
}
345
391
346
- await fsp . writeFile ( path . join ( cwd , '.github/.react-version' ) , newVersionStr )
347
-
348
392
if ( errors . length ) {
349
393
// eslint-disable-next-line no-undef -- Defined in Node.js
350
394
throw new AggregateError ( errors )
351
395
}
352
396
397
+ if ( createPull ) {
398
+ const github = await import ( '@actions/github' )
399
+ const octokit = github . getOctokit ( githubToken )
400
+ const branchName = `update/react/${ newSha } -${ newDateString } `
401
+
402
+ const pullRequest = await octokit . rest . pulls . create ( {
403
+ owner : repoOwner ,
404
+ repo : repoName ,
405
+ head : branchName ,
406
+ base : 'main' ,
407
+ draft : false ,
408
+ title : `Upgrade React from \`${ baseSha } -${ baseDateString } \` to \`${ newSha } -${ newDateString } \`` ,
409
+ body : prDescription ,
410
+ } )
411
+
412
+ await Promise . all ( [
413
+ actor
414
+ ? octokit . rest . issues . addAssignees ( {
415
+ owner : repoOwner ,
416
+ repo : repoName ,
417
+ issue_number : pullRequest . data . number ,
418
+ assignees : [ actor ] ,
419
+ } )
420
+ : Promise . resolve ( ) ,
421
+ octokit . rest . pulls . requestReviewers ( {
422
+ owner : repoOwner ,
423
+ repo : repoName ,
424
+ pull_number : pullRequest . data . number ,
425
+ reviewers : pullRequestReviewers ,
426
+ } ) ,
427
+ octokit . rest . issues . addLabels ( {
428
+ owner : repoOwner ,
429
+ repo : repoName ,
430
+ issue_number : pullRequest . data . number ,
431
+ labels : pullRequestLabels ,
432
+ } ) ,
433
+ ] )
434
+ }
435
+
436
+ console . log ( prDescription )
353
437
console . log (
354
438
`Successfully updated React from \`${ baseSha } -${ baseDateString } \` to \`${ newSha } -${ newDateString } \``
355
439
)
0 commit comments