chore(repo): change e2e to use verdaccio executor (#17347)

This commit is contained in:
Emily Xiong 2023-06-07 12:26:43 -04:00 committed by GitHub
parent 417ac38759
commit 075ac2545d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 155 additions and 169 deletions

View File

@ -161,7 +161,6 @@ pnpm-lock.yaml @nrwl/nx-pipelines-reviewers
# Scripts
/scripts/depcheck @FrozenPandaz @vsavkin @jaysoo
/scripts/documentation @nrwl/nx-docs-reviewers
/scripts/local-registry @FrozenPandaz @vsavkin
/scripts/angular-support-upgrades @nrwl/nx-angular-reviewers
# CI

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-angular-core',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-angular-extensions',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-cypress',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-detox',
testTimeout: 600000,
preset: '../../jest.preset.js',

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-esbuild',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-expo',
testTimeout: 600000,
preset: '../../jest.preset.js',

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-jest',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-js',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-lerna-smoke-tests',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-linter',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-next',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-node',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-nx-init',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-nx-misc',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-nx-run',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-plugin',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-react-core',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-react-extensions',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-react-native',
testTimeout: 600000,
preset: '../../jest.preset.js',

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-rollup',
preset: '../../jest.preset.js',
};

View File

@ -5,6 +5,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-storybook-angular',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-storybook',
preset: '../../jest.preset.js',
};

55
e2e/utils/global-setup.ts Normal file
View File

@ -0,0 +1,55 @@
import { join } from 'path';
import { ChildProcess, execSync, spawn } from 'child_process';
export default async function () {
const storageLocation = join(
process.cwd(),
'tmp/local-registry/storage',
process.env.NX_TASK_TARGET_PROJECT ?? ''
);
global.nxLocalRegistryProcess = await new Promise<ChildProcess>(
(resolve, reject) => {
const childProcess = spawn(
`nx`,
`local-registry @nx/nx-source --location none --storage ${storageLocation} --clear ${
process.env.NX_E2E_SKIP_BUILD_CLEANUP !== 'true'
}`.split(' ')
);
childProcess.stdout.on('data', (data) => {
if (data.toString().includes('http://localhost:')) {
const port = parseInt(
data.toString().match(/localhost:(?<port>\d+)/)?.groups?.port
);
console.log('Local registry started on port ' + port);
const registry = `http://localhost:${port}`;
process.env.npm_config_registry = registry;
process.env.YARN_REGISTRY = registry;
console.log('Set npm and yarn config registry to ' + registry);
resolve(childProcess);
}
});
childProcess.stderr.on('data', (data) => {
process.stderr.write(data);
reject(data);
});
childProcess.on('error', (err) => {
console.log('local registry error', err);
reject(err);
});
childProcess.on('exit', (code) => {
console.log('local registry exit', code);
reject(code);
});
}
);
if (process.env.NX_E2E_SKIP_BUILD_CLEANUP !== 'true') {
console.log('Publishing packages to local registry');
execSync('pnpm nx-release --local major', {
stdio: process.env.CI === 'true' ? 'ignore' : 'inherit',
});
}
}

View File

@ -0,0 +1,6 @@
export default function () {
if (global.nxLocalRegistryProcess) {
global.nxLocalRegistryProcess.kill();
console.log('Killed local registry process');
}
}

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-vite',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-web',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-webpack',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-workspace-create-npm',
preset: '../../jest.preset.js',
};

View File

@ -6,6 +6,8 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
globalSetup: '../utils/global-setup.ts',
globalTeardown: '../utils/global-teardown.ts',
displayName: 'e2e-workspace-create',
preset: '../../jest.preset.js',
};

View File

@ -1,8 +1,5 @@
const nxPreset = require('@nx/jest/preset').default;
process.env.npm_config_registry = `http://localhost:4872`;
process.env.YARN_REGISTRY = `http://localhost:4872`;
module.exports = {
...nxPreset,
testTimeout: 30000,

51
nx.json
View File

@ -111,10 +111,11 @@
"outputs": ["{options.outputFile}"]
},
"e2e": {
"executor": "nx:run-commands",
"inputs": [
"default",
"^production",
"{workspaceRoot}/jest.preset.js",
"{workspaceRoot}/.verdaccio/config.yml",
{
"env": "SELECTED_CLI"
},
@ -128,26 +129,20 @@
"env": "CI"
}
],
"executor": "@nx/jest:jest",
"options": {
"commands": [
{
"command": "pnpm e2e-start-local-registry"
"jestConfig": "{projectRoot}/jest.config.ts",
"passWithNoTests": true,
"runInBand": true
},
{
"command": "pnpm e2e-build-package-publish"
},
{
"command": "nx run-e2e-tests {projectName}"
}
],
"parallel": false
}
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"]
},
"e2e-macos": {
"executor": "nx:run-commands",
"inputs": [
"default",
"^production",
"{workspaceRoot}/jest.preset.js",
"{workspaceRoot}/.verdaccio/config.yml",
{
"env": "SELECTED_CLI"
},
@ -158,31 +153,6 @@
"env": "NX_E2E_CI_CACHE_KEY"
}
],
"options": {
"commands": [
{
"command": "pnpm e2e-start-local-registry"
},
{
"command": "pnpm e2e-build-package-publish"
},
{
"command": "nx run-e2e-tests {projectName}"
}
],
"parallel": false
}
},
"e2e-base": {
"inputs": ["default", "^production"]
},
"run-e2e-tests": {
"inputs": [
"default",
"^production",
"{workspaceRoot}/jest.preset.js",
"{workspaceRoot}/.verdaccio/config.yml"
],
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "{projectRoot}/jest.config.ts",
@ -191,6 +161,9 @@
},
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"]
},
"e2e-base": {
"inputs": ["default", "^production"]
},
"build-storybook": {
"inputs": ["default", "^production", "{workspaceRoot}/.storybook/**/*"]
}

View File

@ -12,8 +12,6 @@
"check-lock-files": "node ./scripts/check-lock-files.js",
"check-documentation-map": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/map-link-checker.ts",
"check-codeowners": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/check-codeowners.ts",
"e2e-start-local-registry": "node ./scripts/e2e-start-local-registry.js",
"e2e-build-package-publish": "ts-node -P ./scripts/tsconfig.e2e.json ./scripts/e2e-build-package-publish.ts",
"nx-release": "ts-node -P ./scripts/tsconfig.release.json ./scripts/nx-release",
"prepublishOnly": "node ./scripts/update-package-group.js",
"version": "pnpm prettier lerna.json --write",

View File

@ -44,6 +44,7 @@
"babel-plugin-macros": "^2.8.0",
"babel-plugin-transform-typescript-metadata": "^0.3.1",
"chalk": "^4.1.0",
"detect-port": "^1.5.1",
"fast-glob": "3.2.7",
"fs-extra": "^11.1.0",
"ignore": "^5.0.4",

View File

@ -1,6 +1,9 @@
import { ExecutorContext, logger } from '@nx/devkit';
import { removeSync, existsSync } from 'fs-extra';
import { ChildProcess, execSync, fork } from 'child_process';
import * as detectPort from 'detect-port';
import { join } from 'path';
import { VerdaccioExecutorSchema } from './schema';
let childProcess: ChildProcess;
@ -25,6 +28,7 @@ export async function verdaccioExecutor(
if (options.clear && options.storage && existsSync(options.storage)) {
removeSync(options.storage);
}
const cleanupFunctions =
options.location === 'none' ? [] : [setupNpm(options), setupYarn(options)];
@ -42,30 +46,43 @@ export async function verdaccioExecutor(
process.on('SIGHUP', processExitListener);
try {
await startVerdaccio(options);
const port = await detectPort(options.port);
if (port === options.port) {
logger.info(`Port ${options.port} was occupied. Using port ${port}.`);
options.port = port;
}
await startVerdaccio(options, context.root);
} catch (e) {
logger.error('Failed to start verdaccio: ' + e.toString());
logger.error('Failed to start verdaccio: ' + e?.toString());
return {
success: false,
port: options.port,
};
}
return {
success: true,
port: options.port,
};
}
/**
* Fork the verdaccio process: https://verdaccio.org/docs/verdaccio-programmatically/#using-fork-from-child_process-module
*/
function startVerdaccio(options: VerdaccioExecutorSchema) {
function startVerdaccio(
options: VerdaccioExecutorSchema,
workspaceRoot: string
) {
return new Promise((resolve, reject) => {
childProcess = fork(
require.resolve('verdaccio/bin/verdaccio'),
createVerdaccioOptions(options),
createVerdaccioOptions(options, workspaceRoot),
{
env: {
...process.env,
VERDACCIO_HANDLE_KILL_SIGNALS: 'true',
...(options.storage
? { VERDACCIO_STORAGE_PATH: options.storage }
: {}),
},
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
}
@ -100,13 +117,16 @@ function startVerdaccio(options: VerdaccioExecutorSchema) {
});
}
function createVerdaccioOptions(options: VerdaccioExecutorSchema) {
function createVerdaccioOptions(
options: VerdaccioExecutorSchema,
workspaceRoot: string
) {
const verdaccioArgs: string[] = [];
if (options.port) {
verdaccioArgs.push('--listen', options.port.toString());
}
if (options.config) {
verdaccioArgs.push('--config', options.config);
verdaccioArgs.push('--config', join(workspaceRoot, options.config));
}
return verdaccioArgs;
}

View File

@ -1,65 +0,0 @@
import { execSync } from 'child_process';
import { remove } from 'fs-extra';
import { existsSync } from 'fs';
import { stripIndent, NX_PREFIX } from 'nx/src/utils/logger';
process.env.npm_config_registry = `http://localhost:4872`;
process.env.YARN_REGISTRY = process.env.npm_config_registry;
async function buildPackagePublishAndCleanPorts() {
if (process.env.NX_E2E_SKIP_BUILD_CLEANUP !== 'true') {
if (!process.env.CI) {
console.log(
stripIndent(`
Did you know that you can run the command with:
> NX_E2E_SKIP_BUILD_CLEANUP - saves time by reusing the previously built local packages
> CI - simulate the CI environment settings
If you change create-nx-workspace or create-nx-plugin, make sure to remove your npx cache.
Otherwise the changes won't be reflected in the tests.
If your e2e tests fail when trying to create a workspace, remove your npx cache.
\n`)
);
}
await Promise.all([
remove('./build'),
remove('/tmp/nx-e2e/nx/proj-backup'),
remove('/tmp/nx-e2e/angular/proj-backup'),
remove('./tmp/local-registry'),
]);
}
if (
process.env.NX_E2E_SKIP_BUILD_CLEANUP !== 'true' ||
!existsSync('./build')
) {
try {
await updateVersionsAndPublishPackages();
} catch (e) {
console.log(e);
process.exit(1);
}
} else {
console.log(`\n⏩ Project building skipped. Reusing the existing packages`);
}
}
async function updateVersionsAndPublishPackages() {
console.log(`\n${NX_PREFIX} 📦 Publishing packages\n`);
const isVerbose =
process.env.NX_VERBOSE_LOGGING === 'true' ||
process.argv.includes('--verbose');
const response = execSync(`pnpm nx-release major --local`, {
stdio: isVerbose ? 'inherit' : 'pipe',
encoding: 'utf8',
});
// extract published version
if (!isVerbose) {
const value = response.match(/Successfully published:\s+ - .+@(.*)/);
console.log(`${NX_PREFIX} ✅ Published local version: ${value?.[1]}\n`);
}
}
(async () => {
await buildPackagePublishAndCleanPorts();
})();

View File

@ -1,21 +0,0 @@
const { exec } = require('child_process');
const verdacio = exec(
'pnpm verdaccio --config ./scripts/local-registry/config.yml'
);
verdacio.unref();
console.log('starting local registry');
function outputHandling(data) {
console.log(data.toString());
if (data.toString().indexOf('address already in use') > -1) {
console.log('Ignoring the error. The local registry is already running.');
process.exit(0);
}
}
verdacio.stdout.on('data', outputHandling);
verdacio.stderr.on('data', outputHandling);
verdacio.on('exit', (code) => process.exit(code));
setTimeout(() => process.exit(0), 2000);

View File

@ -1,31 +0,0 @@
# path to a directory with all packages
storage: ../../tmp/local-registry/storage
listen: localhost:4872
# a list of other known repositories we can talk to
uplinks:
npmjs:
url: https://registry.npmjs.org/
max_fails: 100
maxage: 30m
fail_timeout: 10m
timeout: 600s
cache: false
packages:
'@nrwl/*':
access: $all
publish: $all
'**':
access: $all
publish: $all
unpublish: $all
proxy: npmjs
# log settings
logs:
type: stdout
format: pretty
level: warn