Only create tarballs once per run-tests (#48321)

When our `run-tests` util is used we can safely only create one instance
of the package tarballs and re-use for the tests and then cleaning up at
the end.

Ports changes from testing new workflow
0ceae76bf4
This commit is contained in:
JJ Kasper 2023-04-12 23:23:59 -07:00 committed by GitHub
parent e21b93b523
commit 1088b3f682
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 73 deletions

View file

@ -55,6 +55,9 @@ const cleanUpAndExit = async (code) => {
if (process.env.NEXT_TEST_STARTER) {
await fs.remove(process.env.NEXT_TEST_STARTER)
}
if (process.env.NEXT_TEST_TEMP_REPO) {
await fs.remove(process.env.NEXT_TEST_TEMP_REPO)
}
console.log(`exiting with code ${code}`)
setTimeout(() => {
@ -257,14 +260,23 @@ async function main() {
// to avoid having to run yarn each time
console.log('Creating Next.js install for isolated tests')
const reactVersion = process.env.NEXT_TEST_REACT_VERSION || 'latest'
const testStarter = await createNextInstall({
const { installDir, pkgPaths, tmpRepoDir } = await createNextInstall({
parentSpan: mockTrace(),
dependencies: {
react: reactVersion,
'react-dom': reactVersion,
},
keepRepoDir: true,
})
process.env.NEXT_TEST_STARTER = testStarter
const serializedPkgPaths = []
for (const key of pkgPaths.keys()) {
serializedPkgPaths.push([key, pkgPaths.get(key)])
}
process.env.NEXT_TEST_PKG_PATHS = JSON.stringify(serializedPkgPaths)
process.env.NEXT_TEST_TEMP_REPO = tmpRepoDir
process.env.NEXT_TEST_STARTER = installDir
}
const sema = new Sema(concurrency, { capacity: testNames.length })
@ -527,7 +539,9 @@ async function main() {
}
}
main().catch((err) => {
console.error(err)
cleanUpAndExit(1)
})
main()
.then(() => cleanUpAndExit(0))
.catch((err) => {
console.error(err)
cleanUpAndExit(1)
})

View file

@ -14,94 +14,101 @@ async function createNextInstall({
packageJson = {},
dirSuffix = '',
onlyPackages = false,
keepRepoDir = false,
}) {
return await parentSpan
.traceChild('createNextInstall')
.traceAsyncFn(async (rootSpan) => {
const tmpDir = await fs.realpath(process.env.NEXT_TEST_DIR || os.tmpdir())
const origRepoDir = path.join(__dirname, '../../')
const tmpRepoDir = path.join(
tmpDir,
`next-repo-${randomBytes(32).toString('hex')}${dirSuffix}`
)
const installDir = path.join(
tmpDir,
`next-install-${randomBytes(32).toString('hex')}${dirSuffix}`
)
let tmpRepoDir
require('console').log('Creating next instance in:')
require('console').log(installDir)
await rootSpan.traceChild('ensure swc binary').traceAsyncFn(async () => {
// ensure swc binary is present in the native folder if
// not already built
for (const folder of await fs.readdir(
path.join(origRepoDir, 'node_modules/@next')
)) {
if (folder.startsWith('swc-')) {
const swcPkgPath = path.join(
origRepoDir,
'node_modules/@next',
folder
)
const outputPath = path.join(
origRepoDir,
'packages/next-swc/native'
)
await fs.copy(swcPkgPath, outputPath, {
filter: (item) => {
return (
item === swcPkgPath ||
(item.endsWith('.node') &&
!fs.pathExistsSync(
path.join(outputPath, path.basename(item))
))
)
},
})
}
}
})
let pkgPaths = process.env.NEXT_TEST_PKG_PATHS
if (pkgPaths) {
pkgPaths = new Map(JSON.parse(pkgPaths))
require('console').log('using provided pkg paths')
} else {
tmpRepoDir = path.join(
tmpDir,
`next-repo-${randomBytes(32).toString('hex')}${dirSuffix}`
)
require('console').log('Creating temp repo dir', tmpRepoDir)
for (const item of ['package.json', 'packages']) {
await rootSpan
.traceChild(`copy ${item} to temp dir`)
.traceChild('ensure swc binary')
.traceAsyncFn(async () => {
await fs.copy(
path.join(origRepoDir, item),
path.join(tmpRepoDir, item),
{
filter: (item) => {
return (
!item.includes('node_modules') &&
!item.includes('pnpm-lock.yaml') &&
!item.includes('.DS_Store') &&
// Exclude Rust compilation files
!/next[\\/]build[\\/]swc[\\/]target/.test(item) &&
!/next-swc[\\/]target/.test(item)
)
},
// ensure swc binary is present in the native folder if
// not already built
for (const folder of await fs.readdir(
path.join(origRepoDir, 'node_modules/@next')
)) {
if (folder.startsWith('swc-')) {
const swcPkgPath = path.join(
origRepoDir,
'node_modules/@next',
folder
)
const outputPath = path.join(
origRepoDir,
'packages/next-swc/native'
)
await fs.copy(swcPkgPath, outputPath, {
filter: (item) => {
return (
item === swcPkgPath ||
(item.endsWith('.node') &&
!fs.pathExistsSync(
path.join(outputPath, path.basename(item))
))
)
},
})
}
)
}
})
}
for (const item of ['package.json', 'packages']) {
await rootSpan
.traceChild(`copy ${item} to temp dir`)
.traceAsyncFn(async () => {
await fs.copy(
path.join(origRepoDir, item),
path.join(tmpRepoDir, item),
{
filter: (item) => {
return (
!item.includes('node_modules') &&
!item.includes('pnpm-lock.yaml') &&
!item.includes('.DS_Store') &&
// Exclude Rust compilation files
!/next[\\/]build[\\/]swc[\\/]target/.test(item) &&
!/next-swc[\\/]target/.test(item)
)
},
}
)
})
}
pkgPaths = await rootSpan.traceChild('linkPackages').traceAsyncFn(() =>
linkPackages({
repoDir: tmpRepoDir,
})
)
}
let combinedDependencies = dependencies
if (onlyPackages) {
return pkgPaths
}
if (!(packageJson && packageJson.nextParamateSkipLocalDeps)) {
const pkgPaths = await rootSpan
.traceChild('linkPackages')
.traceAsyncFn(() =>
linkPackages({
repoDir: tmpRepoDir,
})
)
if (onlyPackages) {
return pkgPaths
}
combinedDependencies = {
next: pkgPaths.get('next'),
...Object.keys(dependencies).reduce((prev, pkg) => {
@ -161,7 +168,16 @@ async function createNextInstall({
})
}
await fs.remove(tmpRepoDir)
if (!keepRepoDir && tmpRepoDir) {
await fs.remove(tmpRepoDir)
}
if (keepRepoDir) {
return {
installDir,
pkgPaths,
tmpRepoDir,
}
}
return installDir
})
}