Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

810 lines
27 KiB
JavaScript
Raw Permalink Normal View History

Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
// @ts-check
const path = require('path')
const fsp = require('fs/promises')
const process = require('process')
const { pathToFileURL } = require('url')
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
const execa = require('execa')
const { Octokit } = require('octokit')
const SemVer = require('semver')
const yargs = require('yargs')
const {
replayLocalCommitsAsSigned,
upsertBranchRef,
} = require('./github-utils/signed-commit')
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
// Use this script to update Next's vendored copy of React and related packages:
//
// Basic usage (defaults to most recent React canary version):
// pnpm run sync-react
//
// Update package.json but skip installing the dependencies automatically:
// pnpm run sync-react --no-install
//
// 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'
const pullRequestLabels = ['type: react-sync']
const pullRequestReviewers = ['eps1lon']
/**
* Set to `null` to automatically sync the React version of Pages Router with App Router React version.
* Set to a specific version to override the Pages Router React version e.g. `^19.0.0`.
*
* "Active" just refers to our current development practice. While we do support
* React 18 in pages router, we don't focus our development process on it considering
* it does not receive new features.
* @type {string | null}
*/
const activePagesRouterReact = '^19.0.0'
const defaultLatestChannel = 'canary'
const filesReferencingReactPeerDependencyVersion = [
'run-tests.js',
'packages/create-next-app/templates/index.ts',
'test/lib/next-modes/base.ts',
]
const libraryManifestsSupportingNextjsReact = [
'packages/third-parties/package.json',
'packages/next/package.json',
]
const appManifestsInstallingNextjsPeerDependencies = [
'examples/reproduction-template/package.json',
'test/.stats-app/package.json',
// TODO: These should use the usual test helpers that automatically install the right React version
'test/e2e/next-test/first-time-setup-js/package.json',
'test/e2e/next-test/first-time-setup-ts/package.json',
]
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, {
headers: {
Accept: 'application/json',
},
})
if (!response.ok) {
throw new Error(
`${url}: ${response.status} ${response.statusText}\n${await response.text()}`
)
}
const manifest = await response.json()
return manifest.dependencies['scheduler']
}
/**
* @param {string} packageName
* @param {string} versionStr An NPM version or a file URL to a React checkout
* @returns {string}
*/
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}`
}
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
async function sync({ channel, newVersionStr, noInstall }) {
const useExperimental = channel === 'experimental'
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
const cwd = process.cwd()
const pkgJson = JSON.parse(
await fsp.readFile(path.join(cwd, 'package.json'), 'utf-8')
)
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
const devDependencies = pkgJson.devDependencies
const pnpmOverrides = pkgJson.pnpm.overrides
const baseVersionStr = devDependencies[
useExperimental ? 'react-experimental-builtin' : 'react-builtin'
].replace(/^npm:react@/, '')
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
console.log(`Updating "react@${channel}" to ${newVersionStr}...`)
if (newVersionStr === baseVersionStr) {
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
console.log('Already up to date.')
return
}
const newSchedulerVersionStr = await getSchedulerVersion(newVersionStr)
console.log(`Updating "scheduler@${channel}" to ${newSchedulerVersionStr}...`)
for (const packageName of ['react', 'react-dom']) {
devDependencies[
`${packageName}${useExperimental ? '-experimental' : ''}-builtin`
] = getPackageVersion(packageName, newVersionStr)
if (!useExperimental) {
pnpmOverrides[packageName] = getPackageVersion(packageName, newVersionStr)
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
}
}
for (const packageName of [
'react-server-dom-turbopack',
'react-server-dom-webpack',
]) {
devDependencies[`${packageName}${useExperimental ? '-experimental' : ''}`] =
getPackageVersion(packageName, newVersionStr)
}
devDependencies[
`scheduler-${useExperimental ? 'experimental-' : ''}builtin`
] = getPackageVersion('scheduler', newSchedulerVersionStr)
if (!useExperimental) {
pnpmOverrides.scheduler = getPackageVersion(
'scheduler',
newSchedulerVersionStr
)
// TODO: Should be handled like the other React packages
devDependencies['react-is-builtin'] = newVersionStr.startsWith('file://')
? new URL('react-is', newVersionStr).href
: newVersionStr.startsWith('vp:')
? getPackageVersion('react-is', newVersionStr)
: `npm:react-is@${newVersionStr}`
pnpmOverrides['react-is'] = newVersionStr.startsWith('file://')
? new URL('react-is', newVersionStr).href
: newVersionStr.startsWith('vp:')
? getPackageVersion('react-is', newVersionStr)
: `npm:react-is@${newVersionStr}`
}
await fsp.writeFile(
path.join(cwd, 'package.json'),
JSON.stringify(pkgJson, null, 2) +
// Prettier would add a newline anyway so do it manually to skip the additional `pnpm prettier-write`
'\n'
)
}
/**
* @typedef {object} ReactVersionInfo
* @property {string} semverVersion - The semver version of React.
* @property {string} releaseLabel - The release label of React (e.g. "canary", "rc").
* @property {string} sha - The commit SHA of the React version.
* @property {string} dateString - The date string of the React version.
* @returns {ReactVersionInfo}
*/
function extractInfoFromReactVersion(versionStr) {
if (versionStr.startsWith('file://')) {
return {
dateString: new Date().toISOString().split('T')[0],
releaseLabel: 'local',
semverVersion: '0.0.0',
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>.*)$/
)
return match ? match.groups : null
}
async function getChangelogFromGitHub(baseSha, newSha) {
const pageSize = 50
let changelog = []
for (let currentPage = 1; ; currentPage++) {
const url = `https://api.github.com/repos/facebook/react/compare/${baseSha}...${newSha}?per_page=${pageSize}&page=${currentPage}`
const headers = new Headers()
// GITHUB_TOKEN is optional but helps in case of rate limiting during development.
if (process.env.GITHUB_TOKEN) {
headers.set('Authorization', `token ${process.env.GITHUB_TOKEN}`)
}
const response = await fetch(url, {
headers,
})
if (!response.ok) {
throw new Error(
`${response.url}: Failed to fetch commit log from GitHub:\n${response.statusText}\n${await response.text()}`
)
}
const data = await response.json()
const { commits } = data
for (const { commit, sha } of commits) {
const title = commit.message.split('\n')[0] || ''
const match =
// The "title" looks like "[Fiber][Float] preinitialized stylesheets should support integrity option (#26881)"
/\(#([0-9]+)\)$/.exec(title) ??
// or contains "Pull Request resolved: https://github.com/facebook/react/pull/12345" in the body if merged via ghstack (e.g. https://github.com/facebook/react/commit/0a0a5c02f138b37e93d5d93341b494d0f5d52373)
/^Pull Request resolved: https:\/\/github.com\/facebook\/react\/pull\/([0-9]+)$/m.exec(
commit.message
)
const prNum = match ? match[1] : ''
if (prNum) {
changelog.push(`- https://github.com/facebook/react/pull/${prNum}`)
} else {
changelog.push(
`- [${commit.message.split('\n')[0]} facebook/react@${sha.slice(0, 9)}](https://github.com/facebook/react/commit/${sha}) (${commit.author.name})`
)
}
}
if (commits.length < pageSize) {
// If the number of commits is less than the page size, we've reached
// the end. Otherwise we'll keep fetching until we run out.
break
}
}
changelog.reverse()
return changelog.length > 0 ? changelog.join('\n') : null
}
async function findHighestNPMReactVersion(versionLike) {
const { stdout, stderr } = await execa(
'npm',
['--silent', 'view', '--json', `react@${versionLike}`, 'version'],
{
// Avoid "Usage Error: This project is configured to use pnpm".
cwd: '/tmp',
}
)
if (stderr) {
console.error(stderr)
throw new Error(
`Failed to read highest react@${versionLike} version from npm.`
)
}
const result = JSON.parse(stdout)
return typeof result === 'string'
? result
: result.sort((a, b) => {
return SemVer.compare(b, a)
})[0]
}
/**
* Assigns `actor` to the given Pull Request if they can be assigned.
* On scheduled runs `github.actor` often resolves to a bot like
* `github-actions[bot]`, which cannot be assigned. User tokens silently
* ignore non-assignable assignees but GitHub App tokens fail the whole
* request with 403, so check assignability first and skip instead.
* @param {InstanceType<typeof Octokit>} octokit
* @param {string | undefined} actor
* @param {number} pullRequestNumber
*/
async function assignActorIfAssignable(octokit, actor, pullRequestNumber) {
if (actor === undefined) {
return null
}
try {
await octokit.rest.issues.checkUserCanBeAssigned({
owner: repoOwner,
repo: repoName,
assignee: actor,
})
} catch (error) {
if (error instanceof Error && 'status' in error && error.status === 404) {
console.warn(
`'${actor}' cannot be assigned in ${repoOwner}/${repoName}. Skipping assignment.`
)
return null
}
throw error
}
return octokit.rest.issues.addAssignees({
owner: repoOwner,
repo: repoName,
issue_number: pullRequestNumber,
assignees: [actor],
})
}
async function main() {
const cwd = process.cwd()
const errors = []
const argv = await yargs(process.argv.slice(2))
.version(false)
.options('actor', {
type: 'string',
description:
'Required with `--create-pull`. The actor (GitHub username) that runs this script. Will be assigned to the Pull Request for notifications, but neither the commits nor the Pull Request are attributed to them.',
})
.options('create-pull', {
default: false,
type: 'boolean',
description: 'Create a Pull Request in vercel/next.js',
})
.options('commit', {
default: false,
type: 'boolean',
description:
'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',
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
// Ensure trailing slash so that the URL is treated as a directory.
if (!version.endsWith('/')) {
version += '/'
}
}
async function commitEverything(message) {
await execa('git', ['add', '-A'])
await execa('git', [
'commit',
'--message',
message,
'--no-verify',
// Some steps can be empty, e.g. when we don't sync Pages router
'--allow-empty',
])
}
if (createPull && !actor) {
throw new Error(
`Pull Request cannot be created without a GitHub actor (received '${String(actor)}'). ` +
'Pass an actor via `--actor "some-actor"`.'
)
}
const releaseGithubToken = process.env.RELEASE_GITHUB_TOKEN
const releaseAppSlug = process.env.RELEASE_GITHUB_APP_SLUG
const releaseAppUserId = process.env.RELEASE_GITHUB_APP_USER_ID
if (createPull) {
if (!releaseGithubToken) {
throw new Error(
`Environment variable 'RELEASE_GITHUB_TOKEN' not specified but required when --create-pull is specified.`
)
}
if (!releaseAppSlug || !releaseAppUserId) {
throw new Error(
`Environment variables 'RELEASE_GITHUB_APP_SLUG' and 'RELEASE_GITHUB_APP_USER_ID' must be set when --create-pull is specified.`
)
}
// Set the git author up-front so all subsequent local commits made by
// this script (intermediate `--commit` steps and the final PR commit)
// succeed even on CI runners that don't have a default git identity.
// The values themselves are discarded by the GitHub REST API: the
// GPG-signed commits on the remote are attributed to the app token's
// identity regardless of local git config. The same app token opens the
// Pull Request, so the PR author matches the commit author.
const botUserName = `${releaseAppSlug}[bot]`
const botUserEmail = `${releaseAppUserId}+${releaseAppSlug}[bot]@users.noreply.github.com`
await execa('git', ['config', 'user.name', botUserName])
await execa('git', ['config', 'user.email', botUserEmail])
}
let newVersionStr = version
if (
newVersionStr === null ||
// TODO: Fork arguments in GitHub workflow to ensure `--version ""` is considered a mistake
newVersionStr === ''
) {
newVersionStr = await findHighestNPMReactVersion(defaultLatestChannel)
console.log(
`--version was not provided. Using react@${defaultLatestChannel}: ${newVersionStr}`
)
}
const newVersionInfo = extractInfoFromReactVersion(newVersionStr)
if (!newVersionInfo) {
throw new Error(
`New react version does not match expected format: ${newVersionStr}
Choose a React canary version from npm: https://www.npmjs.com/package/react?activeTab=versions
Or, run this command with no arguments to use the most recently published version.
`
)
}
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',
[
'ls-remote',
'--exit-code',
'--heads',
'origin',
`refs/heads/${branchName}`,
],
{ reject: false }
)
if (exitCode === 2) {
console.log(
`No sync in progress in branch '${branchName}' according to '${command}'. Starting a new one.`
)
} else if (exitCode === 0) {
console.log(
`An existing sync already exists in branch '${branchName}'. Delete the branch to start a new sync.`
)
return
} else {
throw new Error(
`Failed to check if the branch already existed:\n${command}: ${all}`
)
}
}
const rootManifest = JSON.parse(
await fsp.readFile(path.join(cwd, 'package.json'), 'utf-8')
)
const baseVersionStr = rootManifest.devDependencies['react-builtin'].replace(
/^npm:react@/,
''
)
let experimentalNewVersionStr = `0.0.0-experimental-${newSha}-${newDateString}`
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({
newVersionStr: experimentalNewVersionStr,
noInstall: !install,
channel: 'experimental',
})
if (commit) {
await commitEverything('Update `react@experimental`')
}
await sync({
newVersionStr,
noInstall: !install,
channel: '<framework-stable>',
})
if (commit) {
await commitEverything('Update `react`')
}
const baseVersionInfo = extractInfoFromReactVersion(baseVersionStr)
if (!baseVersionInfo) {
throw new Error(
'Base react version does not match expected format: ' + baseVersionStr
)
}
const syncPagesRouterReact = activePagesRouterReact === null
const newActivePagesRouterReactVersion = syncPagesRouterReact
? newVersionStr
: activePagesRouterReact
const pagesRouterReactVersion = `^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ${newActivePagesRouterReactVersion}`
const highestPagesRouterReactVersion = await findHighestNPMReactVersion(
pagesRouterReactVersion
)
const { sha: baseSha, dateString: baseDateString } = baseVersionInfo
for (const fileName of filesReferencingReactPeerDependencyVersion) {
const filePath = path.join(cwd, fileName)
const previousSource = await fsp.readFile(filePath, 'utf-8')
const previousHighestVersionMatch = previousSource.match(
/const nextjsReactPeerVersion = "([^"]+)";/
)
if (previousHighestVersionMatch === null) {
errors.push(
new Error(
`${fileName}: Is this file still referencing the React peer dependency version?`
)
)
} else {
const updatedSource = previousSource.replace(
previousHighestVersionMatch[0],
`const nextjsReactPeerVersion = "${highestPagesRouterReactVersion}";`
)
if (updatedSource !== previousSource) {
await fsp.writeFile(filePath, updatedSource)
}
}
}
for (const fileName of appManifestsInstallingNextjsPeerDependencies) {
const packageJsonPath = path.join(cwd, fileName)
const packageJson = await fsp.readFile(packageJsonPath, 'utf-8')
const manifest = JSON.parse(packageJson)
if (manifest.dependencies['react']) {
manifest.dependencies['react'] = highestPagesRouterReactVersion
}
if (manifest.dependencies['react-dom']) {
manifest.dependencies['react-dom'] = highestPagesRouterReactVersion
}
await fsp.writeFile(
packageJsonPath,
JSON.stringify(manifest, null, 2) +
// Prettier would add a newline anyway so do it manually to skip the additional `pnpm prettier-write`
'\n'
)
}
if (commit) {
await commitEverything('Updated peer dependency references in apps')
}
for (const fileName of libraryManifestsSupportingNextjsReact) {
const packageJsonPath = path.join(cwd, fileName)
const packageJson = await fsp.readFile(packageJsonPath, 'utf-8')
const manifest = JSON.parse(packageJson)
// Need to specify last supported RC version to avoid breaking changes.
if (manifest.peerDependencies['react']) {
manifest.peerDependencies['react'] = pagesRouterReactVersion
}
if (manifest.peerDependencies['react-dom']) {
manifest.peerDependencies['react-dom'] = pagesRouterReactVersion
}
await fsp.writeFile(
packageJsonPath,
JSON.stringify(manifest, null, 2) +
// Prettier would add a newline anyway so do it manually to skip the additional `pnpm prettier-write`
'\n'
)
}
if (commit) {
await commitEverything('Updated peer dependency references in libraries')
}
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
// Install the updated dependencies and build the vendored React files.
if (!install) {
console.log('Skipping install step because --no-install flag was passed.')
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
} else {
console.log('Installing dependencies...')
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
const installSubprocess = execa('pnpm', [
'install',
// Pnpm freezes the lockfile by default in CI.
// However, we just changed versions so the lockfile is expected to be changed.
'--no-frozen-lockfile',
])
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
if (installSubprocess.stdout) {
installSubprocess.stdout.pipe(process.stdout)
}
try {
await installSubprocess
} catch (error) {
console.error(error)
throw new Error('Failed to install updated dependencies.')
}
if (commit) {
await commitEverything('Update lockfile')
}
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
console.log('Building vendored React files...\n')
const nccSubprocess = execa('pnpm', ['ncc-compiled'], {
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
cwd: path.join(cwd, 'packages', 'next'),
})
if (nccSubprocess.stdout) {
nccSubprocess.stdout.pipe(process.stdout)
}
try {
await nccSubprocess
} catch (error) {
console.error(error)
throw new Error('Failed to run ncc.')
}
if (commit) {
await commitEverything('ncc-compiled')
}
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
// Print extra newline after ncc output
console.log()
}
let prDescription = ''
if (newVersionInfo.releaseLabel === 'local') {
prDescription = "Can't generate a changelog for local builds"
} else {
if (syncPagesRouterReact) {
prDescription += `**breaking change for canary users: Bumps peer dependency of React from \`${baseVersionStr}\` to \`${pagesRouterReactVersion}\`**\n\n`
}
// Fetch the changelog from GitHub and print it to the console.
prDescription += `[diff facebook/react@${baseSha}...${newSha}](https://github.com/facebook/react/compare/${baseSha}...${newSha})\n\n`
try {
const changelog = await getChangelogFromGitHub(baseSha, newSha)
if (changelog === null) {
prDescription += `GitHub reported no changes between ${baseSha} and ${newSha}.`
} else {
prDescription += `<details>\n<summary>React upstream changes</summary>\n\n${changelog}\n\n</details>`
}
} catch (error) {
console.error(error)
prDescription +=
'\nFailed to fetch changelog from GitHub. Changes were applied, anyway.\n'
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
}
}
if (!install) {
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
console.log(
`
To finish upgrading, complete the following steps:
- Install the updated dependencies: pnpm install
- Build the vendored React files: (inside packages/next dir) pnpm ncc-compiled
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
Or run this command again without the --no-install flag to do both automatically.
`
)
}
if (errors.length) {
// eslint-disable-next-line no-undef -- Defined in Node.js
throw new AggregateError(errors)
}
if (createPull) {
const octokit = new Octokit({ auth: releaseGithubToken })
const prTitle = `Upgrade React from \`${baseSha}-${baseDateString}\` to \`${newSha}-${newDateString}\``
await execa('git', ['checkout', '-b', branchName])
// We didn't commit intermediate steps yet so now we need to commit to create a PR.
if (!commit) {
await commitEverything(prTitle)
}
// Branch protection on canary requires signed commits. Push each local
// commit to the remote as a GitHub-signed commit via the REST API
// instead of `git push` (which would push unsigned commits).
const baseRef = process.env.GITHUB_REF_NAME || 'canary'
const remoteBaseSha = (
await execa('git', ['rev-parse', `origin/${baseRef}`])
).stdout.trim()
const localCommitSha = (
await execa('git', ['rev-parse', 'HEAD'])
).stdout.trim()
[cd] add ad-hoc preview release cut from canary (#95086) Add a `preview` release type so `@preview` npm releases can be cut **ad-hoc from `canary`** via the `Trigger Release` workflow, retiring the dedicated long-lived preview branch. The GitHub environment has been updated accordingly. A preview cut produces **two commits**, pushed in a single update: 1. **Bump-to-preview** — all packages set to the computed preview version, tagged `v…-preview.N`. This tag's build publishes `@preview` (relies on #95085). 2. **Revert-to-canary** — restores the `-canary.N` versions so `canary` keeps advancing its own line and isn't stranded on a preview version. ``` B canary HEAD before cut (e.g. 16.3.0-canary.61) │ P v16.3.0-preview.N ← tag here; tag build publishes @preview │ R canary HEAD after cut (versions restored to 16.3.0-canary.61) ``` ### Preview version numbering `base = max(canary major.minor.patch, npm @preview major.minor.patch)`: - base still on the published preview line → continue it (`n + 1`) - canary advanced to a higher base (or no `@preview` published) → reset to `.0` So if `canary` jumps to `18.0.0-canary.x` since the last `16.3.0-preview.x`, the next cut is `18.0.0-preview.0`, not a continuation. ## Test plan The dry mode of `start-release.js` was extended to intercept the GH requests and log the relevant data. ```console $ node ./scripts/start-release.js --release-type preview --dry-run Dry run: keeping commits locally, skipping git push and GitHub release creation Running pnpm release-preview... [...] > lerna version 16.3.0-preview.4 --force-publish -y --no-push --allow-branch '**' [...] Creating GitHub-signed release commit(s) for v16.3.0-preview.4 from local commits 0f5c1e865cc34edb257a16823ed6525d9cd58bfc..0062348c411776271fe7eac64e97b8bad2775b77 [dry-run] GitHub API POST /repos/vercel/next.js/git/blobs [...] [dry-run] GitHub API POST /repos/vercel/next.js/git/commits {"message":"v16.3.0-preview.4","tree":"0000000000000000000000000000000000000016","parents":["0f5c1e865cc34edb257a16823ed6525d9cd58bfc"]} [dry-run] GitHub API POST /repos/vercel/next.js/git/commits {"message":"Restore canary version 16.3.0-canary.61 after v16.3.0-preview.4 preview release","tree":"000000000000000000000000000000000000002d","parents":["0000000000000000000000000000000000000017"]} [dry-run] GitHub API POST /repos/vercel/next.js/git/refs {"ref":"refs/tags/v16.3.0-preview.4","sha":"0000000000000000000000000000000000000017"} [dry-run] GitHub API PATCH /repos/vercel/next.js/git/refs/heads/sebbie/preview-release-from-canary {"sha":"000000000000000000000000000000000000002e","force":false} Dry run: skipping local branch sync; would set sebbie/preview-release-from-canary to 000000000000000000000000000000000000002e and tag v16.3.0-preview.4 at 0000000000000000000000000000000000000017 Created GitHub-signed release tag v16.3.0-preview.4 at 0000000000000000000000000000000000000017; branch sebbie/preview-release-from-canary now at 000000000000000000000000000000000000002e Dry run: skipping GitHub release creation Release process is finished ```
2026-06-24 16:33:37 +02:00
const { headSha: finalSignedSha } = await replayLocalCommitsAsSigned({
token: releaseGithubToken,
owner: repoOwner,
repo: repoName,
fromBaseSha: remoteBaseSha,
toLocalSha: localCommitSha,
// commitEverything uses --allow-empty for steps that didn't change
// any files (e.g. when Pages Router doesn't need a sync); preserve
// that on the remote signed commits.
allowEmpty: true,
})
await upsertBranchRef({
token: releaseGithubToken,
owner: repoOwner,
repo: repoName,
branch: branchName,
sha: finalSignedSha,
})
const pullRequest = await octokit.rest.pulls.create({
owner: repoOwner,
repo: repoName,
head: branchName,
base: process.env.GITHUB_REF || 'canary',
draft: false,
title: prTitle,
body: prDescription,
})
console.log('Created pull request %s', pullRequest.data.html_url)
// Enable GitHub auto-merge with the squash method so the PR merges
// automatically once required checks pass. GitHub has no REST field for
// this, so it must be enabled via the GraphQL mutation on the PR node id.
// The commit title is left to GitHub's default (the PR title with the PR
// number), while an explicit empty commitBody keeps the squash commit
// description empty regardless of the repo's squash message setting.
await octokit.graphql(
`mutation ($pullRequestId: ID!) {
enablePullRequestAutoMerge(
input: {
pullRequestId: $pullRequestId
mergeMethod: SQUASH
commitBody: ""
}
) {
pullRequest {
autoMergeRequest {
enabledAt
}
}
}
}`,
{ pullRequestId: pullRequest.data.node_id }
)
const finalizeResults = await Promise.allSettled([
assignActorIfAssignable(octokit, actor, pullRequest.data.number),
octokit.rest.pulls.requestReviewers({
owner: repoOwner,
repo: repoName,
pull_number: pullRequest.data.number,
reviewers: pullRequestReviewers,
}),
octokit.rest.issues.addLabels({
owner: repoOwner,
repo: repoName,
issue_number: pullRequest.data.number,
labels: pullRequestLabels,
}),
])
const failures = finalizeResults.filter(
(result) => result.status === 'rejected'
)
if (failures.length > 0) {
// eslint-disable-next-line no-undef -- Defined in Node.js
throw new AggregateError(
failures.map((failure) => failure.reason),
`${failures.length} of ${finalizeResults.length} requests to finalize the Pull Request failed.`
)
}
}
console.log(prDescription)
console.log(
`Successfully updated React from \`${baseSha}-${baseDateString}\` to \`${newSha}-${newDateString}\``
)
Add script to automate updating vendored React version (#46663) Since we intend to update our vendored copy of React frequently, I wrote a script to automate the steps. Basic usage (defaults to most recent React canary version): ```sh pnpm run sync-react ``` Specify a canary version: ```sh pnpm run sync-react --version 18.3.0-next-41110021f-20230301 ``` Update package.json but skip installing the dependencies automatically: ```sh pnpm run sync-react --no-install ``` At the end it will print out a changelog so you can copy/paste it into the PR description. <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2023-03-01 21:15:02 -05:00
}
main().catch((error) => {
console.error(error)
process.exit(1)
})