| | |
| | const execa = require('execa') |
| | const fs = require('node:fs/promises') |
| | const os = require('node:os') |
| | const path = require('node:path') |
| |
|
| | async function main() { |
| | const [ |
| | githubSha, |
| | githubHeadSha, |
| | tarballDirectory = path.join(os.tmpdir(), 'vercel-nextjs-preview-tarballs'), |
| | ] = process.argv.slice(2) |
| | const repoRoot = path.resolve(__dirname, '..') |
| |
|
| | await fs.mkdir(tarballDirectory, { recursive: true }) |
| |
|
| | const [{ stdout: shortSha }, { stdout: dateString }] = await Promise.all([ |
| | execa('git', ['rev-parse', '--short', githubSha]), |
| | |
| | execa(`git`, [ |
| | 'show', |
| | '-s', |
| | '--no-show-signature', |
| | '--format=%cd', |
| | '--date=format:%Y%m%d', |
| | githubSha, |
| | ]), |
| | ]) |
| |
|
| | const lernaConfig = JSON.parse( |
| | await fs.readFile(path.join(repoRoot, 'lerna.json'), 'utf8') |
| | ) |
| |
|
| | |
| | |
| | const [semverStableVersion] = lernaConfig.version.split('-') |
| | const version = `${semverStableVersion}-preview-${shortSha}-${dateString}` |
| | console.info(`Designated version: ${version}`) |
| |
|
| | const nativePackagesDir = path.join(repoRoot, 'crates/napi/npm') |
| | const platforms = (await fs.readdir(nativePackagesDir)).filter( |
| | (name) => !name.startsWith('.') |
| | ) |
| |
|
| | console.info(`Creating tarballs for next-swc packages`) |
| | const nextSwcPackageNames = new Set() |
| | await Promise.all( |
| | platforms.map(async (platform) => { |
| | const binaryName = `next-swc.${platform}.node` |
| | try { |
| | await fs.cp( |
| | path.join(repoRoot, 'packages/next-swc/native', binaryName), |
| | path.join(nativePackagesDir, platform, binaryName) |
| | ) |
| | } catch (error) { |
| | if (error.code === 'ENOENT') { |
| | console.warn( |
| | `Skipping next-swc platform '${platform}' tarball creation because ${binaryName} was never built.` |
| | ) |
| | return |
| | } |
| | throw error |
| | } |
| | const manifest = JSON.parse( |
| | await fs.readFile( |
| | path.join(nativePackagesDir, platform, 'package.json'), |
| | 'utf8' |
| | ) |
| | ) |
| | manifest.version = version |
| | await fs.writeFile( |
| | path.join(nativePackagesDir, platform, 'package.json'), |
| | JSON.stringify(manifest, null, 2) + '\n' |
| | ) |
| | |
| | const packDestination = path.join(tarballDirectory, manifest.name) |
| | await fs.mkdir(packDestination, { recursive: true }) |
| | const { stdout } = await execa( |
| | 'npm', |
| | ['pack', '--pack-destination', packDestination], |
| | { |
| | cwd: path.join(nativePackagesDir, platform), |
| | } |
| | ) |
| | |
| | const tarballName = stdout.trim().split('\n').pop() |
| | console.info(`Created tarball ${path.join(packDestination, tarballName)}`) |
| |
|
| | nextSwcPackageNames.add(manifest.name) |
| | }) |
| | ) |
| |
|
| | const lernaListJson = await execa('pnpm', [ |
| | '--silent', |
| | 'lerna', |
| | 'list', |
| | '--json', |
| | ]) |
| | const packages = JSON.parse(lernaListJson.stdout) |
| | const packagesByVersion = new Map() |
| | |
| | |
| | for (const packageInfo of packages) { |
| | packagesByVersion.set( |
| | packageInfo.name, |
| | `https://vercel-packages.vercel.app/next/commits/${githubHeadSha}/${packageInfo.name}` |
| | ) |
| | } |
| | for (const nextSwcPackageName of nextSwcPackageNames) { |
| | packagesByVersion.set( |
| | nextSwcPackageName, |
| | `https://vercel-packages.vercel.app/next/commits/${githubHeadSha}/${nextSwcPackageName}` |
| | ) |
| | } |
| |
|
| | console.info(`Creating tarballs for regular packages`) |
| | for (const packageInfo of packages) { |
| | if (packageInfo.private) { |
| | continue |
| | } |
| |
|
| | const packageJsonPath = path.join(packageInfo.location, 'package.json') |
| | const packageJson = await fs.readFile(packageJsonPath, 'utf8') |
| | const manifest = JSON.parse(packageJson) |
| |
|
| | manifest.version = version |
| |
|
| | if (packageInfo.name === 'next') { |
| | manifest.optionalDependencies ??= {} |
| | for (const nextSwcPackageName of nextSwcPackageNames) { |
| | manifest.optionalDependencies[nextSwcPackageName] = |
| | packagesByVersion.get(nextSwcPackageName) |
| | } |
| | } |
| |
|
| | |
| | for (const [dependencyName, version] of packagesByVersion) { |
| | if (manifest.dependencies?.[dependencyName] !== undefined) { |
| | manifest.dependencies[dependencyName] = version |
| | } |
| | if (manifest.devDependencies?.[dependencyName] !== undefined) { |
| | manifest.devDependencies[dependencyName] = version |
| | } |
| | if (manifest.peerDependencies?.[dependencyName] !== undefined) { |
| | manifest.peerDependencies[dependencyName] = version |
| | } |
| | if (manifest.optionalDependencies?.[dependencyName] !== undefined) { |
| | manifest.optionalDependencies[dependencyName] = version |
| | } |
| | } |
| |
|
| | await fs.writeFile( |
| | packageJsonPath, |
| | JSON.stringify(manifest, null, 2) + |
| | |
| | '\n' |
| | ) |
| |
|
| | |
| | const packDestination = path.join(tarballDirectory, manifest.name) |
| | await fs.mkdir(packDestination, { recursive: true }) |
| | const { stdout } = await execa( |
| | 'npm', |
| | ['pack', '--pack-destination', packDestination], |
| | { |
| | cwd: packageInfo.location, |
| | } |
| | ) |
| | |
| | const tarballName = stdout.trim().split('\n').pop() |
| | console.info(`Created tarball ${path.join(packDestination, tarballName)}`) |
| | } |
| |
|
| | console.info( |
| | `When this job is completed, a Next.js preview build will be available under ${packagesByVersion.get('next')}` |
| | ) |
| | } |
| |
|
| | main().catch((err) => { |
| | console.error(err) |
| | process.exit(1) |
| | }) |
| |
|