deployable-awscdk-app-ts
Version:
A projen project for Typescript AWS CDK App
666 lines • 93.7 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeployableAwsCdkTypeScriptAppStepsFactory = void 0;
exports.getDeployJobId = getDeployJobId;
exports.getDiffAnnotationJobId = getDiffAnnotationJobId;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const projen_1 = require("projen");
const github_1 = require("projen/lib/github");
const workflows_model_1 = require("projen/lib/github/workflows-model");
const javascript_1 = require("projen/lib/javascript");
const types_1 = require("./types");
const checkActiveDeploymentStepId = 'deployment-check';
const skipIfAlreadyActiveDeploymentCondition = `steps.${checkActiveDeploymentStepId}.outputs.has_active_deployment != 'true'`;
const formattedDiffAnnotationCommentStepId = 'formatted_diff_annotation_comment';
/**
* Factory to create reusable steps for the deployment workflow
* @experimental
*/
class DeployableAwsCdkTypeScriptAppStepsFactory {
/**
* Validate that the provided environment deployment dependencies are valid
* @param deployOptions The deployment options
* @param environmentDependencies The environment deployment dependencies to validate
*/
static validateEnvironmentDeploymentDependencies(deployOptions, environmentDependencies) {
if (deployOptions.jobStrategy !== types_1.DeployJobStrategy.MULTI_JOB) {
throw new Error('Environment deployment dependencies are only supported for MULTI_JOB strategy');
}
Object.entries(environmentDependencies).forEach(([env, deps]) => {
const hasEnvironment = deployOptions.environments.some(e => e.name === env);
if (!hasEnvironment) {
throw new Error(`Environment "${env}" defined in dependencies does not exist in deployOptions.environments`);
}
deps.forEach(dep => {
const hasDepEnvironment = deployOptions.environments.some(e => e.name === dep);
if (!hasDepEnvironment) {
throw new Error(`Dependency environment "${dep}" for environment "${env}" does not exist in deployOptions.environments`);
}
});
});
}
/**
* Create a new DeployableAwsCdkTypeScriptAppStepsFactory
* @param project The project
* @param props The factory properties
*/
constructor(project, props) {
this.project = project;
this.props = props;
}
/**
* Condition to skip a step if an active deployment is already present
* @returns JobStep condition or undefined if checkActiveDeployment is false
*/
get skipIfAlreadyActiveDeploymentCondition() {
return this.props.checkActiveDeployment ? { if: `\${{ ${skipIfAlreadyActiveDeploymentCondition} }}` } : undefined;
}
get checkoutStep() {
return github_1.WorkflowSteps.checkout({
with: {
fetchDepth: 0,
ref: '${{ github.sha }}',
},
});
}
/**
* Step to run before installing dependencies if exists
* @returns JobStep or undefined if no preInstallTaskName is provided
*/
get preInstallDependenciesStep() {
if (!this.props.preInstallTaskName) {
return undefined;
}
return {
...this.skipIfAlreadyActiveDeploymentCondition,
name: this.props.preInstallTaskName,
run: `npx projen ${this.props.preInstallTaskName}`,
};
}
/**
* Step to check if there is an active deployment for the environment in the matrix strategy
* @returns JobStep
*/
get checkActiveDeploymentStepForMatrix() {
return this.getCheckActiveDeploymentStepForEnvironment('${{ matrix.environment }}');
}
/**
* Step to check if there is an active deployment for a specific environment
* @param environment The environment to check
* @returns JobStep
*/
getCheckActiveDeploymentStepForEnvironment(environment) {
if (!this.props.checkActiveDeployment) {
return undefined;
}
return {
id: checkActiveDeploymentStepId,
uses: 'AminFazlMondo/check-deployed-environment@v1',
with: {
environment: environment,
},
env: {
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}',
},
};
}
/**
* Step to setup AWS credentials in the environment for the matrix strategy
* @returns JobStep[]
*/
get setupAwsCredentialsStepsForMatrix() {
return [
this.setupAwsCredentialsInEnvironmentForMatrix,
this.assumeAwsRoleStepForMatrix,
];
}
/**
* Get the steps to setup AWS credentials for a specific environment
* @param environmentOptions The environment options
* @returns JobStep[]
*/
getSetupAwsCredentialsStepsForEnvironment(environmentOptions) {
const steps = [];
const fromEnvVariableStep = this.getSetupAwsCredentialsInEnvironmentForEnvironment(environmentOptions.awsCredentials.roleToAssume ? true : false, environmentOptions.awsCredentials.accessKeyIdSecretName ?? 'AWS_ACCESS_KEY_ID', environmentOptions.awsCredentials.secretAccessKeySecretName ?? 'AWS_SECRET_ACCESS_KEY', environmentOptions.awsCredentials.region);
if (fromEnvVariableStep) {
steps.push(fromEnvVariableStep);
}
const assumeRoleStep = this.getAssumeAwsRoleStepForEnvironment(environmentOptions.awsCredentials.roleToAssume ? true : false, environmentOptions.awsCredentials.accessKeyIdSecretName ?? 'AWS_ACCESS_KEY_ID', environmentOptions.awsCredentials.secretAccessKeySecretName ?? 'AWS_SECRET_ACCESS_KEY', environmentOptions.awsCredentials.region, environmentOptions.awsCredentials.roleToAssume ?? '', environmentOptions.awsCredentials.assumeRoleDurationSeconds ?? 900);
if (assumeRoleStep) {
steps.push(assumeRoleStep);
}
return steps;
}
/**
* Step to setup AWS credentials in the environment for the matrix strategy
* @returns JobStep
*/
get setupAwsCredentialsInEnvironmentForMatrix() {
return this.getSetupAwsCredentialsInEnvironmentForEnvironment('matrix.assumeRole', 'matrix.accessKeyIdSecretName', 'matrix.secretAccessKeySecretName', '${{ matrix.region }}');
}
/**
* Step to setup AWS credentials in the environment for a specific environment
* @param assumeRoleFlag Whether to assume a role, can be a boolean or a string for matrix strategy
* @param accessKeyIdSecretName The GitHub secret name for the access key ID
* @param secretAccessKeySecretName The GitHub secret name for the secret access key
* @param region The region
* @returns JobStep or undefined if no AWS credentials are provided,
* if assumeRoleFlag is boolean will be evaluated and return a JobStep only if false
* if assumeRoleFlag is string will always return a JobStep (for matrix strategy)
*/
getSetupAwsCredentialsInEnvironmentForEnvironment(assumeRoleFlag, accessKeyIdSecretName, secretAccessKeySecretName, region) {
function getCondition(factory) {
if (typeof assumeRoleFlag === 'boolean') {
if (assumeRoleFlag) {
return undefined;
}
return factory.props.checkActiveDeployment ? skipIfAlreadyActiveDeploymentCondition : undefined;
}
return factory.props.checkActiveDeployment ?
`\${{ ${assumeRoleFlag} == 'false' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
`\${{ ${assumeRoleFlag} == 'false' }}`;
}
const commands = [
'echo "AWS_ACCESS_KEY_ID=$accessKeyId" >> $GITHUB_ENV',
'echo "AWS_SECRET_ACCESS_KEY=$secretAccessKey" >> $GITHUB_ENV',
'echo "AWS_REGION=$region" >> $GITHUB_ENV',
];
if (typeof assumeRoleFlag === 'boolean' && assumeRoleFlag) {
return undefined;
}
const condition = getCondition(this);
return {
if: condition,
name: 'Configure AWS Credentials',
run: `${commands.join('\n')}`,
env: {
accessKeyId: `\${{ secrets[${accessKeyIdSecretName}] }}`,
secretAccessKey: `\${{ secrets[${secretAccessKeySecretName}] }}`,
region,
},
};
}
/**
* Step to assume an AWS role for the matrix strategy
* @returns JobStep
*/
get assumeAwsRoleStepForMatrix() {
return this.getAssumeAwsRoleStepForEnvironment('matrix.assumeRole', 'matrix.accessKeyIdSecretName', 'matrix.secretAccessKeySecretName', '${{ matrix.region }}', '${{ matrix.roleToAssume }}', '${{ matrix.assumeRoleDurationSeconds }}');
}
/**
* Step to assume an AWS role for a specific environment
* @param assumeRoleFlag Whether to assume a role, can be a boolean or a string for matrix strategy
* @param accessKeyIdSecretName The GitHub secret name for the access key ID
* @param secretAccessKeySecretName The GitHub secret name for the secret access key
* @param region The region
* @param roleToAssume The role to assume
* @param assumeRoleDurationSeconds The duration for assuming the role
* @returns JobStep or undefined if assumeRoleFlag is boolean and false
* if assumeRoleFlag is string will always return a JobStep (for matrix strategy)
*/
getAssumeAwsRoleStepForEnvironment(assumeRoleFlag, accessKeyIdSecretName, secretAccessKeySecretName, region, roleToAssume, assumeRoleDurationSeconds) {
function getCondition(factory) {
if (typeof assumeRoleFlag === 'boolean') {
if (!assumeRoleFlag) {
return undefined;
}
return factory.props.checkActiveDeployment ? skipIfAlreadyActiveDeploymentCondition : undefined;
}
return factory.props.checkActiveDeployment ?
`\${{ ${assumeRoleFlag} == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
`\${{ ${assumeRoleFlag} == 'true' }}`;
}
if (typeof assumeRoleFlag === 'boolean' && !assumeRoleFlag) {
return undefined;
}
const condition = getCondition(this);
const secretsParams = this.props.authProvider === javascript_1.CodeArtifactAuthProvider.ACCESS_AND_SECRET_KEY_PAIR ?
{
'aws-access-key-id': `\${{ secrets[${accessKeyIdSecretName}] }}`,
'aws-secret-access-key': `\${{ secrets[${secretAccessKeySecretName}] }}`,
} : undefined;
return {
if: condition,
name: 'Assume AWS Role',
uses: 'aws-actions/configure-aws-credentials@v4',
with: {
...secretsParams,
'role-to-assume': roleToAssume,
'aws-region': region,
'role-duration-seconds': assumeRoleDurationSeconds,
},
};
}
/**
* Step to setup NPM config if provided
* @returns JobStep or undefined if no npmConfig is provided
*/
get setupNpmConfigForMatrix() {
return this.getSetupNpmConfigForEnvironment('${{ matrix.environment }}');
}
getSetupNpmConfigForEnvironment(environment) {
const { npmConfigEnvironment } = this.props;
if (!npmConfigEnvironment) {
return undefined;
}
const environmentVariableName = 'CONFIG_VALUE';
return {
...this.skipIfAlreadyActiveDeploymentCondition,
name: 'Setting NPM Config',
env: {
[environmentVariableName]: environment,
},
run: `npm config set ${npmConfigEnvironment} $${environmentVariableName}`,
};
}
/**
* Get the step to run a specific script
* @param scriptName The name of the script to run
* @param stepName The name of the step in the workflow
* @param hasScriptFlag Whether the script should be run
* @returns The job step to run the script or undefined if not applicable
* If hasScriptFlag is boolean and false will return undefined
* If hasScriptFlag is string will always return a JobStep (for matrix strategy)
*/
getRunScriptStep(scriptName, stepName, hasScriptFlag) {
function getCondition(factory) {
if (typeof hasScriptFlag === 'boolean') {
if (!hasScriptFlag) {
return undefined;
}
return factory.props.checkActiveDeployment ? skipIfAlreadyActiveDeploymentCondition : undefined;
}
return factory.props.checkActiveDeployment ?
`\${{ ${hasScriptFlag} == 'true' && ${skipIfAlreadyActiveDeploymentCondition} }}` :
`\${{ ${hasScriptFlag} == 'true' }}`;
}
if (typeof hasScriptFlag === 'boolean' && !hasScriptFlag) {
return undefined;
}
const condition = getCondition(this);
return {
if: condition,
name: `Run ${stepName}`,
run: `${this.project.runScriptCommand} ${scriptName}`,
};
}
/**
* Step to deploy the workflow
* @returns JobStep
*/
get deploymentStep() {
return this.getRunScriptStep('deploy:workflow', 'Deployment', true);
}
/**
* Step to run post deployment script in matrix strategy
* @returns JobStep
*/
get preDeploymentStepForMatrix() {
return this.getPreDeploymentStepForEnvironment('matrix.hasPreDeployTask', '${{ matrix.preDeploymentScript }}');
}
/**
* Get the pre-deployment step for a specific environment
* @param hasPreDeployTaskFlag Whether the pre-deployment task should be run
* @param preDeploymentScript The script to run
* @returns The job step to run the pre-deployment script or undefined if not applicable
* If hasPreDeployTaskFlag is boolean and false will return undefined
* If hasPreDeployTaskFlag is string will always return a JobStep (for matrix strategy)
*/
getPreDeploymentStepForEnvironment(hasPreDeployTaskFlag, preDeploymentScript) {
return this.getRunScriptStep(preDeploymentScript, 'Pre Deployment', hasPreDeployTaskFlag);
}
/**
* Step to run post deployment script in matrix strategy
* @returns JobStep
*/
get postDeploymentStepForMatrix() {
return this.getPostDeploymentStepForEnvironment('matrix.hasPostDeployTask', '${{ matrix.postDeploymentScript }}');
}
/**
* Get the post-deployment step for a specific environment
* @param hasPostDeployTaskFlag Whether the post-deployment task should be run
* @param postDeploymentScript The script to run
* @returns The job step to run the post-deployment script or undefined if not applicable
* If hasPostDeployTaskFlag is boolean and false will return undefined
* If hasPostDeployTaskFlag is string will always return a JobStep (for matrix strategy)
*/
getPostDeploymentStepForEnvironment(hasPostDeployTaskFlag, postDeploymentScript) {
return this.getRunScriptStep(postDeploymentScript, 'Post Deployment', hasPostDeployTaskFlag);
}
/**
* Get all deployment jobs whether for matrix strategy or not
* @returns Record of jobs
*/
get deploymentJobs() {
if (this.props.deployOptions.environments.length === 0) {
this.project.logger.warn('The project does not have any environment set, make sure this is desired setting');
}
return this.props.jobStrategy === types_1.DeployJobStrategy.MATRIX ? this.deploymentJobsForMatrix : this.deploymentJobsForMultiJob;
}
/**
* Get deployment jobs for matrix strategy
* @returns Record of jobs
*/
get deploymentJobsForMatrix() {
const { environments, environmentVariableName } = this.props.deployOptions;
const include = environments.map(environmentOptions => {
const { awsCredentials } = environmentOptions;
const assumeRole = awsCredentials.roleToAssume ? 'true' : 'false';
const assumeRoleSettings = awsCredentials.roleToAssume ? {
roleToAssume: awsCredentials.roleToAssume,
assumeRoleDurationSeconds: awsCredentials.assumeRoleDurationSeconds || 900,
} : undefined;
const accessKeyIdSecretName = awsCredentials.accessKeyIdSecretName ?? 'AWS_ACCESS_KEY_ID';
const secretAccessKeySecretName = awsCredentials.secretAccessKeySecretName ?? 'AWS_SECRET_ACCESS_KEY';
const hasPostDeployTask = environmentOptions.postDeployWorkflowScript ? 'true' : 'false';
const hasPreDeployTask = environmentOptions.preDeployWorkflowScript ? 'true' : 'false';
return {
environment: environmentOptions.name,
accessKeyIdSecretName,
secretAccessKeySecretName,
region: awsCredentials.region,
assumeRole,
hasPostDeployTask,
postDeploymentScript: environmentOptions.postDeployWorkflowScript || '',
hasPreDeployTask,
preDeploymentScript: environmentOptions.preDeployWorkflowScript || '',
...assumeRoleSettings,
};
});
const deployJobEnv = environmentVariableName ? {
[environmentVariableName]: '${{ matrix.environment }}',
} : undefined;
const jobDefinition = {
runsOn: ['ubuntu-latest'],
concurrency: {
'group': '${{ matrix.environment }}-deploy',
'cancel-in-progress': false,
},
needs: [
'release_github',
],
permissions: {
contents: workflows_model_1.JobPermission.READ,
deployments: workflows_model_1.JobPermission.WRITE,
idToken: this.props.authProvider === javascript_1.CodeArtifactAuthProvider.GITHUB_OIDC ? workflows_model_1.JobPermission.WRITE : undefined,
},
strategy: {
maxParallel: 1,
matrix: {
domain: {
environment: include.map(e => e.environment),
},
include,
},
},
environment: {
name: '${{ matrix.environment }}',
},
env: deployJobEnv,
steps: [],
};
jobDefinition.steps.push(this.checkoutStep);
const preInstallDependenciesStep = this.preInstallDependenciesStep;
if (preInstallDependenciesStep) {
jobDefinition.steps.push(preInstallDependenciesStep);
}
jobDefinition.steps.push(...(this.project).renderWorkflowSetup());
const checkActiveDeploymentStepForMatrix = this.checkActiveDeploymentStepForMatrix;
if (checkActiveDeploymentStepForMatrix) {
jobDefinition.steps.push(checkActiveDeploymentStepForMatrix);
}
jobDefinition.steps.push(...this.setupAwsCredentialsStepsForMatrix);
const setupNpmConfigStep = this.setupNpmConfigForMatrix;
if (setupNpmConfigStep) {
jobDefinition.steps.push(setupNpmConfigStep);
}
jobDefinition.steps.push(this.preDeploymentStepForMatrix);
jobDefinition.steps.push(this.deploymentStep);
jobDefinition.steps.push(this.postDeploymentStepForMatrix);
return { deploy: jobDefinition };
}
/**
* Get the IDs of the jobs that must be completed before the specified environment's deployment job
* @param environmentName The name of the environment
* @returns An array of job IDs
*/
getDeploymentJobPrerequisiteJobIds(environmentName) {
const result = [];
if (!this.props.environmentDependencies) {
const index = this.props.deployOptions.environments.findIndex(env => env.name === environmentName);
const prerequisiteEnvironment = index > 0 ? this.props.deployOptions.environments[index - 1] : undefined;
if (prerequisiteEnvironment) {
result.push(getDeployJobId(prerequisiteEnvironment.name));
}
}
else {
const dependencies = this.props.environmentDependencies[environmentName];
if (dependencies) {
dependencies.forEach(dep => {
result.push(getDeployJobId(dep));
});
}
}
if (result.length === 0) {
result.push('release_github');
}
return result;
}
/**
* Get deployment jobs for multi-job strategy
* @returns Record of jobs
*/
get deploymentJobsForMultiJob() {
const { environmentVariableName, environments } = this.props.deployOptions;
const jobs = environments.map((environmentOptions) => {
return [getDeployJobId(environmentOptions.name), this.getJobForEnvironment(environmentOptions, environmentVariableName)];
});
return Object.fromEntries(jobs);
}
/**
* Get the job definition for a specific environment
* @param environmentOptions The environment options
* @param environmentVariableName The name of the environment variable to set with the environment name, if any
* @returns The job definition for the environment
*/
getJobForEnvironment(environmentOptions, environmentVariableName) {
const { name } = environmentOptions;
const deployJobEnv = environmentVariableName ? {
[environmentVariableName]: name,
} : undefined;
const jobDefinition = {
runsOn: ['ubuntu-latest'],
concurrency: {
'group': `${name}-deploy`,
'cancel-in-progress': false,
},
needs: this.getDeploymentJobPrerequisiteJobIds(name),
permissions: {
contents: workflows_model_1.JobPermission.READ,
deployments: workflows_model_1.JobPermission.WRITE,
idToken: this.props.authProvider === javascript_1.CodeArtifactAuthProvider.GITHUB_OIDC ? workflows_model_1.JobPermission.WRITE : undefined,
},
environment: {
name: name,
},
env: deployJobEnv,
steps: [],
};
jobDefinition.steps.push(this.checkoutStep);
const preInstallDependenciesStep = this.preInstallDependenciesStep;
if (preInstallDependenciesStep) {
jobDefinition.steps.push(preInstallDependenciesStep);
}
jobDefinition.steps.push(...(this.project).renderWorkflowSetup());
const checkActiveDeploymentStep = this.getCheckActiveDeploymentStepForEnvironment(name);
if (checkActiveDeploymentStep) {
jobDefinition.steps.push(checkActiveDeploymentStep);
}
jobDefinition.steps.push(...this.getSetupAwsCredentialsStepsForEnvironment(environmentOptions));
const setupNpmConfigStep = this.getSetupNpmConfigForEnvironment(name);
if (setupNpmConfigStep) {
jobDefinition.steps.push(setupNpmConfigStep);
}
const preDeploymentStep = this.getPreDeploymentStepForEnvironment(environmentOptions.preDeployWorkflowScript ? true : false, environmentOptions.preDeployWorkflowScript || '');
if (preDeploymentStep) {
jobDefinition.steps.push(preDeploymentStep);
}
jobDefinition.steps.push(this.deploymentStep);
const postDeploymentStep = this.getPostDeploymentStepForEnvironment(environmentOptions.postDeployWorkflowScript ? true : false, environmentOptions.postDeployWorkflowScript || '');
if (postDeploymentStep) {
jobDefinition.steps.push(postDeploymentStep);
}
return jobDefinition;
}
/**
* Step to generate the diff output
* @returns JobStep
*/
get generateDiffStep() {
return this.getRunScriptStep('diff:output', 'Generate Diff Output', true);
}
/**
* Get the job to annotate the PR with the diff output for all environments
* @param dependentJobNames The names of the jobs that the annotation job depends on
* @returns The job definition for annotating the PR with the diff output
*/
getAnnotateDiffJob(dependentJobNames) {
return {
runsOn: ['ubuntu-latest'],
needs: dependentJobNames,
permissions: {
contents: workflows_model_1.JobPermission.READ,
pullRequests: workflows_model_1.JobPermission.WRITE,
},
steps: [
projen_1.github.WorkflowSteps.downloadArtifact({
name: 'Download all diff artifacts',
with: {
pattern: 'diff-output-*',
path: 'diff-outputs',
mergeMultiple: true,
},
}),
{
name: 'Annotate PR with Diff Output',
uses: 'mshick/add-pr-comment@v3',
with: {
'message-id': 'diff-output',
'refresh-message-position': true,
'message-path': 'diff-outputs/*.md',
},
},
],
};
}
/**
* Get the step to format the diff output into a GitHub annotation comment for a specific environment
* @param environment The environment to format the diff for
* @returns JobStep
*/
getFormattedDiffAnnotationCommentStepForEnvironment(environment) {
return {
name: 'Get formatted diff annotation comment',
id: formattedDiffAnnotationCommentStepId,
run: [
'mkdir -p diff-output',
`echo "### Changes for environment ${environment}" > diff-output/diff-${environment}.md`,
'echo "" >> diff-output/diff-${environment}.md',
'echo "<details>" >> diff-output/diff-${environment}.md',
'echo "<summary>Show diff</summary>" >> diff-output/diff-${environment}.md',
'echo "" >> diff-output/diff-${environment}.md',
"echo '\`\`\`' >> diff-output/diff-${environment}.md",
'for file in $(find . -path "**/cdk.out/diff.log" 2>/dev/null); do',
' echo "========== $file ==========" >> diff-output/diff-${environment}.md',
' sed \'s/\\x1B\\[[0-9;]*[mGKHF]//g\' "$file" >> diff-output/diff-${environment}.md',
' echo "" >> diff-output/diff-${environment}.md',
'done',
"echo '\`\`\`' >> diff-output/diff-${environment}.md",
'echo "</details>" >> diff-output/diff-${environment}.md',
'echo "" >> diff-output/diff-${environment}.md',
].join('\n'),
env: {
environment: environment,
},
};
}
/**
* Get the deployment method argument for the deploy command
* @param environmentOptions The environment options
* @param environmentVariableName The name of the environment variable to set with the environment name, if any
* @returns The diff annotation job for the environment
*/
getDiffAnnotationJobForEnvironment(environmentOptions, environmentVariableName) {
const { name } = environmentOptions;
const deployJobEnv = environmentVariableName ? {
[environmentVariableName]: name,
} : undefined;
const jobDefinition = {
runsOn: ['ubuntu-latest'],
needs: ['build'],
permissions: {
contents: workflows_model_1.JobPermission.READ,
idToken: this.props.authProvider === javascript_1.CodeArtifactAuthProvider.GITHUB_OIDC ? workflows_model_1.JobPermission.WRITE : undefined,
},
env: deployJobEnv,
steps: [],
};
jobDefinition.steps.push(this.checkoutStep);
const preInstallDependenciesStep = this.preInstallDependenciesStep;
if (preInstallDependenciesStep) {
jobDefinition.steps.push(preInstallDependenciesStep);
}
jobDefinition.steps.push(...(this.project).renderWorkflowSetup());
jobDefinition.steps.push(...this.getSetupAwsCredentialsStepsForEnvironment(environmentOptions));
const setupNpmConfigStep = this.getSetupNpmConfigForEnvironment(name);
if (setupNpmConfigStep) {
jobDefinition.steps.push(setupNpmConfigStep);
}
jobDefinition.steps.push(this.generateDiffStep);
jobDefinition.steps.push(this.getFormattedDiffAnnotationCommentStepForEnvironment(name));
// Upload the diff output as an artifact
jobDefinition.steps.push(projen_1.github.WorkflowSteps.uploadArtifact({
name: 'Upload diff output',
with: {
name: `diff-output-${name}`,
path: 'diff-output/',
retentionDays: 1,
},
}));
return jobDefinition;
}
/**
* Get diff annotation jobs for all environments
* @returns Record of jobs
*/
get diffAnnotationJobs() {
const { environmentVariableName, environments } = this.props.deployOptions;
const jobEntries = environments.map((environmentOptions) => {
return [getDiffAnnotationJobId(environmentOptions.name), this.getDiffAnnotationJobForEnvironment(environmentOptions, environmentVariableName)];
});
const jobs = Object.fromEntries(jobEntries);
jobs['Diff-Annotation-Comment'] = this.getAnnotateDiffJob(Object.keys(jobs));
return jobs;
}
}
exports.DeployableAwsCdkTypeScriptAppStepsFactory = DeployableAwsCdkTypeScriptAppStepsFactory;
_a = JSII_RTTI_SYMBOL_1;
DeployableAwsCdkTypeScriptAppStepsFactory[_a] = { fqn: "deployable-awscdk-app-ts.DeployableAwsCdkTypeScriptAppStepsFactory", version: "0.1.839" };
/**
* Get the deploy job ID for a specific environment
* @param environmentName The name of the environment
* @returns The deploy job ID
*/
function getDeployJobId(environmentName) {
return `Deploy-${environmentName}`;
}
/**
* Get the diff annotation job ID for a specific environment
* @param environmentName The name of the environment
* @returns The diff annotation job ID
*/
function getDiffAnnotationJobId(environmentName) {
return `Diff-Annotation-${environmentName}`;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3RlcHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQTQxQkEsd0NBRUM7QUFPRCx3REFFQzs7QUF2MkJELG1DQUE0QztBQUM1Qyw4Q0FBa0Q7QUFDbEQsdUVBQWdGO0FBQ2hGLHNEQUFpRTtBQUNqRSxtQ0FBa0g7QUFFbEgsTUFBTSwyQkFBMkIsR0FBRyxrQkFBa0IsQ0FBQztBQUN2RCxNQUFNLHNDQUFzQyxHQUFFLFNBQVMsMkJBQTJCLDBDQUEwQyxDQUFDO0FBQzdILE1BQU0sb0NBQW9DLEdBQUcsbUNBQW1DLENBQUM7QUF3Q2pGOzs7R0FHRztBQUNILE1BQWEseUNBQXlDO0lBRXBEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMseUNBQXlDLENBQ3JELGFBQTRCLEVBQzVCLHVCQUEwRDtRQUcxRCxJQUFJLGFBQWEsQ0FBQyxXQUFXLEtBQUsseUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDOUQsTUFBTSxJQUFJLEtBQUssQ0FBQywrRUFBK0UsQ0FBQyxDQUFDO1FBQ25HLENBQUM7UUFFRCxNQUFNLENBQUMsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUM5RCxNQUFNLGNBQWMsR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLGdCQUFnQixHQUFHLHdFQUF3RSxDQUFDLENBQUM7WUFDL0csQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ2pCLE1BQU0saUJBQWlCLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQyxJQUFJ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