Repository: vercel/next.js
Pull request: [sync-react] Allow syncing from a React commit

E.g. via `pnpm sync-react --version vp:///78bbf1f7ea87971cb305d539281814ee38c5ee3c`#

The URL used in package.json will use `https:` leveraging https://github.com/vercel/vercel-packages/pull/80

The commit must be built in facebook/react (either pushed to facebook/react or in a PR).

The `vp:` protocol stands for "vercel-packages". I preferred something short here since I couldn't come up with something intuitive. Full vercel-packages URLs are also supported e.g. `p sync-react --version https://vercel-packages.vercel.app/react/commits/bc50ab4bffa17f507386554a8ef3c3ed4f37fe1b/react@canary` if you prefer that. vercel-packages URLs are mostly supported to allow syncing from a vercel-packages URL to a new one.

Only commits are supported for now.






Changed files:
filename: scripts/sync-react.js
patch: @@ -19,6 +19,8 @@ const yargs = require('yargs')
 //
 // Sync from a local checkout of React (requires having React built first):
 //   pnpm run sync-react --version /path/to/react/checkout/
+// Sync from a React commit (can be a commit on a PR)
+//   pnpm run sync-react --version vp:///commit-sha
 
 const repoOwner = 'vercel'
 const repoName = 'next.js'
@@ -57,6 +59,9 @@ async function getSchedulerVersion(reactVersion) {
   if (reactVersion.startsWith('file://')) {
     return reactVersion
   }
+  if (reactVersion.startsWith('vp:')) {
+    return reactVersion
+  }
 
   const url = `https://registry.npmjs.org/react-dom/${reactVersion}`
   const response = await fetch(url, {
@@ -84,6 +89,14 @@ function getPackageVersion(packageName, versionStr) {
   if (versionStr.startsWith('file://')) {
     return new URL(packageName, versionStr).href
   }
+  if (versionStr.startsWith('vp:')) {
+    const { pathname } = new URL(versionStr)
+    const [, commit, releaseChannel] = pathname.split('/')
+    return new URL(
+      `/react/commits/${commit}/${packageName}@${releaseChannel}`,
+      'https://vercel-packages.vercel.app'
+    ).href
+  }
 
   return `npm:${packageName}@${versionStr}`
 }
@@ -139,10 +152,14 @@ async function sync({ channel, newVersionStr, noInstall }) {
     // TODO: Should be handled like the other React packages
     devDependencies['react-is-builtin'] = newVersionStr.startsWith('file://')
       ? new URL('react-is', newVersionStr).href
-      : `npm:react-is@${newVersionStr}`
+      : newVersionStr.startsWith('vp:')
+        ? getPackageVersion('react-is', newVersionStr)
+        : `npm:react-is@${newVersionStr}`
     pnpmOverrides['react-is'] = newVersionStr.startsWith('file://')
       ? new URL('react-is', newVersionStr).href
-      : `npm:react-is@${newVersionStr}`
+      : newVersionStr.startsWith('vp:')
+        ? getPackageVersion('react-is', newVersionStr)
+        : `npm:react-is@${newVersionStr}`
   }
 
   await fsp.writeFile(
@@ -170,6 +187,32 @@ function extractInfoFromReactVersion(versionStr) {
       sha: 'local',
     }
   }
+  if (versionStr.startsWith('vp:')) {
+    const { pathname } = new URL(versionStr)
+    const [, commit] = pathname.split('/')
+    return {
+      dateString: new Date().toISOString().split('T')[0],
+      releaseLabel: 'vercel-packages',
+      semverVersion: '0.0.0',
+      sha: commit,
+    }
+  }
+  if (versionStr.startsWith('https:')) {
+    const url = new URL(versionStr)
+    if (url.hostname === 'vercel-packages.vercel.app') {
+      // e.g https://vercel-packages.vercel.app/react/commits/bc50ab4bffa17f507386554a8ef3c3ed4f37fe1b/react@canary
+      const [, , , commit] = url.pathname.split('/')
+      return {
+        dateString: new Date().toISOString().split('T')[0],
+        releaseLabel: `vercel-packages`,
+        semverVersion: '0.0.0',
+        sha: commit,
+      }
+    }
+    throw new Error(
+      `Unsupported URL '${versionStr}'. Only vercel-packages.vercel.app URLs are supported.`
+    )
+  }
 
   const match = versionStr.match(
     /(?<semverVersion>.*)-(?<releaseLabel>.*)-(?<sha>.*)-(?<dateString>.*)$/
@@ -276,7 +319,12 @@ async function main() {
         'Creates commits for each intermediate step. Useful to create better diffs for GitHub.',
     })
     .options('install', { default: true, type: 'boolean' })
-    .options('version', { default: null, type: 'string' }).argv
+    .options('version', {
+      default: null,
+      type: 'string',
+      description:
+        'e.g. 19.3.0-canary-?-? or vp:///commit-sha for a build from a specific React commit (can be a commit on a PR)',
+    }).argv
   let { actor, createPull, commit, install, version } = argv
   if (version !== null && version.startsWith('/')) {
     version = pathToFileURL(version).href
@@ -334,12 +382,19 @@ Or, run this command with no arguments to use the most recently published versio
 `
     )
   }
-  const { sha: newSha, dateString: newDateString } = newVersionInfo
-
-  const branchName = newVersionStr.startsWith('file://')
-    ? // left to user to name their local sync branch
-      `update/react/local`
-    : `update/react/${newVersionStr}`
+  const {
+    sha: newSha,
+    dateString: newDateString,
+    releaseLabel,
+  } = newVersionInfo
+
+  const branchName =
+    releaseLabel === 'local'
+      ? // left to user to name their local sync branch
+        `update/react/local`
+      : releaseLabel === 'vercel-packages'
+        ? `update/react/remote/vercel-packages/${newSha}`
+        : `update/react/${newVersionStr}`
   if (createPull) {
     const { exitCode, all, command } = await execa(
       'git',
@@ -381,6 +436,9 @@ Or, run this command with no arguments to use the most recently published versio
   if (version !== null && version.startsWith('file://')) {
     experimentalNewVersionStr = new URL('build/oss-experimental/', version).href
     newVersionStr = new URL('build/oss-stable/', version).href
+  } else if (releaseLabel === 'vercel-packages') {
+    experimentalNewVersionStr = `vp:///${newSha}/experimental`
+    newVersionStr = `vp:///${newSha}/canary`
   }
 
   await sync({