Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.

Commit d568d82

Browse files
branberryseungpark
andauthored
[DOP-3726]: Update Autobuilder to process messages from queue for enhanced infrastructure (#831)
* [DOP-3639]: Create base API construct * [DOP-3639]: Create ts files to export specific lambda handler * [DOP-3639]: Create ts files to export specific lambda handler * [DOP-3639]: Create methods for triggering builds * [DOP-3639]: Remove the jobQueue as an attribute for the webhooks construct * [DOP-3639]: Rename construct to better reflect what it represents * [DOP-3639]: Use correct path * [DOP-3639]: Retrieve SSM params * [DOP-3639]: Add DB name * [DOP-3639]: Add dochub env vars * [DOP-3639]: Add correct dochub path * [DOP-3639]: use correct method to retrieve secure strings * [DOP-3639]: Delete zip script in favor of using NodejsFunction construct * [DOP-3639]: Update esbuild config for nodejsfunctions * [DOP-3639]: Remove bundle script and handlers * [DOP-3639]: Get tests working * [DOP-3639]: Delete handlers and remove zip script * [DOP-3639]: refactor so that queues are a separate construct from the api * [DOP-3639]: add correct identifiers for constructs * [DOP-3639]: Update comments for bundling * [DOP-3639]: Update tests * [DOP-3639]: Clean up some typing * [DOP-3639]: Add script to bundle lambda config with zip * [DOP-3639]: Add permission to execute script * [DOP-3639]: rename file * [DOP-3639]: Use the regular function construct again and update bundling script * [DOP-3639]: Add updated script and add snapshot test * [DOP-3639]: Add updated script * [DOP-3639]: Prune dev dependencies when deploying lambda * [DOP-3639]: Add slack auth token * [DOP-3639]: Add queue urls as env vars * [DOP-3639]: Grab DB info from ssm * [DOP-3639]: Update env vars * [DOP-3639]: Remove cdk.context.json * [DOP-3639]: Update gitignore and use valueFromLookup * [DOP-3639]: Refactor code to successfully deploy and use config variables * [DOP-3639]: Remove unnecessary build command * [DOP-3639]: Remove unnecessary build script * [DOP-3639]: Refactor env vars into separate construct * [DOP-3639]: Remove build.zip from gitignore * [DOP-3639]: Remove bundle command * [DOP-3680]: Add v2 handlers * [DOP-3680]: Use v2 handlers * [DOP-3680]: Revert slack v1 * [DOP-3639]: Remove additional slash * [DOP-3639]: Remove unused params * [DOP-3639]: Remove unused import * [DOP-3639]: Use esModuleInterop * [DOP-3640]: Rename to simplify stuff * [DOP-3640]: Add util to get bucket names * [DOP-3640]: Add task definition for fargate and create cluster * [DOP-3640]: Refactor Stack and constructs * [DOP-3640]: Add CDK infra to docker ignore * [DOP-3640]: Rename files to be less generic and add task definition for lambdas * [DOP-3640]: Work on creating bucket constructs * [DOP-3640]: destroy buckets when tearing down * [DOP-3640]: Grant ecs task permission to read and write from buckets * [DOP-3640]: Add VPC endpoint for ECR * [DOP-3640]: Add custom dockerfile for testing enhanced app * [DOP-3640]: Refactor path names to take into account the environment * [DOP-3640]: Add a bunch of env vars * [DOP-3640]: Add a bunch of env vars for worker * [DOP-3640]: Remove unused env var * [DOP-3640]: Refactor object destructure for consistency * [DOP-3640]: Add first routing rule * [DOP-3640]: Add routing rules for root bucket * [DOP-3640]: Refactor container props to be a little nicer * [DOP-3640]: Add feature branch deploy logic * [DOP-3640]: Add env to worker * [DOP-3640]: Move stuff around and work on getting secure strings using aws sdk * [DOP-3640]: Add SSM client SDK to query secure strings * [DOP-3640]: Add remaining secure strings and refactor stack to use async ssm client * [DOP-3640]: Grant permissions to the ECS cluster to read and write to queues * [DOP-3640]: Add Tag for stack to help debug costs * [DOP-3640]: Refactor layout to be a bit simpler * [DOP-3640]: Refactor enhanced job to check for correct job type * [DOP-3640]: Remove unnecesssary code * [DOP-3640]: Update readme * [DOP-3640]: Update prettier to ignore cdk-infra * [DOP-3640]: Add functionality to execute a single job for enhanced app * [DOP-3640]: Use clustername for task definition family (that's the value that is actually used) * [DOP-3726]: Modify HandleJobs to not create ecs tasks * [DOP-3640]: Refactor enhanced job to check for correct job type * [DOP-3726]: Move the additional notification out of the insertBulkJobs * [DOP-3726]: Update typing to get rid of type errors in github webhooks * [DOP-3640]: Update README * [DOP-3726]: Job status is not needed in the jobsQueue * [DOP-3726]: Wait only one second for queue polling * [DOP-3726]: Wait only four seconds for queue polling * [DOP-3726]: Add enhanced job handler so that we can specify s3 buckets for custom feature stacks * [DOP-3726]: rename files * [DOP-3726]: Use enhancedApp buckets * [DOP-3726]: Add dash * [DOP-3726]: Use correct env variables for db * [DOP-3726]: Add queue collection name * [DOP-3726]: Update timeout for lambdas * [DOP-3726]: Remove extra console logs and add missing env variable for repo branches collection * [DOP-3726]: Remove enhanced since it doesn't impact anything * [DOP-3726]: Remove enhanced since it doesn't impact anything * [DOP-3726]: Remove extra log statement * [DOP-3640]: Update readme and rename context variables * [DOP-3640]: Refactor how environment variables are retrieved to not depend on current scope * [DOP-3640]: Add routing rule for 1.1.4 of atlas cli * [DOP-3640]: Call initContextVars * [DOP-3726]: Re-introduce enhanced env var for worker and remove aws credentials from env * [DOP-3726]: Add esbuild as a dev dependency * [DOP-3726]: Update dockerfile to build more quickly * [DOP-3726]: Resolve additional merge conflicts * [DOP-3726]: Resolve additional merge conflicts * [DOP-3726]: Resolve additional merge conflicts * [DOP-3726]: Resolve additional merge conflicts * [DOP-3726]: Resolve additional merge conflicts * [DOP-3726]: Update index * [DOP-3726]: Update API name to be more identifiable in aws console * [DOP-3726]: Resolve merge conflict * [DOP-3726]: Refactor enhanced job handler factory * Empty-Commit * test * [DOP-3726]: Update enhanced dockerfile * [DOP-3726]: Remove private --------- Co-authored-by: Seung Park <[email protected]>
1 parent de16bf4 commit d568d82

File tree

21 files changed

+917
-33
lines changed

21 files changed

+917
-33
lines changed

Dockerfile.enhanced

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ WORKDIR /home/docsworker-xlarge
44
COPY config config/
55
COPY package*.json ./
66
COPY tsconfig*.json ./
7-
RUN npm install
7+
RUN npm ci
88
COPY . ./
99
RUN npm run build
1010

1111
# install persistence module
1212
RUN cd ./modules/persistence \
13-
&& npm install \
13+
&& npm ci --legacy-peer-deps \
1414
&& npm run build
1515

1616
# Build modules
1717
# OAS Page Builder
1818
RUN cd ./modules/oas-page-builder \
19-
&& npm install \
19+
&& npm ci --legacy-peer-deps \
2020
&& npm run build
2121

2222
# where repo work will happen
@@ -102,14 +102,14 @@ RUN mkdir -p modules/persistence && chmod 755 modules/persistence
102102
COPY --from=ts-compiler --chown=docsworker-xlarge /home/docsworker-xlarge/modules/persistence/package*.json ./modules/persistence/
103103
COPY --from=ts-compiler --chown=docsworker-xlarge /home/docsworker-xlarge/modules/persistence/dist ./modules/persistence/
104104
ENV PERSISTENCE_MODULE_PATH=${WORK_DIRECTORY}/modules/persistence/index.js
105-
RUN cd ./modules/persistence/ && ls && npm install
105+
RUN cd ./modules/persistence/ && ls && npm ci --legacy-peer-deps
106106

107107
# OAS Page Builder module copy
108108
# Create directory and add permissions to allow node module installation
109109
RUN mkdir -p modules/oas-page-builder && chmod 755 modules/oas-page-builder
110110
COPY --from=ts-compiler --chown=docsworker-xlarge /home/docsworker-xlarge/modules/oas-page-builder/package*.json ./modules/oas-page-builder/
111111
COPY --from=ts-compiler --chown=docsworker-xlarge /home/docsworker-xlarge/modules/oas-page-builder/dist ./modules/oas-page-builder/
112-
RUN cd ./modules/oas-page-builder/ && npm install
112+
RUN cd ./modules/oas-page-builder/ && npm ci --legacy-peer-deps
113113

114114
# Needed for OAS Page Builder module in shared.mk
115115
ENV REDOC_PATH=${WORK_DIRECTORY}/redoc/cli/index.js

api/controllers/v2/github.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { APIGatewayEvent, APIGatewayProxyResult } from 'aws-lambda';
66
import { JobRepository } from '../../../src/repositories/jobRepository';
77
import { ConsoleLogger } from '../../../src/services/logger';
88
import { BranchRepository } from '../../../src/repositories/branchRepository';
9-
import { Job, JobStatus } from '../../../src/entities/job';
9+
import { EnhancedJob, JobStatus } from '../../../src/entities/job';
1010
import { PushEvent } from '@octokit/webhooks-types';
1111

1212
// This function will validate your payload from GitHub
@@ -29,7 +29,7 @@ async function prepGithubPushPayload(
2929
githubEvent: PushEvent,
3030
branchRepository: BranchRepository,
3131
prefix: string
32-
): Promise<Omit<Job, '_id'>> {
32+
): Promise<Omit<EnhancedJob, '_id'>> {
3333
const branch_name = githubEvent.ref.split('/')[2];
3434
const branch_info = await branchRepository.getRepoBranchAliases(githubEvent.repository.name, branch_name);
3535
const urlSlug = branch_info.aliasObject?.urlSlug ?? branch_name;
@@ -39,7 +39,7 @@ async function prepGithubPushPayload(
3939
return {
4040
title: githubEvent.repository.full_name,
4141
user: githubEvent.pusher.name,
42-
email: githubEvent.pusher.email,
42+
email: githubEvent.pusher.email ?? '',
4343
status: JobStatus.inQueue,
4444
createdTime: new Date(),
4545
startTime: null,
@@ -111,6 +111,7 @@ export const TriggerBuild = async (event: APIGatewayEvent): Promise<APIGatewayPr
111111
try {
112112
consoleLogger.info(job.title, 'Creating Job');
113113
const jobId = await jobRepository.insertJob(job, c.get('jobsQueueUrl'));
114+
jobRepository.notify(jobId, c.get('jobUpdatesQueueUrl'), JobStatus.inQueue, 0);
114115
consoleLogger.info(job.title, `Created Job ${jobId}`);
115116
} catch (err) {
116117
return {

api/controllers/v2/jobs.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,15 @@ export const HandleJobs = async (event: SQSEvent): Promise<void> => {
6565
switch (jobStatus) {
6666
case JobStatus[JobStatus.inQueue]:
6767
await NotifyBuildProgress(jobId);
68-
// start the task , don't start the process before processing the notification
69-
const ecsServices = new ECSContainer(c, consoleLogger);
70-
const res = await ecsServices.execute(jobId);
71-
if (res) {
72-
await saveTaskId(jobId, res, consoleLogger);
73-
}
74-
consoleLogger.info(jobId, JSON.stringify(res));
7568
break;
7669
case JobStatus[JobStatus.inProgress]:
7770
await NotifyBuildProgress(jobId);
7871
break;
7972
case JobStatus[JobStatus.timedOut]:
8073
await NotifyBuildSummary(jobId);
8174
const taskId = body['taskId'];
75+
// for the enhanced application, the taskId will never be defined
76+
// as we are not saving it at this time
8277
if (taskId) {
8378
await stopECSTask(taskId, consoleLogger);
8479
}

api/controllers/v2/slack.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ConsoleLogger, ILogger } from '../../../src/services/logger';
66
import { SlackConnector } from '../../../src/services/slack';
77
import { JobRepository } from '../../../src/repositories/jobRepository';
88
import { APIGatewayEvent, APIGatewayProxyResult } from 'aws-lambda';
9+
import { JobStatus } from '../../../src/entities/job';
910

1011
function isUserEntitled(entitlementsObject: any): boolean {
1112
return (entitlementsObject?.repos?.length ?? 0) > 0;
@@ -99,6 +100,13 @@ export const DisplayRepoOptions = async (event: APIGatewayEvent): Promise<APIGat
99100
async function deployRepo(deployable: Array<any>, logger: ILogger, jobRepository: JobRepository, jobQueueUrl) {
100101
try {
101102
await jobRepository.insertBulkJobs(deployable, jobQueueUrl);
103+
104+
// we need to also notify the jobUpdatesQueue as well so that slack users get notified
105+
await Promise.all(
106+
deployable.map(async ({ jobId }) => {
107+
await jobRepository.notify(jobId, c.get('jobUpdatesQueueUrl'), JobStatus.inQueue, 0);
108+
})
109+
);
102110
} catch (err) {
103111
logger.error('deployRepo', err);
104112
}

cdk-infra/lib/constructs/api/webhook-api-construct.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { Duration } from 'aws-cdk-lib';
12
import { Cors, CorsOptions, LambdaIntegration, LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
23
import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda';
34
import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
45
import { BundlingOptions, NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
56
import { IQueue } from 'aws-cdk-lib/aws-sqs';
67
import { Construct } from 'constructs';
78
import path from 'path';
9+
import { getFeatureName } from '../../../utils/env';
810

911
const HANDLERS_PATH = path.join(__dirname, '/../../../../api/controllers/v2');
1012

@@ -35,12 +37,15 @@ export class WebhookApiConstruct extends Construct {
3537
constructor(scope: Construct, id: string, { jobsQueue, jobUpdatesQueue, environment }: WebhookApiConstructProps) {
3638
super(scope, id);
3739

40+
const timeout = Duration.minutes(2);
41+
3842
const slackTriggerLambda = new NodejsFunction(this, 'slackTriggerLambda', {
3943
entry: `${HANDLERS_PATH}/slack.ts`,
4044
runtime,
4145
handler: 'DeployRepo',
4246
environment,
4347
bundling,
48+
timeout,
4449
});
4550

4651
const slackDisplayRepoLambda = new NodejsFunction(this, 'slackDisplayRepoLambda', {
@@ -49,13 +54,15 @@ export class WebhookApiConstruct extends Construct {
4954
handler: 'DeployRepoDisplayRepoOptions',
5055
environment,
5156
bundling,
57+
timeout,
5258
});
5359

5460
const dochubTriggerUpsertLambda = new NodejsFunction(this, 'dochubTriggerUpsertLambda', {
5561
entry: `${HANDLERS_PATH}/dochub.ts`,
5662
runtime,
5763
handler: 'UpsertEdgeDictionaryItem',
5864
environment,
65+
timeout,
5966
});
6067

6168
const githubTriggerLambda = new NodejsFunction(this, 'githubTriggerLambda', {
@@ -64,6 +71,7 @@ export class WebhookApiConstruct extends Construct {
6471
handler: 'TriggerBuild',
6572
bundling,
6673
environment,
74+
timeout,
6775
});
6876

6977
const triggerLocalBuildLambda = new NodejsFunction(this, 'triggerLocalBuildLambda', {
@@ -72,6 +80,7 @@ export class WebhookApiConstruct extends Construct {
7280
handler: 'TriggerLocalBuild',
7381
environment,
7482
bundling,
83+
timeout,
7584
});
7685

7786
const handleJobsLambda = new NodejsFunction(this, 'handleJobsLambda', {
@@ -87,9 +96,12 @@ export class WebhookApiConstruct extends Construct {
8796
code: Code.fromInline('exports.default = (event) => { console.log("hello, world!!"); }'),
8897
runtime,
8998
handler: 'RootEndpointLambda',
99+
timeout,
90100
});
91101

92-
const restApi = new LambdaRestApi(this, 'webhookHandlers', {
102+
const apiName = `webhookHandlers-${getFeatureName()}`;
103+
104+
const restApi = new LambdaRestApi(this, apiName, {
93105
handler: rootEndpointLambda,
94106
proxy: false,
95107
});

cdk-infra/lib/constructs/api/webhook-env-construct.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ export class WebhookEnvConstruct extends Construct {
1919
const dbName = StringParameter.valueFromLookup(this, `${ssmPrefix}/atlas/dbname`);
2020
const dbUsername = StringParameter.valueFromLookup(this, `${ssmPrefix}/atlas/username`);
2121
const dbHost = StringParameter.valueFromLookup(this, `${ssmPrefix}/atlas/host`);
22+
const jobCollection = StringParameter.valueFromLookup(this, `${ssmPrefix}/atlas/collections/job/queue`);
2223

23-
const dbPassword = secureStrings[`${ssmPrefix}/atlas/password`];
24+
const dbPassword = secureStrings['MONGO_ATLAS_PASSWORD'];
2425
this.environment = {
2526
...secureStrings,
2627
MONGO_ATLAS_USERNAME: dbUsername,
2728
MONGO_ATLAS_PASSWORD: dbPassword,
2829
MONGO_ATLAS_URL: `mongodb+srv://${dbUsername}:${dbPassword}@${dbHost}/admin?retryWrites=true`,
2930
DB_NAME: dbName,
30-
31+
JOB_QUEUE_COL_NAME: jobCollection,
3132
NODE_CONFIG_DIR: './config',
3233
JOBS_QUEUE_URL: jobsQueue.queueUrl,
3334
JOB_UPDATES_QUEUE_URL: jobUpdatesQueue.queueUrl,

cdk-infra/lib/constructs/worker/worker-construct.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export class WorkerConstruct extends Construct {
8383

8484
const taskDefLogGroup = new LogGroup(this, 'workerLogGroup');
8585
const taskDefinition = new FargateTaskDefinition(this, 'workerTaskDefinition', {
86-
cpu: 2048,
86+
cpu: 4096,
8787
memoryLimitMiB: 8192,
8888
taskRole,
8989
executionRole,

cdk-infra/lib/constructs/worker/worker-env-construct.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { IQueue } from 'aws-cdk-lib/aws-sqs';
22
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
33
import { Construct } from 'constructs';
44
import { getCdnInvalidatorUrl } from '../../../utils/cdn';
5-
import { getEnv, envShortToFullName } from '../../../utils/env';
5+
import { getEnv, envShortToFullName, getIsEnhanced } from '../../../utils/env';
66
import { getSearchIndexFolder } from '../../../utils/search-index';
77
import { getSsmPathPrefix } from '../../../utils/ssm';
88

@@ -39,13 +39,13 @@ export class WorkerEnvConstruct extends Construct {
3939
const repoBranchesCollection = StringParameter.valueFromLookup(this, `${ssmPrefix}/atlas/collections/repo`);
4040
const jobCollection = StringParameter.valueFromLookup(this, `${ssmPrefix}/atlas/collections/job/queue`);
4141

42-
const dbPassword = secureStrings[`${ssmPrefix}/atlas/password`];
43-
42+
const dbPassword = secureStrings['MONGO_ATLAS_PASSWORD'];
4443
this.environment = {
4544
...secureStrings,
4645
STAGE: env,
4746
SNOOTY_ENV: envShortToFullName(env),
4847
MONGO_ATLAS_USERNAME: dbUsername,
48+
MONGO_ATLAS_HOST: dbHost,
4949
MONGO_ATLAS_URL: `mongodb+srv://${dbUsername}:${dbPassword}@${dbHost}/admin?retryWrites=true`,
5050
DB_NAME: dbName,
5151
JOBS_QUEUE_URL: jobsQueue.queueUrl,
@@ -55,11 +55,12 @@ export class WorkerEnvConstruct extends Construct {
5555
PREVIEW_BUILD_ENABLED: previewBuildEnabled,
5656
USER_ENTITLEMENT_COL_NAME: entitlementCollection,
5757
NPM_EMAIL: npmEmail,
58-
REPO_BRANCHES_COLLECTION: repoBranchesCollection,
58+
REPO_BRANCHES_COL_NAME: repoBranchesCollection,
5959
JOB_QUEUE_COL_NAME: jobCollection,
6060
CDN_INVALIDATOR_SERVICE_URL: getCdnInvalidatorUrl(env),
6161
SEARCH_INDEX_BUCKET: 'docs-search-indexes-test',
6262
SEARCH_INDEX_FOLDER: getSearchIndexFolder(env),
63+
ENHANCED: `${getIsEnhanced()}`,
6364
};
6465
}
6566
}

0 commit comments

Comments
 (0)