@@ -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' ,
@@ -153,9 +158,39 @@ async function getChangelogFromGitHub(baseSha, newSha) {
153
158
async function main ( ) {
154
159
const cwd = process . cwd ( )
155
160
const errors = [ ]
156
- const { noInstall, version } = await yargs ( process . argv . slice ( 2 ) )
157
- . options ( 'version' , { default : null , type : 'string' } )
158
- . options ( 'no-install' , { default : false , type : 'boolean' } ) . argv
161
+ const { actor, createPull, noCommit, noInstall, version } = await yargs (
162
+ process . argv . slice ( 2 )
163
+ )
164
+ . options ( 'actor' , {
165
+ type : 'string' ,
166
+ description :
167
+ 'Required with `--create-pull`. The actor (GitHub username) that runs this script. Will be used for notifications but not commit attribution.' ,
168
+ } )
169
+ . options ( 'create-pull' , {
170
+ default : false ,
171
+ type : 'boolean' ,
172
+ description : 'Create a Pull Request in vercel/next.js' ,
173
+ } )
174
+ . options ( 'no-commit' , {
175
+ default : false ,
176
+ type : 'boolean' ,
177
+ description : 'Will not create any commit' ,
178
+ } )
179
+ . options ( 'no-install' , { default : false , type : 'boolean' } )
180
+ . options ( 'version' , { default : null , type : 'string' } ) . 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
+ }
159
194
160
195
let newVersionStr = version
161
196
if ( newVersionStr === null ) {
@@ -201,13 +236,21 @@ Or, run this command with no arguments to use the most recently published versio
201
236
noInstall,
202
237
channel : 'experimental' ,
203
238
} )
239
+ if ( ! noCommit ) {
240
+ await execa ( 'git' , [ 'add' , '-A' ] )
241
+ await execa ( 'git' , [ 'commit' , '--message' , 'Update `react@experimental`' ] )
242
+ }
204
243
await sync ( {
205
244
newDateString,
206
245
newSha,
207
246
newVersionStr,
208
247
noInstall,
209
248
channel : 'rc' ,
210
249
} )
250
+ if ( ! noCommit ) {
251
+ await execa ( 'git' , [ 'add' , '-A' ] )
252
+ await execa ( 'git' , [ 'commit' , '--message' , 'Update `react@rc`' ] )
253
+ }
211
254
212
255
const baseVersionInfo = extractInfoFromReactVersion ( baseVersionStr )
213
256
if ( ! baseVersionInfo ) {
@@ -267,6 +310,15 @@ Or, run this command with no arguments to use the most recently published versio
267
310
)
268
311
}
269
312
313
+ if ( ! noCommit ) {
314
+ await execa ( 'git' , [ 'add' , '-A' ] )
315
+ await execa ( 'git' , [
316
+ 'commit' ,
317
+ '--message' ,
318
+ 'Updated peer dependency references' ,
319
+ ] )
320
+ }
321
+
270
322
// Install the updated dependencies and build the vendored React files.
271
323
if ( noInstall ) {
272
324
console . log ( 'Skipping install step because --no-install flag was passed.\n' )
@@ -300,32 +352,28 @@ Or, run this command with no arguments to use the most recently published versio
300
352
301
353
// Print extra newline after ncc output
302
354
console . log ( )
355
+
356
+ if ( ! noCommit ) {
357
+ await execa ( 'git' , [ 'add' , '-A' ] )
358
+ await execa ( 'git' , [ 'commit' , '--message' , 'Updated lockfile' ] )
359
+ }
303
360
}
304
361
305
- console . log (
306
- `**breaking change for canary users: Bumps peer dependency of React from \`${ baseVersionStr } \` to \`${ newVersionStr } \`**`
307
- )
362
+ let prDescription = `**breaking change for canary users: Bumps peer dependency of React from \`${ baseVersionStr } \` to \`${ newVersionStr } \`**\n\n`
308
363
309
364
// Fetch the changelog from GitHub and print it to the console.
310
- console . log (
311
- `[diff facebook/react@${ baseSha } ...${ newSha } ](https://github.com/facebook/react/compare/${ baseSha } ...${ newSha } )`
312
- )
365
+ prDescription += `[diff facebook/react@${ baseSha } ...${ newSha } ](https://github.com/facebook/react/compare/${ baseSha } ...${ newSha } )\n\n`
313
366
try {
314
367
const changelog = await getChangelogFromGitHub ( baseSha , newSha )
315
368
if ( changelog === null ) {
316
- console . log (
317
- `GitHub reported no changes between ${ baseSha } and ${ newSha } .`
318
- )
369
+ prDescription += `GitHub reported no changes between ${ baseSha } and ${ newSha } .`
319
370
} else {
320
- console . log (
321
- `<details>\n<summary>React upstream changes</summary>\n\n${ changelog } \n\n</details>`
322
- )
371
+ prDescription += `<details>\n<summary>React upstream changes</summary>\n\n${ changelog } \n\n</details>`
323
372
}
324
373
} catch ( error ) {
325
374
console . error ( error )
326
- console . log (
375
+ prDescription +=
327
376
'\nFailed to fetch changelog from GitHub. Changes were applied, anyway.\n'
328
- )
329
377
}
330
378
331
379
if ( noInstall ) {
@@ -341,13 +389,51 @@ Or run this command again without the --no-install flag to do both automatically
341
389
)
342
390
}
343
391
344
- await fsp . writeFile ( path . join ( cwd , '.github/.react-version' ) , newVersionStr )
345
-
346
392
if ( errors . length ) {
347
393
// eslint-disable-next-line no-undef -- Defined in Node.js
348
394
throw new AggregateError ( errors )
349
395
}
350
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 )
351
437
console . log (
352
438
`Successfully updated React from \`${ baseSha } -${ baseDateString } \` to \`${ newSha } -${ newDateString } \``
353
439
)
0 commit comments