# see what's been affected by changes\nnx affected:graph\n\n# run tests for current changes\nnx affected:test\n\n# run e2e tests for current changes\nnx affected:e2e
\n \n
\n\n
\n Carefully crafted with\n \n
\n
\n
\n '},AppElement}(_wrap_native_super(HTMLElement));AppElement.observedAttributes=[],customElements.define("app-root",AppElement)}},__webpack_require__=>{var __webpack_exports__=__webpack_require__(__webpack_require__.s=97)}]);
\ No newline at end of file
diff --git a/packages/upgrade-verify/src/executors/verify-build/__fixtures__/_dist/test-app/runtime.dd97139be5136261.js b/packages/upgrade-verify/src/executors/verify-build/__fixtures__/_dist/test-app/runtime.dd97139be5136261.js
new file mode 100644
index 0000000..d2adc61
--- /dev/null
+++ b/packages/upgrade-verify/src/executors/verify-build/__fixtures__/_dist/test-app/runtime.dd97139be5136261.js
@@ -0,0 +1 @@
+(()=>{"use strict";var __webpack_modules__={},__webpack_module_cache__={};function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(void 0!==cachedModule)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={exports:{}};return __webpack_modules__[moduleId](module,module.exports,__webpack_require__),module.exports}__webpack_require__.m=__webpack_modules__,(()=>{var deferred=[];__webpack_require__.O=(result,chunkIds,fn,priority)=>{if(chunkIds){priority=priority||0;for(var i=deferred.length;i>0&&deferred[i-1][2]>priority;i--)deferred[i]=deferred[i-1];deferred[i]=[chunkIds,fn,priority];return}for(var notFulfilled=1/0,i=0;i=priority&&Object.keys(__webpack_require__.O).every(key=>__webpack_require__.O[key](chunkIds[j]))?chunkIds.splice(j--,1):(fulfilled=!1,priorityObject.prototype.hasOwnProperty.call(obj,prop),(()=>{var installedChunks={666:0};__webpack_require__.O.j=chunkId=>0===installedChunks[chunkId];var webpackJsonpCallback=(parentChunkLoadingFunction,data)=>{var moduleId,chunkId,[chunkIds,moreModules,runtime]=data,i=0;if(chunkIds.some(id=>0!==installedChunks[id])){for(moduleId in moreModules)__webpack_require__.o(moreModules,moduleId)&&(__webpack_require__.m[moduleId]=moreModules[moduleId]);if(runtime)var result=runtime(__webpack_require__)}for(parentChunkLoadingFunction&&parentChunkLoadingFunction(data);i{}},__webpack_require__=>{var __webpack_exports__=__webpack_require__(__webpack_require__.s=658)}]);
\ No newline at end of file
diff --git a/packages/upgrade-verify/src/executors/verify-build/__fixtures__/_dist/test-app/styles.ef46db3751d8e999.css b/packages/upgrade-verify/src/executors/verify-build/__fixtures__/_dist/test-app/styles.ef46db3751d8e999.css
new file mode 100644
index 0000000..e69de29
diff --git a/packages/upgrade-verify/src/executors/verify-build/executor.spec.ts b/packages/upgrade-verify/src/executors/verify-build/executor.spec.ts
index 28dfcd8..a0590e8 100644
--- a/packages/upgrade-verify/src/executors/verify-build/executor.spec.ts
+++ b/packages/upgrade-verify/src/executors/verify-build/executor.spec.ts
@@ -23,7 +23,7 @@ describe('VerifyBuild Executor', () => {
yield {
success: true,
options: {
- outputPath: resolve(__dirname, '__fixtures__/dist/test-app'),
+ outputPath: resolve(__dirname, '__fixtures__/_dist/test-app'),
},
};
})()
@@ -119,6 +119,40 @@ describe('VerifyBuild Executor', () => {
expect(readFile).not.toHaveBeenCalled();
expect(writeFile).not.toHaveBeenCalled();
});
+
+ it('isolates build runs from executor context modifications', async () => {
+ jest.spyOn(devkit, 'runExecutor').mockImplementation(async (targetDescription, overrides, context) => {
+ if (context.target?.command === 'should-not-retain-this') {
+ throw new Error('Context is modified from previous run.');
+ }
+ context.target ??= {};
+ context.target.command = 'should-not-retain-this';
+ return (async function* () {
+ yield { success: true };
+ })();
+ });
+ context.target = { command: 'whatever' };
+ const { success } = await executor(options, context);
+ expect(success).toBe(true);
+ });
+
+ it('isolates build runs from process env modifications (but retains the originals)', async () => {
+ jest.spyOn(devkit, 'runExecutor').mockImplementation(async (targetDescription, overrides, context) => {
+ if (process.env['something'] === 'should-not-retain-this') {
+ throw new Error('Env is modified from previous run.');
+ }
+ if (process.env['andThis'] !== 'should-be-retained') {
+ throw new Error('Env var has not been retained between runs.');
+ }
+ process.env['something'] = 'should-not-retain-this';
+ return (async function* () {
+ yield { success: true };
+ })();
+ });
+ process.env['andThis'] = 'should-be-retained';
+ const { success } = await executor(options, context);
+ expect(success).toBe(true);
+ });
});
function createContext(): ExecutorContext {
@@ -135,7 +169,7 @@ function createContext(): ExecutorContext {
targets: {
build: {
options: {
- outputPath: 'packages/upgrade-verify/src/executors/verify-build/__fixtures__/dist/test-app',
+ outputPath: 'packages/upgrade-verify/src/executors/verify-build/__fixtures__/_dist/test-app',
},
configurations: {
production: {},
diff --git a/packages/upgrade-verify/src/executors/verify-build/executor.ts b/packages/upgrade-verify/src/executors/verify-build/executor.ts
index a60303d..56d1c4b 100644
--- a/packages/upgrade-verify/src/executors/verify-build/executor.ts
+++ b/packages/upgrade-verify/src/executors/verify-build/executor.ts
@@ -1,6 +1,7 @@
import { ExecutorContext, logger, runExecutor } from '@nx/devkit';
import { mkdir, writeFile } from 'fs/promises';
import { join } from 'path';
+import { env } from 'process';
import { compareStats } from './dist-stat-comparer';
import { calculateDistStats, loadExistingDistStats } from './dist-stats';
import { VerifyBuildExecutorSchema } from './schema';
@@ -29,16 +30,20 @@ export default async function verifyBuild(options: VerifyBuildExecutorSchema, co
}
let success = true;
+ const envBackup = { ...env };
for (const configurationName of Object.keys(projectConfig.targets['build'].configurations)) {
+ retainEnv(envBackup);
+ const runContext: ExecutorContext = JSON.parse(JSON.stringify(context));
+
const result = await runExecutor(
{
- project: context.projectName,
+ project: runContext.projectName ?? '',
target: 'build',
configuration: configurationName,
},
{},
- context
+ runContext
);
for await (const x of result) {
@@ -56,7 +61,7 @@ export default async function verifyBuild(options: VerifyBuildExecutorSchema, co
if (existingStats != null) {
const comparison = compareStats(existingStats, newStats);
logger.info(
- `Stats for ${context.projectName}/${configurationName}: ${comparison.totalSizeDifferencePercentage}% total size difference, ${comparison.fileCountDifferencePercentage}% file count difference, ${comparison.newFilesPercentage}% new files, ${comparison.deletedFilesPercentage}% deleted files`
+ `Stats for ${runContext.projectName}/${configurationName}: ${comparison.totalSizeDifferencePercentage}% total size difference, ${comparison.fileCountDifferencePercentage}% file count difference, ${comparison.newFilesPercentage}% new files, ${comparison.deletedFilesPercentage}% deleted files`
);
if (
@@ -80,3 +85,10 @@ async function tryMkdir(statsDir: string) {
// ignore
}
}
+
+function retainEnv(envBackup: Record): void {
+ for (const key of Object.keys(env)) {
+ delete env[key];
+ }
+ Object.assign(env, envBackup);
+}