Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript deploy utils #459

Merged
merged 21 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
run: yarn run build
env:
NODE_ENV: production
- name: Check deploy utils
run: yarn deploy-utils
codecov:
name: 'Upload coverage'
needs: lint-test
Expand Down
File renamed without changes.
3 changes: 0 additions & 3 deletions app/tsconfig.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref, join } = require('@mapbox/cloudfriend');
import { ref, join } from '@mapbox/cloudfriend';

module.exports = {
export default {
Type: 'AWS::CloudFront::Distribution',
Properties: {
DistributionConfig: {
Expand Down
4 changes: 2 additions & 2 deletions deploy/stack/DNSRecord.js → deploy/stack/DNSRecord.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref, getAtt, join } = require('@mapbox/cloudfriend');
import { ref, getAtt, join } from '@mapbox/cloudfriend';

module.exports = {
export default {
Type: 'AWS::Route53::RecordSet',
Properties: {
HostedZoneName: join([ref('ProjectDomain'), '.']),
Expand Down
4 changes: 2 additions & 2 deletions deploy/stack/DNSRecordCAA.js → deploy/stack/DNSRecordCAA.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref, join } = require('@mapbox/cloudfriend');
import { ref, join } from '@mapbox/cloudfriend';

module.exports = {
export default {
Type: 'AWS::Route53::RecordSet',
Properties: {
HostedZoneName: join([ref('ProjectDomain'), '.']),
Expand Down
4 changes: 2 additions & 2 deletions deploy/stack/DNSRecordWWW.js → deploy/stack/DNSRecordWWW.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref, getAtt, join } = require('@mapbox/cloudfriend');
import { ref, getAtt, join } from '@mapbox/cloudfriend';

module.exports = {
export default {
// Only create this resource if ProjectDomain and ProjectFQDomain are the same.
// This adds a www.<ProjectDomain> route that works equally.
Condition: 'CreateWWW',
Expand Down
4 changes: 2 additions & 2 deletions deploy/stack/HostedZone.js → deploy/stack/HostedZone.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref, join } = require('@mapbox/cloudfriend');
import { ref, join } from '@mapbox/cloudfriend';

module.exports = {
export default {
Condition: 'CreateHostedZone',
Type: 'AWS::Route53::HostedZone',
Properties: {
Expand Down
4 changes: 2 additions & 2 deletions deploy/stack/S3Bucket.js → deploy/stack/S3Bucket.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref } = require('@mapbox/cloudfriend');
import { ref } from '@mapbox/cloudfriend';

module.exports = {
export default {
Type: 'AWS::S3::Bucket',
Properties: {
BucketName: ref('ProjectFQDomain'),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ref, join } = require('@mapbox/cloudfriend');
import { ref, join } from '@mapbox/cloudfriend';

module.exports = {
export default {
Type: 'AWS::S3::BucketPolicy',
Properties: {
Bucket: ref('ProjectFQDomain'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
* It piggybacks off work done by these fine folks: https://github.com/binxio/cfn-certificate-provider
*/

const { ref, join, getAtt, region, sub } = require('@mapbox/cloudfriend');
import { ref, join, getAtt, region, sub } from '@mapbox/cloudfriend';

const config = require('../../config');
import config from '../../config';

module.exports = {
export default {
Certificate: {
Type: 'Custom::Certificate',
Properties: {
Expand Down
28 changes: 13 additions & 15 deletions deploy/template.js → deploy/template.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const { ref, equals } = require('@mapbox/cloudfriend');
import { ref, equals } from '@mapbox/cloudfriend';

const HostedZone = require('./stack/HostedZone');
const DNSRecord = require('./stack/DNSRecord');
const DNSRecordWWW = require('./stack/DNSRecordWWW');
const DNSRecordCAA = require('./stack/DNSRecordCAA');
const CloudFrontDistribution = require('./stack/CloudFrontDistribution');
const S3Bucket = require('./stack/S3Bucket');
const S3BucketPolicy = require('./stack/S3BucketPolicy');
const ValidatedCertificate = require('./stack/ValidatedCertificate');
const config = require('../config');
import HostedZone from './stack/HostedZone';
import DNSRecord from './stack/DNSRecord';
import DNSRecordWWW from './stack/DNSRecordWWW';
import DNSRecordCAA from './stack/DNSRecordCAA';
import CloudFrontDistribution from './stack/CloudFrontDistribution';
import S3Bucket from './stack/S3Bucket';
import S3BucketPolicy from './stack/S3BucketPolicy';
import ValidatedCertificate from './stack/ValidatedCertificate';
import config from '../config';

const template = {
const tpl = {
Description: `CloudFormation stack for ${config.ProjectName} project`,
AWSTemplateFormatVersion: '2010-09-09',
Parameters: {
Expand Down Expand Up @@ -43,7 +43,5 @@ const template = {
},
};

module.exports = {
template: JSON.stringify(template),
parameters: Object.keys(template.Parameters),
};
export const template = JSON.stringify(tpl);
export const parameters = Object.keys(tpl.Parameters);
122 changes: 122 additions & 0 deletions deploy/types/cloudfriend.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
declare module '@mapbox/cloudfriend' {
/**
* [The intrinsic function Ref](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html)
* returns the value of the specified parameter or resource.
*
* @static
* @memberof cloudfriend
* @name ref
* @param {string} name - The logical name of the resource or parameter you want
* to dereference.
* @returns The physical ID of the resource or the value of the parameter.
*/
export function ref(name: string): {
Ref: string;
};

/**
* [The intrinsic function Fn::Join](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-join.html)
* appends a set of values into a single value, separated by the specified
* delimiter. If a delimiter is the empty string, the set of values are
* concatenated with no delimiter.
*
* @static
* @memberof cloudfriend
* @name join
* @param {string} [delimiter=''] The value you want to occur between fragments.
* @param {array} pieces - The list of values you want combined.
* The delimiter will occur between fragments only. It will not terminate the
* final value.
* @returns The combined string.
*/
export function join(pieces: unknown[]): {
'Fn::Join': (string | unknown[])[];
};
export function join(
delimiter: string,
pieces: unknown[],
): {
'Fn::Join': (string | unknown[])[];
};
/**
* [The intrinsic function Fn::GetAtt](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html)
* returns the value of an attribute from a resource in the template.
*
* @static
* @memberof cloudfriend
* @name getAtt
* @param {string} obj - The logical name of the resource that contains the
* attribute you want.
* @param {string} key - The name of the resource-specific attribute whose value
* you want. See the resource's reference page for details about the attributes
* available for that resource type.
* @returns The attribute value.
*/
export function getAtt(
obj: string,
key: string,
): {
'Fn::GetAtt': string[];
};
/**
* [The condition Fn::Equals](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#d0e121788)
* compares if two values are equal. Returns true if the two values are equal or
* false if they aren't.
*
* @static
* @memberof cloudfriend
* @name equals
* @param {unknown} a - A value of any type that you want to compare.
* @param {unknown} b - A value of any type that you want to compare.
* @returns true if the two values are equal or false if they aren't
*/
export function equals(
a: unknown,
b: unknown,
): {
'Fn::Equals': unknown[];
};
/**
* [The intrinsic function Sub](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html)
* substitutes variables in an input string with values that you specify. In
* your templates, you can use this function to construct commands or outputs
* that include values that aren't available until you create or update a stack.
*
* @static
* @memberof cloudfriend
* @name sub
* @param {string} str - A string with variables that AWS CloudFormation
* substitutes with their associated values at runtime. Write variables as
* ${MyVarName}. Variables can be template parameter names, resource logical
* IDs, resource attributes, or a variable in a key-value map. If you specify
* only template parameter names, resource logical IDs, and resource attributes,
* don't specify a key-value map.
* If you specify template parameter names or resource logical IDs, such as
* ${InstanceTypeParameter}, AWS CloudFormation returns the same values as if
* you used the Ref intrinsic function. If you specify resource attributes,
* such as ${MyInstance.PublicIp}, AWS CloudFormation returns the same values
* as if you used the Fn::GetAtt intrinsic function.
* To write a dollar sign and curly braces (${}) literally, add an exclamation
* point (!) after the open curly brace, such as ${!Literal}. AWS CloudFormation
* resolves this text as ${Literal}.
* @param {object} [variables] - An object where each key is the name of a
* variable that you included in the String parameter, and each value is the
* value that AWS CloudFormation substitutes for the associated variable name
* at runtime.
* @returns
*/
export function sub(
str: string,
variables?: object,
):
| {
'Fn::Sub': string;
}
| {
'Fn::Sub': unknown[];
};

export function region(): {
Ref: 'AWS:Region';
};
}
16 changes: 0 additions & 16 deletions deploy/utils/bucketExists.js

This file was deleted.

15 changes: 15 additions & 0 deletions deploy/utils/bucketExists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { S3Client, HeadBucketCommand } from '@aws-sdk/client-s3';

import config from '../../config';

export default async () => {
const s3 = new S3Client({ region: config.Region });
const cmd = new HeadBucketCommand({ Bucket: config.ProjectFQDomain });

try {
await s3.send(cmd);
console.log('true');
} catch {
console.log('false');
}
};
4 changes: 4 additions & 0 deletions deploy/utils/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function getErrorMessage(error: unknown) {
if (error instanceof Error) return error.message;
return String(error);
}
10 changes: 7 additions & 3 deletions deploy/utils/index.js → deploy/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
const invalidate = require('./invalidate');
const launch = require('./launch');
const bucketExists = require('./bucketExists');
import invalidate from './invalidate';
import launch from './launch';
import bucketExists from './bucketExists';

const utilName = process.argv[2];
(() => {
if (!utilName) {
console.log('invalidate | launch | bucketExists');
return null;
}
switch (utilName) {
case 'invalidate':
return invalidate();
Expand Down
54 changes: 0 additions & 54 deletions deploy/utils/invalidate.js

This file was deleted.

Loading