Skip to content

Commit

Permalink
test: speed up isolated next instance test setup (#56525)
Browse files Browse the repository at this point in the history
  • Loading branch information
SukkaW authored Oct 6, 2023
1 parent 3c326ea commit edb92a3
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 79 deletions.
176 changes: 104 additions & 72 deletions .github/actions/next-stats-action/src/prepare/repo-setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const path = require('path')
const fs = require('fs-extra')
const fse = require('fs-extra')
const fs = require('fs')
const fsp = require('fs/promises')
const exec = require('../util/exec')
const { remove } = require('fs-extra')
const logger = require('../util/logger')
Expand Down Expand Up @@ -54,11 +56,23 @@ module.exports = (actionInfo) => {
},
async linkPackages({ repoDir, nextSwcVersion }) {
const pkgPaths = new Map()

/**
* @typedef {Object} PkgData
* @property {string} pkgDataPath Where the package.json file is located
* @property {string} pkg The folder name of the package
* @property {string} pkgPath The path to the package folder
* @property {any} pkgData The content of package.json
* @property {string} packedPkgPath The npm pack output .tgz file path
*/

/** @type {Map<string, PkgData>} */
const pkgDatas = new Map()

let pkgs

try {
pkgs = await fs.readdir(path.join(repoDir, 'packages'))
pkgs = await fsp.readdir(path.join(repoDir, 'packages'))
} catch (err) {
if (err.code === 'ENOENT') {
require('console').log('no packages to link')
Expand All @@ -67,69 +81,81 @@ module.exports = (actionInfo) => {
throw err
}

for (const pkg of pkgs) {
const pkgPath = path.join(repoDir, 'packages', pkg)
const packedPkgPath = path.join(pkgPath, `${pkg}-packed.tgz`)

const pkgDataPath = path.join(pkgPath, 'package.json')
if (!fs.existsSync(pkgDataPath)) {
require('console').log(`Skipping ${pkgDataPath}`)
continue
}
const pkgData = require(pkgDataPath)
const { name } = pkgData

pkgDatas.set(name, {
pkgDataPath,
pkg,
pkgPath,
pkgData,
packedPkgPath,
await Promise.all(
pkgs.map(async (pkg) => {
const pkgPath = path.join(repoDir, 'packages', pkg)
const packedPkgPath = path.join(pkgPath, `${pkg}-packed.tgz`)

const pkgDataPath = path.join(pkgPath, 'package.json')
if (fs.existsSync(pkgDataPath)) {
const pkgData = JSON.parse(await fsp.readFile(pkgDataPath))
const { name } = pkgData

pkgDatas.set(name, {
pkgDataPath,
pkg,
pkgPath,
pkgData,
packedPkgPath,
})
pkgPaths.set(name, packedPkgPath)
} else {
require('console').log(`Skipping ${pkgDataPath}`)
}
})
pkgPaths.set(name, packedPkgPath)
}

for (const pkg of pkgDatas.keys()) {
const { pkgDataPath, pkgData } = pkgDatas.get(pkg)
)

for (const pkg of pkgDatas.keys()) {
const { packedPkgPath } = pkgDatas.get(pkg)
for (const [
pkg,
{ pkgDataPath, pkgData, pkgPath },
] of pkgDatas.entries()) {
// update the current package dependencies to point to packed tgz path
for (const [pkg, { packedPkgPath }] of pkgDatas.entries()) {
if (!pkgData.dependencies || !pkgData.dependencies[pkg]) continue
pkgData.dependencies[pkg] = packedPkgPath
}

// make sure native binaries are included in local linking
if (pkg === '@next/swc') {
if (!pkgData.files) {
pkgData.files = []
}
pkgData.files ||= []

pkgData.files.push('native')
require('console').log(
'using swc binaries: ',
await exec(`ls ${path.join(path.dirname(pkgDataPath), 'native')}`)
)
}

if (pkg === 'next') {
try {
const swcBinariesDirContents = await fsp.readdir(
path.join(pkgPath, 'native')
)
require('console').log(
'using swc binaries: ',
swcBinariesDirContents.join(', ')
)
} catch (err) {
if (err.code === 'ENOENT') {
require('console').log('swc binaries dir is missing!')
}
throw err
}
} else if (pkg === 'next') {
const nextSwcPkg = pkgDatas.get('@next/swc')

console.log('using swc dep', {
nextSwcVersion,
nextSwcPkg: pkgDatas.get('@next/swc'),
nextSwcPkg,
})
if (nextSwcVersion) {
Object.assign(pkgData.dependencies, {
'@next/swc-linux-x64-gnu': nextSwcVersion,
})
} else {
if (pkgDatas.get('@next/swc')) {
pkgData.dependencies['@next/swc'] =
pkgDatas.get('@next/swc').packedPkgPath
if (nextSwcPkg) {
pkgData.dependencies['@next/swc'] = nextSwcPkg.packedPkgPath
} else {
pkgData.files.push('native')
}
}
}

await fs.writeFile(
await fsp.writeFile(
pkgDataPath,
JSON.stringify(pkgData, null, 2),
'utf8'
Expand All @@ -139,41 +165,47 @@ module.exports = (actionInfo) => {
// wait to pack packages until after dependency paths have been updated
// to the correct versions
await Promise.all(
Array.from(pkgDatas.keys()).map(async (pkgName) => {
const { pkgPath, packedPkgPath } = pkgDatas.get(pkgName)

let cleanup = null

if (pkgName === '@next/swc') {
// next-swc uses a gitignore to prevent the committing of native builds but it doesn't
// use files in package.json because it publishes to individual packages based on architecture.
// When we used yarn to pack these packages the gitignore was ignored so the native builds were packed
// however npm does respect gitignore when packing so we need to remove it in this specific case
// to ensure the native builds are packed for use in gh actions and related scripts
await fs.rename(
path.join(pkgPath, 'native/.gitignore'),
path.join(pkgPath, 'disabled-native-gitignore')
)
cleanup = async () => {
await fs.rename(
path.join(pkgPath, 'disabled-native-gitignore'),
path.join(pkgPath, 'native/.gitignore')
Array.from(pkgDatas.entries()).map(
async ([pkgName, { pkgPath, packedPkgPath }]) => {
/** @type {null | () => Promise<void>} */
let cleanup = null

if (pkgName === '@next/swc') {
// next-swc uses a gitignore to prevent the committing of native builds but it doesn't
// use files in package.json because it publishes to individual packages based on architecture.
// When we used yarn to pack these packages the gitignore was ignored so the native builds were packed
// however npm does respect gitignore when packing so we need to remove it in this specific case
// to ensure the native builds are packed for use in gh actions and related scripts

const nativeGitignorePath = path.join(
pkgPath,
'native/.gitignore'
)
const renamedGitignorePath = path.join(
pkgPath,
'disabled-native-gitignore'
)

await fsp.rename(nativeGitignorePath, renamedGitignorePath)
cleanup = async () => {
await fsp.rename(renamedGitignorePath, nativeGitignorePath)
}
}
}

const { stdout } = await execa('npm', ['pack'], {
cwd: pkgPath,
env: {
...process.env,
COREPACK_ENABLE_STRICT: '0',
},
})
await fs.rename(path.resolve(pkgPath, stdout.trim()), packedPkgPath)
if (cleanup) {
await cleanup()
const { stdout } = await execa('pnpm', ['pack'], {
cwd: pkgPath,
env: {
...process.env,
COREPACK_ENABLE_STRICT: '0',
},
})

return Promise.all([
fsp.rename(path.resolve(pkgPath, stdout.trim()), packedPkgPath),
cleanup?.(),
])
}
})
)
)
return pkgPaths
},
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ jobs:
with:
node-version: ${{ env.NODE_LTS_VERSION }}
check-latest: true
- run: corepack enable

- name: Install Rust
uses: ./.github/actions/setup-rust
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 18
- run: corepack enable
- name: 'Run link checker'
run: node ./.github/actions/validate-docs-links/lib
env:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/code_freeze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
with:
node-version: 18
check-latest: true
- run: corepack enable

- run: git clone https://github.com/vercel/next.js.git --depth=1 .

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pull_request_approved.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 18
- run: corepack enable
- name: 'Send notification to Slack'
run: node ./.github/actions/pr-approved-open/index.mjs
env:
Expand Down
14 changes: 7 additions & 7 deletions test/lib/create-next-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const { linkPackages } =
* @param {string} cwd - The project directory where pnpm configuration is set.
* @returns {Promise<void>}
*/
async function setPnpmResolutionMode(cwd) {
await execa(
function setPnpmResolutionMode(cwd) {
return execa(
'pnpm',
['config', 'set', '--location=project', 'resolution-mode', 'highest'],
{
Expand Down Expand Up @@ -99,8 +99,8 @@ async function createNextInstall({
for (const item of ['package.json', 'packages']) {
await rootSpan
.traceChild(`copy ${item} to temp dir`)
.traceAsyncFn(async () => {
await fs.copy(
.traceAsyncFn(() =>
fs.copy(
path.join(origRepoDir, item),
path.join(tmpRepoDir, item),
{
Expand All @@ -116,7 +116,7 @@ async function createNextInstall({
},
}
)
})
)
}

pkgPaths = await rootSpan.traceChild('linkPackages').traceAsyncFn(() =>
Expand Down Expand Up @@ -177,7 +177,7 @@ async function createNextInstall({
} else {
await rootSpan
.traceChild('run generic install command')
.traceAsyncFn(async () => {
.traceAsyncFn(() => {
const args = [
'install',
'--strict-peer-dependencies=false',
Expand All @@ -188,7 +188,7 @@ async function createNextInstall({
args.push('--prefer-offline')
}

await execa('pnpm', args, {
return execa('pnpm', args, {
cwd: installDir,
stdio: ['ignore', 'inherit', 'inherit'],
env: process.env,
Expand Down

1 comment on commit edb92a3

@zakariavenom123132
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

salut amdou
dieng

Please sign in to comment.