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

Commit 5631a34

Browse files
authored
DOP-3904: SnootyBuildWebhook updates Job status (#874)
* update Job with status on SnootyBuildWebhook * add type to status * add to staging ecs step * two logs, and proof * clean * set status back to dynamic
1 parent fc1ba1c commit 5631a34

File tree

6 files changed

+32
-25
lines changed

6 files changed

+32
-25
lines changed

api/handlers/jobs.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import { JobRepository } from '../../src/repositories/jobRepository';
77
import { GithubCommenter } from '../../src/services/github';
88
import { SlackConnector } from '../../src/services/slack';
99
import { RepoEntitlementsRepository } from '../../src/repositories/repoEntitlementsRepository';
10-
import { EnhancedJob, Job, Payload } from '../../src/entities/job';
10+
import { EnhancedJob, Job, JobStatus, Payload } from '../../src/entities/job';
1111

1212
// Although data in payload should always be present, it's not guaranteed from
1313
// external callers
1414
interface SnootyPayload {
1515
jobId?: string;
16+
status?: JobStatus;
1617
}
1718

1819
// These options should only be defined if the build summary is being called after
@@ -238,8 +239,8 @@ export async function snootyBuildComplete(event: APIGatewayEvent): Promise<APIGa
238239
await client.connect();
239240
const db = client.db(c.get<string>('dbName'));
240241
const jobRepository = new JobRepository(db, c, consoleLogger);
241-
const { payload } = await jobRepository.updateWithCompletionStatus(jobId, null, false);
242-
const previewUrl = getPreviewUrl(payload, c.get<string>('env'));
242+
const updateResponse = await jobRepository.updateWithStatus(jobId, null, payload.status || JobStatus.failed, false);
243+
const previewUrl = getPreviewUrl(updateResponse.payload, c.get<string>('env'));
243244
await notifyBuildSummary(jobId, { mongoClient: client, previewUrl });
244245
} catch (e) {
245246
consoleLogger.error('SnootyBuildCompleteError', e);
@@ -265,7 +266,6 @@ export async function snootyBuildComplete(event: APIGatewayEvent): Promise<APIGa
265266
* @returns string|undefined
266267
*/
267268
function getPreviewUrl(payload: Payload | undefined, env: string): string | undefined {
268-
console.log('PAYLOAD ', payload);
269269
if (!payload) return;
270270
const { repoOwner, branchName, project } = payload;
271271
const githubUsernameNoHyphens = repoOwner.split('-').join('').toLowerCase();

src/job/jobHandler.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export abstract class JobHandler {
9999
null,
100100
null
101101
);
102-
await this.jobRepository.updateWithCompletionStatus(this.currJob._id, files);
102+
await this.jobRepository.updateWithStatus(this.currJob._id, files, JobStatus.completed);
103103
} else {
104104
if (publishResult.error) {
105105
await this.jobRepository.updateWithErrorStatus(this.currJob._id, publishResult.error);
@@ -649,9 +649,8 @@ export abstract class JobHandler {
649649
return await axios.post(
650650
url,
651651
{
652-
project: this.currJob.payload.project,
653-
branch: this.currJob.payload.branchName,
654652
jobId: this.currJob._id,
653+
status: this.currJob.status,
655654
},
656655
{
657656
headers: { 'x-gatsby-cloud-data-source': 'gatsby-source-snooty-preview' },

src/repositories/jobRepository.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as mongodb from 'mongodb';
22
import { BaseRepository } from './baseRepository';
3-
import type { EnhancedJob, Job, Payload } from '../entities/job';
3+
import type { EnhancedJob, Job } from '../entities/job';
44
import { JobStatus } from '../entities/job';
55
import { ILogger } from '../services/logger';
66
import c, { IConfig } from 'config';
7-
import { DBError, InvalidJobError, JobExistsAlreadyError, JobNotFoundError } from '../errors/errors';
7+
import { DBError, JobExistsAlreadyError, JobNotFoundError } from '../errors/errors';
88
import { IQueueConnector, SQSConnector } from '../services/queue';
99
import { JobQueueMessage } from '../entities/queueMessage';
1010

@@ -21,17 +21,18 @@ export class JobRepository extends BaseRepository {
2121
this._queueConnector = new SQSConnector(logger, config);
2222
}
2323

24-
async updateWithCompletionStatus(
24+
async updateWithStatus(
2525
id: string | mongodb.ObjectId,
2626
result: any,
27+
status: JobStatus,
2728
shouldNotifySqs = true
2829
): Promise<mongodb.Document> {
2930
// Safely convert to object ID
3031
const objectId = new mongodb.ObjectId(id);
3132
const query = { _id: objectId };
3233
const update = {
3334
$set: {
34-
status: 'completed',
35+
status,
3536
endTime: new Date(),
3637
result,
3738
},
@@ -40,7 +41,7 @@ export class JobRepository extends BaseRepository {
4041
query,
4142
update,
4243
{},
43-
`Mongo Timeout Error: Timed out while updating success status for jobId: ${id}`
44+
`Mongo Timeout Error: Timed out while updating job status to "${status}" for jobId: ${id}`
4445
);
4546
if (shouldNotifySqs) {
4647
await this.notify(objectId.toString(), c.get('jobUpdatesQueueUrl'), JobStatus.completed, 0);

tests/unit/job/api/jobs.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jest.mock('config', () => ({
1515

1616
jest.mock('../../../../src/repositories/jobRepository', () => ({
1717
JobRepository: jest.fn().mockImplementation(() => ({
18-
updateWithCompletionStatus: jest.fn(() => mockJob),
18+
updateWithStatus: jest.fn(() => mockJob),
1919
getJobById: jest.fn(),
2020
})),
2121
}));

tests/unit/job/productionJobHandler.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { mockReset } from 'jest-mock-extended';
2+
import { JobStatus } from '../../../src/entities/job';
23
import { TestDataProvider } from '../../data/data';
34
import { getBuildJobDef, getManifestJobDef } from '../../data/jobDef';
45
import { JobHandlerTestHelper } from '../../utils/jobHandlerTestHelper';
@@ -318,11 +319,11 @@ describe('ProductionJobHandler Tests', () => {
318319
null,
319320
null
320321
);
321-
expect(jobHandlerTestHelper.jobRepo.updateWithCompletionStatus).toBeCalledWith(jobHandlerTestHelper.job._id, [
322-
'1.html',
323-
'2.html',
324-
'3.html',
325-
]);
322+
expect(jobHandlerTestHelper.jobRepo.updateWithStatus).toBeCalledWith(
323+
jobHandlerTestHelper.job._id,
324+
['1.html', '2.html', '3.html'],
325+
JobStatus.completed
326+
);
326327
});
327328
}
328329
);

tests/unit/repositories/jobRepository.test.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getBuildJobDef, getBuildJobPlain } from '../../data/jobDef';
33
import { DBRepositoryHelper } from '../../utils/repositoryHelper';
44
import { TestDataProvider } from '../../data/data';
55
import { ObjectId } from 'mongodb';
6-
import { Job } from '../../../src/entities/job';
6+
import { Job, JobStatus } from '../../../src/entities/job';
77

88
describe('Job Repository Tests', () => {
99
let job: Job;
@@ -19,15 +19,17 @@ describe('Job Repository Tests', () => {
1919
expect(new JobRepository(dbRepoHelper.db, dbRepoHelper.config, dbRepoHelper.logger)).toBeDefined();
2020
});
2121

22-
describe('Job Repository updateWithCompletionStatus Tests', () => {
22+
describe('Job Repository updateWithStatus Tests', () => {
2323
test('Update with completion status throws DB Error as result is undefined', async () => {
2424
const testData = TestDataProvider.getStatusUpdateQueryAndUpdateObject(
2525
'64ad959b423952aeb9341fad',
2626
'completed',
2727
'All good',
2828
new Date()
2929
);
30-
await expect(jobRepo.updateWithCompletionStatus('64ad959b423952aeb9341fad', 'All good')).rejects.toThrow(
30+
await expect(
31+
jobRepo.updateWithStatus('64ad959b423952aeb9341fad', 'All good', JobStatus.completed)
32+
).rejects.toThrow(
3133
`Failed to update job (${JSON.stringify(testData.query)}) for ${JSON.stringify(testData.update)}`
3234
);
3335
});
@@ -40,15 +42,19 @@ describe('Job Repository Tests', () => {
4042
new Date()
4143
);
4244
dbRepoHelper.collection.findOneAndUpdate.mockReturnValue(undefined);
43-
await expect(jobRepo.updateWithCompletionStatus('64ad959b423952aeb9341fad', 'All good')).rejects.toThrow(
45+
await expect(
46+
jobRepo.updateWithStatus('64ad959b423952aeb9341fad', 'All good', JobStatus.completed)
47+
).rejects.toThrow(
4448
`Failed to update job (${JSON.stringify(testData.query)}) for ${JSON.stringify(testData.update)}`
4549
);
4650
expect(dbRepoHelper.collection.findOneAndUpdate).toBeCalledTimes(1);
4751
});
4852

4953
test('Update with completion status succeeds', async () => {
5054
setupForFindOneAndUpdateSuccess();
51-
await expect(jobRepo.updateWithCompletionStatus('64ad959b423952aeb9341fad', 'All good')).resolves.toEqual(job);
55+
await expect(
56+
jobRepo.updateWithStatus('64ad959b423952aeb9341fad', 'All good', JobStatus.completed)
57+
).resolves.toEqual(job);
5258
expect(dbRepoHelper.collection.findOneAndUpdate).toBeCalledTimes(1);
5359
expect(dbRepoHelper.logger.error).toBeCalledTimes(0);
5460
});
@@ -61,10 +67,10 @@ describe('Job Repository Tests', () => {
6167
});
6268
});
6369
try {
64-
jobRepo.updateWithCompletionStatus('64ad959b423952aeb9341fad', 'All good').catch((error) => {
70+
jobRepo.updateWithStatus('64ad959b423952aeb9341fad', 'All good', JobStatus.completed).catch((error) => {
6571
expect(dbRepoHelper.logger.error).toBeCalledTimes(1);
6672
expect(error.message).toContain(
67-
`Mongo Timeout Error: Timed out while updating success status for jobId: 64ad959b423952aeb9341fad`
73+
`Mongo Timeout Error: Timed out while updating job status to "${JobStatus.completed}" for jobId: 64ad959b423952aeb9341fad`
6874
);
6975
});
7076
jest.runAllTimers();

0 commit comments

Comments
 (0)