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

Commit b8fdd7d

Browse files
authored
[fix] Update to node 18 in straggling references (#815)
* [fix] Update to node 18 in straggling references * Revert "[DOP-3638]: Transpile API handlers from TS to JS (#800)" This reverts commit 08bb923. * [fix] Prune lambdas before deployment * fixup * fixup * Update deploy-stg-ecs.yml * 1:1 prd and stg deploy action
1 parent 9991af6 commit b8fdd7d

File tree

15 files changed

+8566
-18746
lines changed

15 files changed

+8566
-18746
lines changed

.github/workflows/deploy-prd-ecs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- uses: actions/checkout@v2
1414
- uses: actions/setup-node@v1
1515
with:
16-
node-version: '14.x'
16+
node-version: '18.x'
1717
- name: Install Serverless Framework
1818
run: npm install -g serverless
1919
- name: Serverless AWS authentication
@@ -68,3 +68,4 @@ jobs:
6868
npm ci
6969
sls deploy --stage prd
7070
sls deploy --stage dotcomprd
71+
sls prune -n 5

.github/workflows/deploy-stg-ecs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ jobs:
6666
sls deploy --stage dotcomstg
6767
- name: Deploy Lambdas
6868
run: |
69-
npm ci
69+
npm ci
7070
sls deploy --stage stg
71-
sls deploy --stage dotcomstg
71+
sls deploy --stage dotcomstg
72+
sls prune -n 5

api/controllers/v1/dochub.ts

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,17 @@
11
import { FastlyConnector } from '../../../src/services/cdn';
22
import { ConsoleLogger } from '../../../src/services/logger';
33
import { CDNCreds } from '../../../src/entities/creds';
4-
import { APIGatewayEvent, APIGatewayProxyResult } from 'aws-lambda';
5-
6-
export const UpsertEdgeDictionaryItem = async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
7-
if (!event.body) {
8-
return {
9-
statusCode: 400,
10-
body: 'event.body is null',
11-
};
12-
}
134

5+
export const UpsertEdgeDictionaryItem = async (event: any = {}): Promise<any> => {
146
const body = JSON.parse(event.body);
15-
167
const pair = {
178
key: body.source,
189
value: body.target,
1910
};
20-
21-
const { FASTLY_DOCHUB_SERVICE_ID, FASTLY_DOCHUB_TOKEN, FASTLY_DOCHUB_MAP } = process.env;
22-
23-
if (!FASTLY_DOCHUB_SERVICE_ID) {
24-
return {
25-
statusCode: 500,
26-
body: 'Fastly dochub service ID is not defined',
27-
};
28-
}
29-
30-
if (!FASTLY_DOCHUB_TOKEN) {
31-
return {
32-
statusCode: 500,
33-
body: 'Fastly dochub token is not defined',
34-
};
35-
}
36-
37-
if (!FASTLY_DOCHUB_MAP) {
38-
return {
39-
statusCode: 500,
40-
body: 'Fastly dochub map is not defined',
41-
};
42-
}
43-
44-
const creds = new CDNCreds(FASTLY_DOCHUB_SERVICE_ID, FASTLY_DOCHUB_TOKEN);
45-
await new FastlyConnector(new ConsoleLogger()).upsertEdgeDictionaryItem(pair, FASTLY_DOCHUB_MAP, creds);
11+
// TODO: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
12+
// Above applies for all 'process.env' variables, they should be validated
13+
const creds = new CDNCreds(process.env.FASTLY_DOCHUB_SERVICE_ID, process.env.FASTLY_DOCHUB_TOKEN);
14+
await new FastlyConnector(new ConsoleLogger()).upsertEdgeDictionaryItem(pair, process.env.FASTLY_DOCHUB_MAP, creds);
4615
return {
4716
statusCode: 202,
4817
headers: { 'Content-Type': 'text/plain' },

api/controllers/v1/github.ts

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,22 @@
11
import * as c from 'config';
22
import * as crypto from 'crypto';
33
import * as mongodb from 'mongodb';
4-
import { APIGatewayEvent, APIGatewayProxyResult } from 'aws-lambda';
5-
64
import { JobRepository } from '../../../src/repositories/jobRepository';
75
import { ConsoleLogger } from '../../../src/services/logger';
86
import { BranchRepository } from '../../../src/repositories/branchRepository';
9-
import { Job, JobStatus } from '../../../src/entities/job';
10-
import { PushEvent } from '@octokit/webhooks-types';
117

128
// This function will validate your payload from GitHub
139
// See docs at https://developer.github.com/webhooks/securing/#validating-payloads-from-github
14-
function validateJsonWebhook(request: APIGatewayEvent, secret: string) {
15-
const expectedSignature =
16-
'sha256=' +
17-
crypto
18-
.createHmac('sha256', secret)
19-
.update(request.body ?? '')
20-
.digest('hex');
10+
function validateJsonWebhook(request: any, secret: string) {
11+
const expectedSignature = 'sha256=' + crypto.createHmac('sha256', secret).update(request.body).digest('hex');
2112
const signature = request.headers['X-Hub-Signature-256'];
2213
if (signature !== expectedSignature) {
2314
return false;
2415
}
2516
return true;
2617
}
2718

28-
async function prepGithubPushPayload(
29-
githubEvent: PushEvent,
30-
branchRepository: BranchRepository,
31-
prefix: string
32-
): Promise<Omit<Job, '_id'>> {
19+
async function prepGithubPushPayload(githubEvent: any, branchRepository: BranchRepository, prefix: string) {
3320
const branch_name = githubEvent.ref.split('/')[2];
3421
const branch_info = await branchRepository.getRepoBranchAliases(githubEvent.repository.name, branch_name);
3522
const urlSlug = branch_info.aliasObject?.urlSlug ?? branch_name;
@@ -40,7 +27,7 @@ async function prepGithubPushPayload(
4027
title: githubEvent.repository.full_name,
4128
user: githubEvent.pusher.name,
4229
email: githubEvent.pusher.email,
43-
status: JobStatus.inQueue,
30+
status: 'inQueue',
4431
createdTime: new Date(),
4532
startTime: null,
4633
endTime: null,
@@ -55,6 +42,7 @@ async function prepGithubPushPayload(
5542
branchName: githubEvent.ref.split('/')[2],
5643
isFork: githubEvent.repository.fork,
5744
private: githubEvent.repository.private,
45+
isXlarge: true,
5846
repoOwner: githubEvent.repository.owner.login,
5947
url: githubEvent.repository.clone_url,
6048
newHead: githubEvent.after,
@@ -66,24 +54,14 @@ async function prepGithubPushPayload(
6654
};
6755
}
6856

69-
export const TriggerBuild = async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
57+
export const TriggerBuild = async (event: any = {}, context: any = {}): Promise<any> => {
7058
const client = new mongodb.MongoClient(c.get('dbUrl'));
7159
await client.connect();
7260
const db = client.db(c.get('dbName'));
7361
const consoleLogger = new ConsoleLogger();
7462
const jobRepository = new JobRepository(db, c, consoleLogger);
7563
const branchRepository = new BranchRepository(db, c, consoleLogger);
76-
77-
if (!event.body) {
78-
const err = 'Trigger build does not have a body in event payload';
79-
consoleLogger.error('TriggerBuildError', err);
80-
return {
81-
statusCode: 400,
82-
headers: { 'Content-Type': 'text/plain' },
83-
body: err,
84-
};
85-
}
86-
64+
const sig = event.headers['X-Hub-Signature-256'];
8765
if (!validateJsonWebhook(event, c.get<string>('githubSecret'))) {
8866
const errMsg = "X-Hub-Signature incorrect. Github webhook token doesn't match";
8967
return {
@@ -92,7 +70,6 @@ export const TriggerBuild = async (event: APIGatewayEvent): Promise<APIGatewayPr
9270
body: errMsg,
9371
};
9472
}
95-
9673
const body = JSON.parse(event.body);
9774

9875
if (body.deleted) {
@@ -106,9 +83,8 @@ export const TriggerBuild = async (event: APIGatewayEvent): Promise<APIGatewayPr
10683
const env = c.get<string>('env');
10784
const repoInfo = await branchRepository.getRepo(body.repository.name);
10885
const jobPrefix = repoInfo?.prefix ? repoInfo['prefix'][env] : '';
109-
86+
// TODO: Make job be of type Job
11087
const job = await prepGithubPushPayload(body, branchRepository, jobPrefix);
111-
11288
try {
11389
consoleLogger.info(job.title, 'Creating Job');
11490
const jobId = await jobRepository.insertJob(job, c.get('jobsQueueUrl'));

api/controllers/v1/jobs.ts

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,13 @@ import { Job, JobStatus } from '../../../src/entities/job';
1111
import { ECSContainer } from '../../../src/services/containerServices';
1212
import { SQSConnector } from '../../../src/services/queue';
1313
import { Batch } from '../../../src/services/batch';
14-
import { APIGatewayEvent, APIGatewayProxyResult, SQSEvent, SQSRecord } from 'aws-lambda';
1514

16-
export const TriggerLocalBuild = async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
15+
export const TriggerLocalBuild = async (event: any = {}, context: any = {}): Promise<any> => {
16+
const client = new mongodb.MongoClient(c.get('dbUrl'));
17+
await client.connect();
18+
const db = client.db(c.get('dbName'));
1719
const consoleLogger = new ConsoleLogger();
1820
const sqs = new SQSConnector(consoleLogger, c);
19-
20-
if (!event.body) {
21-
const err = 'Trigger local build does not have a body in event payload';
22-
consoleLogger.error('TriggerLocalBuildError', err);
23-
return {
24-
statusCode: 400,
25-
headers: { 'Content-Type': 'text/plain' },
26-
body: err,
27-
};
28-
}
29-
3021
const body = JSON.parse(event.body);
3122
try {
3223
consoleLogger.info(body.jobId, 'enqueuing Job');
@@ -47,23 +38,26 @@ export const TriggerLocalBuild = async (event: APIGatewayEvent): Promise<APIGate
4738
}
4839
};
4940

50-
export const HandleJobs = async (event: SQSEvent): Promise<void> => {
41+
// TODO: use @types/aws-lambda
42+
export const HandleJobs = async (event: any = {}): Promise<any> => {
5143
/**
5244
* Check the status of the incoming jobs
5345
* if it is inqueue start a task
5446
* if it is inprogress call NotifyBuildProgress
5547
* if it is completed call NotifyBuildSummary
5648
*/
57-
const messages = event.Records;
49+
const messages: JobQueueMessage[] = event.Records;
5850
await Promise.all(
59-
messages.map(async (message: SQSRecord) => {
51+
messages.map(async (message: any) => {
6052
const consoleLogger = new ConsoleLogger();
6153
const body = JSON.parse(message.body);
54+
let queueUrl = '';
6255
const jobId = body['jobId'];
6356
const jobStatus = body['jobStatus'];
6457
try {
6558
switch (jobStatus) {
6659
case JobStatus[JobStatus.inQueue]:
60+
queueUrl = c.get('jobsQueueUrl');
6761
await NotifyBuildProgress(jobId);
6862
// start the task , don't start the process before processing the notification
6963
const ecsServices = new ECSContainer(c, consoleLogger);
@@ -74,6 +68,7 @@ export const HandleJobs = async (event: SQSEvent): Promise<void> => {
7468
consoleLogger.info(jobId, JSON.stringify(res));
7569
break;
7670
case JobStatus[JobStatus.inProgress]:
71+
queueUrl = c.get('jobUpdatesQueueUrl');
7772
await NotifyBuildProgress(jobId);
7873
break;
7974
case JobStatus[JobStatus.timedOut]:
@@ -85,7 +80,9 @@ export const HandleJobs = async (event: SQSEvent): Promise<void> => {
8580
break;
8681
case JobStatus[JobStatus.failed]:
8782
case JobStatus[JobStatus.completed]:
88-
await Promise.all([NotifyBuildSummary(jobId), SubmitArchiveJob(jobId)]);
83+
queueUrl = c.get('jobUpdatesQueueUrl');
84+
await NotifyBuildSummary(jobId);
85+
await SubmitArchiveJob(jobId);
8986
break;
9087
default:
9188
consoleLogger.error(jobId, 'Invalid status');
@@ -137,35 +134,42 @@ async function stopECSTask(taskId: string, consoleLogger: ConsoleLogger) {
137134
await ecs.stopZombieECSTask(taskId);
138135
}
139136

140-
async function NotifyBuildSummary(jobId: string): Promise<void> {
137+
async function retry(message: JobQueueMessage, consoleLogger: ConsoleLogger, url: string): Promise<any> {
138+
try {
139+
const tries = message.tries;
140+
// TODO: c.get('maxRetries') is of type 'Unknown', needs validation
141+
if (tries < c.get('maxRetries')) {
142+
const sqs = new SQSConnector(consoleLogger, c);
143+
message['tries'] += 1;
144+
let retryDelay = 10;
145+
if (c.get('retryDelay')) {
146+
retryDelay = c.get('retryDelay');
147+
}
148+
await sqs.sendMessage(message, url, retryDelay * tries);
149+
}
150+
} catch (err) {
151+
consoleLogger.error(message['jobId'], err);
152+
}
153+
}
154+
async function NotifyBuildSummary(jobId: string): Promise<any> {
141155
const consoleLogger = new ConsoleLogger();
142156
const client = new mongodb.MongoClient(c.get('dbUrl'));
143157
await client.connect();
144158
const db = client.db(c.get('dbName'));
145159
const env = c.get<string>('env');
146160

147161
const jobRepository = new JobRepository(db, c, consoleLogger);
162+
// TODO: Make fullDocument be of type Job, validate existence
148163
const fullDocument = await jobRepository.getJobById(jobId);
149-
150-
if (!fullDocument) {
151-
consoleLogger.error(
152-
`NotifyBuildSummary_${jobId}`,
153-
`Notify build summary failed. Job does not exist for Job ID: ${jobId}`
154-
);
155-
return;
156-
}
157-
158164
const repoName = fullDocument.payload.repoName;
159165
const username = fullDocument.user;
160166
const slackConnector = new SlackConnector(consoleLogger, c);
161167
const repoEntitlementRepository = new RepoEntitlementsRepository(db, c, consoleLogger);
162168
const entitlement = await repoEntitlementRepository.getSlackUserIdByGithubUsername(username);
163-
164169
if (!entitlement?.['slack_user_id']) {
165170
consoleLogger.error(username, 'Entitlement failed');
166171
return;
167172
}
168-
169173
await slackConnector.sendMessage(
170174
await prepSummaryMessage(
171175
env,
@@ -177,6 +181,9 @@ async function NotifyBuildSummary(jobId: string): Promise<void> {
177181
),
178182
entitlement['slack_user_id']
179183
);
184+
return {
185+
statusCode: 200,
186+
};
180187
}
181188

182189
export const extractUrlFromMessage = (fullDocument): string[] => {
@@ -194,11 +201,12 @@ async function prepSummaryMessage(
194201
failed = false
195202
): Promise<string> {
196203
const urls = extractUrlFromMessage(fullDocument);
197-
let mms_urls: Array<string | null> = [null, null];
204+
let mms_urls = [null, null];
198205
// mms-docs needs special handling as it builds two sites (cloudmanager & ops manager)
199206
// so we need to extract both URLs
200207
if (repoName === 'mms-docs') {
201208
if (urls.length >= 2) {
209+
// TODO: Type 'string[]' is not assignable to type 'null[]'.
202210
mms_urls = urls.slice(-2);
203211
}
204212
}
@@ -249,24 +257,15 @@ function prepProgressMessage(
249257
}
250258
}
251259

252-
async function NotifyBuildProgress(jobId: string): Promise<void> {
260+
async function NotifyBuildProgress(jobId: string): Promise<any> {
253261
const consoleLogger = new ConsoleLogger();
254262
const client = new mongodb.MongoClient(c.get('dbUrl'));
255263
await client.connect();
256264
const db = client.db(c.get('dbName'));
257265
const slackConnector = new SlackConnector(consoleLogger, c);
258266
const jobRepository = new JobRepository(db, c, consoleLogger);
259-
267+
// TODO: Make fullDocument be of type Job, validate existence
260268
const fullDocument = await jobRepository.getJobById(jobId);
261-
262-
if (!fullDocument) {
263-
consoleLogger.error(
264-
`NotifyBuildProgress_${jobId}`,
265-
`Notify build progress failed. Job does not exist for Job ID: ${jobId}`
266-
);
267-
return;
268-
}
269-
270269
const jobTitle = fullDocument.title;
271270
const username = fullDocument.user;
272271
const repoEntitlementRepository = new RepoEntitlementsRepository(db, c, consoleLogger);
@@ -275,8 +274,7 @@ async function NotifyBuildProgress(jobId: string): Promise<void> {
275274
consoleLogger.error(username, 'Entitlement Failed');
276275
return;
277276
}
278-
279-
await slackConnector.sendMessage(
277+
const resp = await slackConnector.sendMessage(
280278
prepProgressMessage(
281279
c.get('dashboardUrl'),
282280
jobId,
@@ -286,6 +284,9 @@ async function NotifyBuildProgress(jobId: string): Promise<void> {
286284
),
287285
entitlement['slack_user_id']
288286
);
287+
return {
288+
statusCode: 200,
289+
};
289290
}
290291

291292
function getMongoClient(config: IConfig): mongodb.MongoClient {
@@ -316,15 +317,6 @@ async function SubmitArchiveJob(jobId: string) {
316317
branches: new BranchRepository(db, c, consoleLogger),
317318
};
318319
const job = await models.jobs.getJobById(jobId);
319-
320-
if (!job) {
321-
consoleLogger.error(
322-
`SubmitArchiveJob_${jobId}`,
323-
`Submit archive job failed. Job does not exist for Job ID: ${jobId}`
324-
);
325-
return;
326-
}
327-
328320
const repo = await models.branches.getRepo(job.payload.repoName);
329321

330322
/* NOTE

0 commit comments

Comments
 (0)