Skip to content

Commit

Permalink
fix: move function from index file with IIFE
Browse files Browse the repository at this point in the history
  • Loading branch information
jbw committed Aug 23, 2023
1 parent ac3a885 commit 4f22ecf
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 36 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-unused-expressions': 'warn',
},
};
49 changes: 42 additions & 7 deletions src/cloudformation/stack/cloud-formation-stack.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as AWS from 'aws-sdk';
import { Stack } from 'aws-sdk/clients/cloudformation';
import * as fs from 'fs';

import { CredentialsOptions } from 'aws-sdk/lib/credentials';
import fs from 'fs';
import { AWSWaitForResp } from '../../aws-wait-for-resp';
import { CloudFormationChangeSet } from '../change-set/cloud-formation-change-set';
import {
Expand All @@ -21,12 +20,18 @@ export class CloudFormationStack {

public static createStack(options: CloudFormationStackOptions): CloudFormationStack {
const client = this.createClient(options.client);

return new CloudFormationStack(options.stack, client, new CloudFormationChangeSet(client));
}

public async deploy(): Promise<CloudFormationStackResponse> {
const stack = await this.getStack();
return !stack ? this.create() : this.update(stack);
const stack = await this.getStack(this.stackOptions.name);

if (stack) {
return this.update(stack);
}

return this.create();
}

private async create(): Promise<CloudFormationStackResponse> {
Expand Down Expand Up @@ -61,16 +66,31 @@ export class CloudFormationStack {
params: input,
});

if (waitFor) await this.waitForChangeSetCreation(changeSetName);
if (waitFor) await this.waitForStackUpdate();

return {
status: '200',
stackId: stack.StackId,
};
}

public async getStack(): Promise<Stack | undefined> {
const stackDesc = await this.cf.describeStacks({ StackName: this.stackOptions.name }).promise();
public async getStack(name: string): Promise<Stack | undefined> {
try {
const stackDesc = await this.cf.describeStacks({ StackName: name }).promise();

if (this.stackOptions.waitFor) await this.waitForStackExists();

return stackDesc?.Stacks?.[0];
} catch (e) {
const error = e as AWS.AWSError | undefined;

return stackDesc?.Stacks?.[0];
if (error && error.statusCode === 400 && error.message.includes('does not exist')) {
return undefined;
}

throw e;
}
}

private buildChangeSetInput(stackName: string, changeSetName: string): AWS.CloudFormation.Types.CreateChangeSetInput {
Expand Down Expand Up @@ -165,6 +185,21 @@ export class CloudFormationStack {
return this.cf.waitFor('stackCreateComplete', { StackName: this.stackOptions.name }).promise();
}

private waitForStackUpdate(): Promise<AWSWaitForResp> {
console.debug('Waiting for stack update...');
return this.cf.waitFor('stackUpdateComplete', { StackName: this.stackOptions.name }).promise();
}

private waitForChangeSetCreation(changeSetName: string): Promise<AWSWaitForResp> {
console.debug('Waiting for change set creation...');
return this.cf.waitFor('changeSetCreateComplete', { ChangeSetName: changeSetName }).promise();
}

private waitForStackExists(): Promise<AWSWaitForResp> {
console.debug('Waiting for describe stacks...');
return this.cf.waitFor('stackExists', { StackName: this.stackOptions.name }).promise();
}

private static createClient(options: CloudFormationClientOptions): AWS.CloudFormation {
const cfOptions: AWS.CloudFormation.Types.ClientConfiguration = {
region: options.region,
Expand Down
24 changes: 24 additions & 0 deletions src/createParameterOverrides.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import fs from 'fs';
import path from 'path';

export function createParameterOverrides(parameterOverridesFilePath?: string, parameterOverridesString?: string) {
function loadFile(filepath: string) {
if (!fs.existsSync(filepath)) {
throw new Error(`File ${filepath} does not exist`);
}

const data = fs.readFileSync(filepath, 'utf8');

if (!data) {
throw new Error(`File ${filepath} is empty`);
}

return JSON.parse(data);
}

if (parameterOverridesFilePath) {
return loadFile(path.join(parameterOverridesFilePath));
} else if (parameterOverridesString) {
return JSON.parse(parameterOverridesString);
}
}
24 changes: 1 addition & 23 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,17 @@
import * as core from '@actions/core';
import fs from 'fs';
import path from 'path';

import 'dotenv/config';

import { CloudFormationStack } from './cloudformation/stack/cloud-formation-stack';
import { Template } from './cloudformation/stack/cloud-formation-stack-options';
import { createParameterOverrides } from './createParameterOverrides';

const AWS_ENDPOINT_URL = process.env['AWS_ENDPOINT_URL'];
const AWS_ACCESS_KEY_ID = process.env['AWS_ACCESS_KEY_ID'];
const AWS_SECRET_ACCESS_KEY = process.env['AWS_SECRET_ACCESS_KEY'];
const AWS_REGION = process.env['AWS_DEFAULT_REGION'];

export function createParameterOverrides(parameterOverridesFilePath?: string, parameterOverridesString?: string) {
function loadFile(filepath: string) {
if (!fs.existsSync(filepath)) {
throw new Error(`File ${filepath} does not exist`);
}

const data = fs.readFileSync(filepath, 'utf8');

if (!data) {
throw new Error(`File ${filepath} is empty`);
}

return JSON.parse(data);
}

if (parameterOverridesFilePath) {
return loadFile(path.join(parameterOverridesFilePath));
} else if (parameterOverridesString) {
return JSON.parse(parameterOverridesString);
}
}

export async function run() {
try {
const stackName = core.getInput('stackName');
Expand Down
13 changes: 10 additions & 3 deletions test/deploy.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dotenv/config';
import { CloudFormationStack } from '../src/cloudformation/stack/cloud-formation-stack';
import { CloudFormationStackOptions } from '../src/cloudformation/stack/cloud-formation-stack-options';
import { createParameterOverrides } from '../src/index';

const AWS_ACCESS_KEY_ID = process.env['AWS_ACCESS_KEY_ID'];
const AWS_SECRET_ACCESS_KEY = process.env['AWS_SECRET_ACCESS_KEY'];
Expand Down Expand Up @@ -32,6 +31,7 @@ describe('deploy', () => {
stack: {
name: stackName,
template: { filepath: 'test/test-template.json' },
waitFor: true,
},
client: {
region: 'us-east-1',
Expand All @@ -46,10 +46,14 @@ describe('deploy', () => {
// when
const resp = await stack.deploy();

const stackInfo = await stack.getStack(options.stack.name);

// then
expect(resp.stackId).toContain(stackName);
expect(resp.status).toBe('200');
});
expect(stackInfo?.StackName).toBe(stackName);
expect(stackInfo?.StackStatus).toBe('CREATE_COMPLETE');
}, 500000);

it('should update', async () => {
// given
Expand Down Expand Up @@ -90,11 +94,14 @@ describe('deploy', () => {

const updated = CloudFormationStack.createStack(options);
const resp = await updated.deploy();
const updatedStack = await updated.getStack();
const updatedStack = await updated.getStack(options.stack.name);

// then
expect(resp.stackId).toContain(stackName);
expect(resp.status).toBe('200');
expect(updatedStack?.Parameters).toEqual(options.stack.parameterOverrides);
}, 500000);
});
function createParameterOverrides(parameterOverridesFilePath: string, undefined: undefined) {
throw new Error('Function not implemented.');
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"strict": true,
"noUnusedLocals": true
"noUnusedLocals": false
},
"exclude": ["node_modules", "**/*.spec.ts"],
"include": ["src/**/*.ts"]
Expand Down

0 comments on commit 4f22ecf

Please sign in to comment.