packages/blueprints/blueprint-builder/static-assets/converted-blueprint/src/blueprint.ts (74 lines of code) (raw):

import { SampleWorkspaces, Workspace, WorkspaceDefinition } from '@amazon-codecatalyst/blueprint-component.dev-environments'; import { Environment, EnvironmentDefinition, AccountConnection, Role } from '@amazon-codecatalyst/blueprint-component.environments'; import { SourceRepository } from '@amazon-codecatalyst/blueprint-component.source-repositories'; import { Workflow, WorkflowBuilder, convertToWorkflowEnvironment } from '@amazon-codecatalyst/blueprint-component.workflows'; import { Blueprint as ParentBlueprint, Options as ParentOptions } from '@amazon-codecatalyst/blueprints.blueprint'; import defaults from './defaults.json'; /** * This is the 'Options' interface. The 'Options' interface is interpreted by the wizard to dynamically generate a selection UI. * 1. It MUST be called 'Options' in order to be interpreted by the wizard * 2. This is how you control the fields that show up on a wizard selection panel. Keeping this small leads to a better user experience. * 3. You can use JSDOCs and annotations such as: '?', @advanced, @hidden, @display - textarea, etc. to control how the wizard displays certain fields. * 4. All required members of 'Options' must be defined in 'defaults.json' to synth your blueprint locally * 5. The 'Options' member values defined in 'defaults.json' will be used to populate the wizard selection panel with default values */ export interface Options extends ParentOptions { /** * An environment is somewhere to deploy code. * This is optional * @displayName This is the Environment Title Area */ environment?: EnvironmentDefinition<{ /** * I can connect my aws account via an environment. * I can ask for multiple accounts per environment. * I can use this account connection on a workflow to deploy with. * @displayName This account connection has an overriden name */ awsAccount: AccountConnection<{ /** * Role on my aws account. I can ask for multiple roles per account. * e.g. here's a copy-pastable policy: [to a link] * @displayName This role has an overriden name */ role: Role<[]>; }>; }>; /** * This is a nested area. It should be open by default * @collapsed false */ nested: { /** * This is a regular string input field. * 1. It's display has been overriden to 'new input display name' from 'stringInput' * 2. It should be a required field * 3. It should be collapsed by default * 4. The default value should have entropy of length 5 appended to it * 5. this field is marked with a '?' and so is optional * @displayName 'new input display name' * @validationRegex /^[a-zA-Z0-9_]+$/ * @validationMessage Must contain only upper and lowercase letters, numbers and underscores * @defaultEntropy 5 */ stringInput?: string; }; /** * This is a regular enum input field with an override display name. * This gets rendered as a dropdown. */ dropdown: 'first-option' | 'second-option' | 'third-option' | 'fourth-option' | 'fifth-option'; } /** * This is the actual blueprint class. * 1. This MUST be the only 'class' exported, as 'Blueprint' * 2. This Blueprint should extend another ParentBlueprint */ export class Blueprint extends ParentBlueprint { constructor(options_: Options) { super(options_); console.log(defaults); // helpful typecheck for defaults const typeCheck: Options = { outdir: this.outdir, ...defaults, // typescript needs some help disambiguating enums dropdown: defaults.dropdown as Options['dropdown'], }; const options = Object.assign(typeCheck, options_); // add a repository const repository = new SourceRepository(this, { title: 'code' }); // add some code to my repository by copying everything in static-assets repository.copyStaticFiles({ from: 'starter-code', to: './', substitute: {}, // optional used for {{mustache}} substitutions map: file => { let newPath = file.path; newPath = replaceEndWith(newPath, '_npmignore', '.npmignore'); newPath = replaceEndWith(newPath, '_gitignore', '.gitignore'); return { ...file, path: file.path, }; }, }); // Copy files explicitly // StaticAsset.findAll('**').forEach(asset => { // new SourceFile(repository, asset.path(), asset.content().toString()); // }); // create an environment, if I have one let environment: Environment | undefined = undefined; if (options.environment) { environment = new Environment(this, options.environment); } const workflowBuilder = new WorkflowBuilder(this); workflowBuilder.setName('this-is-my-first-workflow'); workflowBuilder.addBranchTrigger(['main']); /** * We can use a build action to execute some arbitrary steps */ workflowBuilder.addBuildAction({ actionName: 'do-something-in-an-action', input: { Sources: ['WorkflowSource'], }, steps: [ 'ls -la', 'echo "Hello world from a workflow!"', 'echo "If theres an account connection, I can execute in the context of that account"', 'aws sts get-caller-identity', ], // is there is an environment, connect it to the workflow environment: environment && convertToWorkflowEnvironment(environment), output: {}, }); // write a workflow to my repository new Workflow(this, repository, workflowBuilder.getDefinition()); // Create a dev environment workspace in my project const devEnvironementDefiniton: WorkspaceDefinition = SampleWorkspaces.default; new Workspace(this, repository, devEnvironementDefiniton); } } function replaceEndWith(str: string, occurance: string, replacement: string): string { if (str.endsWith(occurance)) { return str.substring(0, str.lastIndexOf(occurance)) + replacement; } return str; }