@dev-thought/nx-deploy-it
Version:
[](https://www.npmjs.com/package/@dev-thought/nx-deploy-it) [](http://opensource.
202 lines (174 loc) • 5.38 kB
text/typescript
import { ProjectDefinition } from '@angular-devkit/core/src/workspace';
import { Rule } from '@angular-devkit/schematics';
import { ApplicationType } from '../utils/application-type';
import { ArchitectOptions } from '../schematics/init/architect-options';
import { join } from 'path';
import { PROVIDER } from '../utils/provider';
import { QUESTIONS } from '../utils/questions';
import { prompt } from 'enquirer';
import { BuilderOutput, BuilderContext } from '@angular-devkit/architect';
import { Observable, from, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { NxDeployItBaseOptions } from './base.adapter.model';
import { NxDeployItInitSchematicSchema } from '../schematics/init/schema';
import { NxDeployItDeployBuilderSchema } from '../builders/deploy/schema';
import { getDistributionPath, getPulumiBinaryPath } from '../utils/workspace';
import { DeployTargetOptions } from '../builders/deploy/target-options';
import { spawnSync } from 'child_process';
export class BaseAdapter {
constructor(
public project: ProjectDefinition,
public options: NxDeployItBaseOptions,
public applicationType: ApplicationType
) {}
async extendOptionsByUserInput(): Promise<void> {
const options = this.options as NxDeployItInitSchematicSchema;
const questions: any[] = [];
if (options.provider === PROVIDER.AWS) {
if (!options['aws:region']) {
questions.push(QUESTIONS.awsRegion);
}
if (!options['aws:profile']) {
questions.push(QUESTIONS.awsProfile);
}
}
if (options.provider === PROVIDER.AZURE && !options['azure:location']) {
questions.push(QUESTIONS.azureLocation);
}
if (
options.provider === PROVIDER.GOOGLE_CLOUD_PLATFORM &&
!options['gcp:project']
) {
questions.push(QUESTIONS.gcpProjectId);
}
const anwsers = await prompt(questions);
this.options = {
...options,
...anwsers
};
}
addRequiredDependencies(): { name: string; version: string }[] {
const dependencies: { name: string; version: string }[] = [];
return dependencies;
}
getApplicationTypeTemplate(): Rule {
throw new Error('implement me');
}
getApplicationTemplatePath(): string {
return `${this.options.provider}/`;
}
getDeployActionConfiguration(): any {
const architectOptions: ArchitectOptions = {
main: join(this.project.root, 'infrastructure', 'index.ts'),
provider: this.options.provider
};
const mergeOptions = { ...this.options };
delete mergeOptions.project;
delete mergeOptions.provider;
return {
builder: '@dev-thought/nx-deploy-it:deploy',
options: {
...architectOptions,
pulumi: mergeOptions
},
configurations: {}
};
}
getDestroyActionConfiguration(): any {
const architectOptions: ArchitectOptions = {
main: join(this.project.root, 'infrastructure', 'index.ts'),
provider: this.options.provider
};
return {
builder: '@dev-thought/nx-deploy-it:destroy',
options: {
...architectOptions
},
configurations: {}
};
}
deploy(
context: BuilderContext,
cwd: string,
options: NxDeployItDeployBuilderSchema,
configuration: string,
targetOptions: any
): Observable<BuilderOutput> {
const distributationPath = getDistributionPath(context);
const build$: Observable<BuilderOutput> = from(
context
.scheduleTarget({
target: 'build',
project: context.target.project,
configuration: context.target.configuration || ''
})
.then(target => target.result)
);
return build$.pipe(
switchMap(() =>
this.up(
cwd,
options,
configuration,
targetOptions,
distributationPath,
context.target.project
)
)
);
}
up(
cwd: string,
options: NxDeployItDeployBuilderSchema,
configuration: string,
targetOptions: DeployTargetOptions,
distPath: string,
projectName: string,
additionArgs: string[] = []
) {
const args = [
'up',
'--cwd',
cwd,
'--stack',
`${configuration}-${projectName}`
];
if (options.nonInteractive) {
args.push('--non-interactive', '--yes');
}
if (targetOptions.pulumi) {
for (const key in targetOptions.pulumi) {
const value = targetOptions.pulumi[key];
if (value) {
args.push('-c', `${key}=${value}`);
}
}
}
args.push('-c', `distPath=${distPath}`);
args.push('-c', `projectName=${projectName}`);
args.push(...additionArgs);
const up = spawnSync(getPulumiBinaryPath(), args, {
env: { ...process.env, PULUMI_SKIP_UPDATE_CHECK: '1' },
stdio: 'inherit'
});
if (up.error) {
return of({ success: false, error: up.error.message });
}
return of({ success: true });
}
getStackOutput(cwd: string, configuration: string, projectName: string) {
const args = [
'stack',
'output',
'--cwd',
cwd,
'--stack',
`${configuration}-${projectName}`,
'--json'
];
const output = spawnSync(getPulumiBinaryPath(), args, {
env: { ...process.env, PULUMI_SKIP_UPDATE_CHECK: '1' }
});
return JSON.parse(output.stdout.toString());
}
}