Skip to content

Commit

Permalink
wip build executor 6
Browse files Browse the repository at this point in the history
  • Loading branch information
BioPhoton committed Sep 4, 2024
1 parent b2751ea commit 6ee0f8c
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 170 deletions.
1 change: 1 addition & 0 deletions tools/build-env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- outputs
- list of packages in registry under `.../storage/.verdaccio-db.json` e.g.: `{"list":["<package-name>"],"secret":"esKM34zA53wetObgi5f0Uu1e7iObmm+f"}``
- tarball of package under `.../storage/@org/<package-name>-<version>.tgz`
e.g.: `{workspaceRoot}/${environmentsDir}/{args.environmentProject}/storage/@org/${packageName}`,
- `package.json` of package under `.../storage/@org/<package-name>/package.json`
- `npm-install`
- outputs
Expand Down
23 changes: 14 additions & 9 deletions tools/build-env/executors.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
{
"executors": {
"setup-env": {
"implementation": "./src/executors/setup-env/executor",
"schema": "./src/executors/setup-env/schema.json",
"description": "Generate and install test environments in your workspace. Cached and ready for use."
},
"bootstrap": {
"implementation": "./src/executors/bootstrap/executor",
"schema": "./src/executors/bootstrap/schema.json",
"description": "Bootstraps a test environments in your workspace. Cached and ready for use."
},
"kill-process": {
"implementation": "./src/executors/kill-process/executor",
"schema": "./src/executors/kill-process/schema.json",
"description": "Kills process by PID, command or file path."
"setup": {
"implementation": "./src/executors/setup/executor",
"schema": "./src/executors/setup/schema.json",
"description": "Generate and install test environments in your workspace. Cached and ready for use."
},
"npm-publish": {
"implementation": "./src/executors/npm-publish/executor",
"schema": "./src/executors/npm-publish/schema.json",
"description": "Publishes npm packages to a configured registry."
},
"npm-install": {
"implementation": "./src/executors/npm-install/executor",
"schema": "./src/executors/npm-install/schema.json",
"description": "Installs npm packages in your workspace."
},
"kill-process": {
"implementation": "./src/executors/kill-process/executor",
"schema": "./src/executors/kill-process/schema.json",
"description": "Kills process by PID, command or file path."
}
}
}
20 changes: 9 additions & 11 deletions tools/build-env/src/executors/bootstrap/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { BootstrapExecutorOptions } from './schema';
import { bootstrapEnvironment } from '../../internal/verdaccio/verdaccio-npm-env';
import { join } from 'node:path';
import { DEFAULT_ENVIRONMENTS_OUTPUT_DIR } from '../../internal/constants';
import { normalizeOptions } from '../internal/normalize-options';

export type BootstrapExecutorOutput = {
success: boolean;
Expand All @@ -11,31 +12,28 @@ export type BootstrapExecutorOutput = {
};

export default async function runBootstrapExecutor(
terminalAndExecutorOptions: BootstrapExecutorOptions,
options: BootstrapExecutorOptions,
context: ExecutorContext
) {
const { projectName } = context;
const normalizedOptions = {
...terminalAndExecutorOptions,
environmentRoot: join(DEFAULT_ENVIRONMENTS_OUTPUT_DIR, projectName),
};
const { projectName, options: normalizedOptions } = normalizeOptions(
context,
options
);
logger.info(
`Execute @org/build-env:build with options: ${JSON.stringify(
terminalAndExecutorOptions,
options,
null,
2
)}`
);

let envResult;
try {
envResult = await bootstrapEnvironment({
await bootstrapEnvironment({
...normalizedOptions,
projectName,
readyWhen: 'Environment ready under',
});
} catch (error) {
// nx build-env cli-e2e
logger.error(error);
return {
success: false,
Expand All @@ -45,6 +43,6 @@ export default async function runBootstrapExecutor(

return Promise.resolve({
success: true,
command: JSON.stringify(envResult, null, 2),
command: 'Bootstraped environemnt successfully.',
} satisfies BootstrapExecutorOutput);
}
22 changes: 22 additions & 0 deletions tools/build-env/src/executors/internal/normalize-options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { join } from 'node:path';
import { DEFAULT_ENVIRONMENTS_OUTPUT_DIR } from '../../internal/constants';
import { ExecutorContext } from '@nx/devkit';

export function normalizeOptions<
T extends ExecutorContext,
I extends Record<string, unknown>
>(
context: T,
options: I
): T & {
options: I & { environmentRoot: string };
} {
const { projectName } = context;
return {
...context,
options: {
...options,
environmentRoot: join(DEFAULT_ENVIRONMENTS_OUTPUT_DIR, projectName),
},
};
}
18 changes: 8 additions & 10 deletions tools/build-env/src/executors/kill-process/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type ExecutorContext, logger } from '@nx/devkit';
import type { KillProcessExecutorOptions } from './schema';
import { join } from 'node:path';
import { killProcessFromPid } from '../../internal/utils/process';
import { normalizeOptions } from '../internal/normalize-options';

export type ExecutorOutput = {
success: boolean;
Expand All @@ -11,25 +12,22 @@ export type ExecutorOutput = {
};

export default async function runKillProcessExecutor(
terminalAndExecutorOptions: KillProcessExecutorOptions,
options: KillProcessExecutorOptions,
context: ExecutorContext
) {
const { projectName } = context;
const { options: opt } = normalizeOptions(context, options);
const {
workspaceRoot,
filePath = join(workspaceRoot ?? '', 'process.json'),
environmentRoot,
pid,
cleanFs = true,
dryRun = false,
verbose = false,
} = {
...terminalAndExecutorOptions,
workspaceRoot: join('tmp', 'environments', projectName),
};
filePath = join(environmentRoot ?? '', 'process.json'),
} = opt;

logger.info(
`Execute @org/stop-verdaccio-env:kill-process with options: ${JSON.stringify(
terminalAndExecutorOptions,
options,
null,
2
)}`
Expand All @@ -45,6 +43,6 @@ export default async function runKillProcessExecutor(
}
return Promise.resolve({
success: true,
command: '????????',
command: 'Process killed successfully.',
} satisfies ExecutorOutput);
}
55 changes: 19 additions & 36 deletions tools/build-env/src/executors/npm-install/executor.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,54 @@
import {
type ExecutorContext,
readJsonFile,
type TargetConfiguration,
} from '@nx/devkit';
import { type ExecutorContext, logger, readJsonFile } from '@nx/devkit';

import type { NpmInstallExecutorOptions } from './schema';
import { join, relative } from 'node:path';
import { executeProcess } from '../../internal/utils/execute-process';
import { objectToCliArgs } from '../../internal/utils/terminal-command';
import { PackageJson } from 'nx/src/utils/package-json';
import { DEFAULT_ENVIRONMENTS_OUTPUT_DIR } from '../../internal/constants';
import { getBuildOutput } from '../../internal/utils/utils';
import { normalizeOptions } from '../internal/normalize-options';

export type ExecutorOutput = {
export type NpmInstallExecutorOutput = {
success: boolean;
command?: string;
error?: Error;
};

const relativeFromPath = (dir: string) =>
relative(join(process.cwd(), dir), join(process.cwd()));

export default async function runNpmInstallExecutor(
terminalAndExecutorOptions: NpmInstallExecutorOptions,
options: NpmInstallExecutorOptions,
context: ExecutorContext
) {
const { projectName, projectsConfigurations } = context;
const { environmentProject = projectName, pkgVersion } =
terminalAndExecutorOptions;
// @TODO DEFAULT_ENVIRONMENTS_OUTPUT_DIR is configured in the registered plugin thing about how to get that value
const environmentRoot = join(
DEFAULT_ENVIRONMENTS_OUTPUT_DIR,
environmentProject
const {
projectName,
projectsConfigurations,
options: opt,
} = normalizeOptions(context, options);

const packageDistPath = getBuildOutput(
projectsConfigurations.projects[projectName]?.targets['build']
);
const packageDistPath = getBuildOutput(projectsConfigurations[projectName]);

const { name: packageName, version } = readJsonFile<PackageJson>(
join(packageDistPath, 'package.json')
);
const userconfig = relativeFromPath(
join(packageDistPath, environmentRoot, '.npmrc')
);
const { pkgVersion = version, environmentRoot } = opt;

logger.info(`Installing ${packageName}@${pkgVersion} in ${environmentRoot}`);

await executeProcess({
command: 'npm',
args: objectToCliArgs({
_: ['install', `${packageName}@${pkgVersion ?? version}`],
_: ['install', `${packageName}@${pkgVersion}`],
'no-fund': true,
'no-shrinkwrap': true,
save: true,
prefix: environmentRoot,
userconfig,
userconfig: join(environmentRoot, '.npmrc'),
}),
cwd: process.cwd(),
verbose: true,
});

return Promise.resolve({
success: true,
command: 'Installed dependencies successfully.',
} satisfies ExecutorOutput);
}

function getBuildOutput(target: TargetConfiguration) {
const { options } = target ?? {};
const { outputPath } = options ?? {};
if (!outputPath) {
throw new Error('outputPath is required');
}
return outputPath;
} satisfies NpmInstallExecutorOutput);
}
57 changes: 57 additions & 0 deletions tools/build-env/src/executors/npm-publish/executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { logger, type ExecutorContext } from '@nx/devkit';

import type { NpmPublishExecutorOptions } from './schema';
import { join, relative } from 'node:path';
import { executeProcess } from '../../internal/utils/execute-process';
import { objectToCliArgs } from '../../internal/utils/terminal-command';
import { DEFAULT_ENVIRONMENTS_OUTPUT_DIR } from '../../internal/constants';
import { getBuildOutput } from '../../internal/utils/utils';
import { normalizeOptions } from '../internal/normalize-options';

export type NpmPublishExecutorOutput = {
success: boolean;
command?: string;
error?: Error;
};

const relativeFromDist = (dir: string) =>
relative(join(process.cwd(), dir), join(process.cwd()));

export default async function runNpmPublishExecutor(
options: NpmPublishExecutorOptions,
context: ExecutorContext
) {
const {
projectName,
projectsConfigurations,
options: opt,
} = normalizeOptions(context, options);
const { environmentRoot } = opt;

const { targets } = projectsConfigurations.projects[projectName];
const packageDistPath = getBuildOutput(targets['build']);
const userconfig = join(
relativeFromDist(packageDistPath),
join(environmentRoot, '.npmrc')
);

logger.info(
`Publishing package from ${packageDistPath} to ${environmentRoot} with userconfig ${userconfig}`
);

// @TODO: try leverage nx-release-publish
await executeProcess({
command: 'npm',
args: objectToCliArgs({
_: ['publish'],
userconfig,
}),
cwd: packageDistPath,
verbose: true,
});

return Promise.resolve({
success: true,
command: 'Published package successfully.',
} satisfies NpmPublishExecutorOutput);
}
22 changes: 22 additions & 0 deletions tools/build-env/src/executors/npm-publish/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "KillProcessExecutorOptions",
"title": "A executor to kill processes by PID, command, or file",
"type": "object",
"properties": {
"dryRun": {
"type": "boolean",
"description": "Print the commands that would be run, but don't actually run them",
"default": false
},
"environmentProject": {
"type": "string",
"description": "The project to use for the environment"
},
"verbose": {
"type": "boolean",
"description": "Print additional logs"
}
},
"additionalProperties": true
}
4 changes: 4 additions & 0 deletions tools/build-env/src/executors/npm-publish/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type NpmPublishExecutorOptions = Partial<{
environmentProject: string;
verbose: boolean;
}>;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { executeProcess } from '../../internal/utils/execute-process';
import { objectToCliArgs } from '../../internal/utils/terminal-command';
import { VerdaccioProcessResult } from '../../internal/verdaccio/verdaccio-registry';
import { SetupEnvironmentExecutorOptions } from './schema';
import { normalizeOptions } from '../internal/normalize-options';

export type ExecutorOutput = {
success: boolean;
Expand All @@ -19,10 +20,11 @@ export default async function runSetupEnvironmentExecutor(
context: ExecutorContext
) {
const { projectName } = context;
const normalizedOptions = {
...terminalAndExecutorOptions,
environmentRoot: join('tmp', 'environments', projectName),
};
const normalizedContext = normalizeOptions(
context,
terminalAndExecutorOptions
);
const { options: normalizedOptions } = normalizedContext;

try {
await runBuildExecutor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,9 @@
"title": "CodePushup CLI build executor",
"type": "object",
"properties": {
"project": {
"environmentRoot": {
"type": "string",
"description": "The name of the project.",
"x-prompt": "Which project should configure Code Pushup?",
"x-dropdown": "projects",
"$default": {
"$source": "argv",
"index": 0
}
"description": "The root directory of the environment"
},
"dryRun": {
"type": "boolean",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type SetupEnvironmentExecutorOptions = Partial<{
workspaceRoot: string;
environmentRoot: string;
keepServerOn: boolean;
progress: boolean;
verbose: boolean;
Expand Down
Loading

0 comments on commit 6ee0f8c

Please sign in to comment.