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

feat: upgrade SST version and migrate to SST app setup #50

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
5 changes: 3 additions & 2 deletions .github/workflows/deploy-dev-apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ on:
jobs:
build:
runs-on: ubuntu-latest
environment: DEVELOPMENT
env:
REACT_APP_TOWNHUB_API_ENDPOINT: ${{ secrets.TOWNHUB_DEV_API_ENDPOINT }}
REACT_APP_TOWNHUB_API_ENDPOINT: ${{ secrets.TOWNHUB_API_ENDPOINT }}
REACT_APP_MAP_BOX_API_KEY: ${{ secrets.MAP_BOX_API_KEY }}
NODE_OPTIONS: --max-old-space-size=4096
steps:
Expand Down Expand Up @@ -41,4 +42,4 @@ jobs:
# https://github.com/typescript-eslint/typescript-eslint/issues/2714
run: CI=false yarn run build:apps
- name: Upload to S3
run: aws s3 sync apps/web/build ${{ secrets.TOWNHUB_DEV_APP_BUCKET_S3_URL }} --acl public-read
run: aws s3 sync apps/web/build ${{ secrets.TOWNHUB_APP_BUCKET_S3_URL }} --acl public-read
3 changes: 3 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
"@testing-library/user-event": "^12.1.10",
"@types/leaflet": "^1.5.19",
"@types/node": "^12.0.0",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react-router-dom": "^5.3.2",
"eslint-config-react-app": "^6.0.0",
"react-scripts": "4.0.3"
},
Expand Down
10 changes: 9 additions & 1 deletion infrastructure/cdk/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,23 @@

# production
/build
cdk.out
cdk.context.json

# typescript
*.js
src/*.js
lib/*.js
*.d.ts

# misc
.DS_Store

# sst build output
.build
.sst/artifacts*

.idea

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Expand Down
21 changes: 0 additions & 21 deletions infrastructure/cdk/lib/api-gateway.spec.ts

This file was deleted.

99 changes: 0 additions & 99 deletions infrastructure/cdk/lib/api-gateway.ts

This file was deleted.

45 changes: 45 additions & 0 deletions infrastructure/cdk/lib/core-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Stack, StackProps, App, Api } from '@serverless-stack/resources';
import { StaticSite } from './resources';

export interface CoreStackProps extends StackProps {
/** The root domain name, used to lookup a Route53 Hosted Zone */
rootDomainName: string;
/** The list of subdomains where the application can be accessed */
appSubdomains: string[];
}

/**
* A Stack that defines the core resources that should not change often and is
* used by all services.
*/
export default class CoreStack extends Stack {
/** The api endpoint to be used by other services adding new APIs */
api: Api;

constructor(
scope: App,
id: string,
{ rootDomainName, appSubdomains, ...props }: CoreStackProps
) {
super(scope, id, props);

/*************************************************************************
* API Gateway for the backend
*************************************************************************/
const apiDomainName = `api.${rootDomainName}`;
this.api = new Api(this, 'Api', {
customDomain: {
domainName: apiDomainName,
hostedZone: rootDomainName,
},
});

/*************************************************************************
* Static site hosting for the frontend app
*************************************************************************/
new StaticSite(this, 'App', {
rootDomainName,
subdomains: appSubdomains,
});
}
}
32 changes: 11 additions & 21 deletions infrastructure/cdk/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
import { App } from '@serverless-stack/resources';
import ApiGatewayStack from './api-gateway';
import StaticSiteStack from './static-site';
import ShuttlesStack from './modules/shuttles';
import TownsStack from './modules/towns';
import { TownsStack } from './modules';
import CoreStack from './core-stack';

export default function main(app: App): void {
const rootDomainName = 'townhub.ca';
const rootDomainName =
app.stage === 'prod' ? 'townhub.ca' : `${app.stage}.townhub.ca`;

new ApiGatewayStack(app, 'ApiGatewayStack', {
const core = new CoreStack(app, 'TownhubCore', {
rootDomainName,
// Setup subdomains for each town in the system
// TODO: Eventually, might move this into a Lambda function that adds a new
// subdomain every time we create a new town in the database, or have a
// script that polls DDB for the latest list before running this.
appSubdomains: ['fernie', 'revelstoke'],
});

new StaticSiteStack(app, 'StaticHomePageStack', {
rootDomainName,
});

new ShuttlesStack(app, 'module-shuttle');
new TownsStack(app, 'module-town');

// Setup subdomains for each town in the system
// TODO: Eventually, might move this into a Lambda function that adds a new
// subdomain every time we create a new town in the database, or have a
// script that polls DDB for the latest list before running this.
new StaticSiteStack(app, 'StaticAppPageStack', {
rootDomainName,
subdomains: ['fernie', 'revelstoke'],
});
new TownsStack(app, 'TownsModule', { api: core.api });
}
5 changes: 5 additions & 0 deletions infrastructure/cdk/lib/modules/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Api, StackProps } from '@serverless-stack/resources';

export interface ServiceStackProps extends StackProps {
api: Api;
}
1 change: 1 addition & 0 deletions infrastructure/cdk/lib/modules/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './towns';
38 changes: 30 additions & 8 deletions infrastructure/cdk/lib/modules/towns.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
import { App, Stack, StackProps } from '@serverless-stack/resources';
import { TownhubTable } from '../resources/table';
import { App, Stack, TableFieldType } from '@serverless-stack/resources';
import { TOWNS_DATABASE } from '@townhub-libs/towns';
import { TownhubTable } from '../resources';
import { ServiceStackProps } from './base';

interface TownsServiceProps extends ServiceStackProps {}

/**
* A Stack containing all the static infrastructure for the towns feature
* of Townhub.
*
* @output TownsTableName, TownsTableArn
*/
export default class TownsStack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
export class TownsStack extends Stack {
constructor(scope: App, id: string, { api, ...props }: TownsServiceProps) {
super(scope, id, props);

// Create the different tables for this module
new TownhubTable(this, 'Towns', { stage: scope.stage });
/*************************************************************************
* Databases
*************************************************************************/
const TownsTable = new TownhubTable(this, `${id}TownsTable`, {
stage: scope.stage,
fields: { hid: TableFieldType.STRING },
primaryIndex: { partitionKey: 'hid' },
});

/*************************************************************************
* API Endpoints
*************************************************************************/
api.addRoutes(this, {
'GET /towns/hid/{townHid}': {
function: {
srcPath: 'src/towns/',
handler: 'get-by-hid.main',
environment: { [TOWNS_DATABASE.ENV]: TownsTable.tableName },
permissions: [TownsTable],
},
},
});
}
}
18 changes: 18 additions & 0 deletions infrastructure/cdk/lib/modules/transit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { App, Stack } from '@serverless-stack/resources';
import { ServiceStackProps } from './base';

interface TransitServiceProps extends ServiceStackProps {}

/**
* A Stack containing all the static infrastructure for the transit feature
* of Townhub.
*/
export default class TransitStack extends Stack {
constructor(scope: App, id: string, { api, ...props }: TransitServiceProps) {
super(scope, id, props);

api.addRoutes(this, {
'GET /transit/daily/{timestamp}': 'src/handler.main',
});
}
}
2 changes: 2 additions & 0 deletions infrastructure/cdk/lib/resources/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './static-site';
export * from './table';
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,30 @@ import { getDomainNameList } from './helpers';
describe('getDomainNameList Helper', () => {
const rootDomainName = 'example.com';
it('should return the rootdomain on prod without subdomain', () => {
const res = getDomainNameList('prod', rootDomainName);
const res = getDomainNameList(rootDomainName);

expect(res).toEqual([rootDomainName]);
});

it('should return the rootdomain on dev without subdomain', () => {
const res = getDomainNameList('dev', rootDomainName);
const res = getDomainNameList(rootDomainName);

expect(res).toEqual([`dev.${rootDomainName}`]);
});

it('should return the subdomain on prod', () => {
const res = getDomainNameList('prod', rootDomainName, ['test']);
const res = getDomainNameList(rootDomainName, ['test']);

expect(res).toEqual([`test.${rootDomainName}`]);
});
it('should return the subdomain on dev', () => {
const res = getDomainNameList('dev', rootDomainName, ['test']);
const res = getDomainNameList(rootDomainName, ['test']);

expect(res).toEqual([`test.dev.${rootDomainName}`]);
});

it('should return the list of subdomains on prod', () => {
const res = getDomainNameList('prod', rootDomainName, [
'test',
'dev',
'stage',
]);
const res = getDomainNameList(rootDomainName, ['test', 'dev', 'stage']);

expect(res).toEqual([
`test.${rootDomainName}`,
Expand All @@ -39,11 +35,7 @@ describe('getDomainNameList Helper', () => {
]);
});
it('should return the list of subdomains on dev', () => {
const res = getDomainNameList('dev', rootDomainName, [
'test',
'dev',
'stage',
]);
const res = getDomainNameList(rootDomainName, ['test', 'dev', 'stage']);

expect(res).toEqual([
`test.dev.${rootDomainName}`,
Expand Down
Loading