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

Commit 75d25d0

Browse files
authored
* move search deploy commands into production job handler * test flag * fix manifest handler * save logs to queue message * construct manifest prefix * fix broken tests * add timer for search job * address comments
1 parent 9422df1 commit 75d25d0

File tree

6 files changed

+94
-22
lines changed

6 files changed

+94
-22
lines changed

cdk-infra/utils/ssm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const workerSecureStrings = [
7474
'/cdn/client/secret',
7575
] as const;
7676

77-
type WorkerSecureString = typeof workerSecureStrings[number];
77+
type WorkerSecureString = (typeof workerSecureStrings)[number];
7878

7979
const workerParamPathToEnvName = new Map<WorkerSecureString, string>();
8080

@@ -113,7 +113,7 @@ const webhookSecureStrings = [
113113
'/snooty/webhook/secret',
114114
] as const;
115115

116-
type WebhookSecureString = typeof webhookSecureStrings[number];
116+
type WebhookSecureString = (typeof webhookSecureStrings)[number];
117117

118118
const webhookParamPathToEnvName = new Map<WebhookSecureString, string>();
119119

src/job/jobHandler.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export abstract class JobHandler {
8080
this._repoBranchesRepo = repoBranchesRepo;
8181
}
8282

83+
// called during build stage of
8384
abstract prepStageSpecificNextGenCommands(): void;
8485

8586
private logErrorMessage(message: string): void {
@@ -391,6 +392,10 @@ export abstract class JobHandler {
391392

392393
protected abstract prepDeployCommands(): void;
393394

395+
protected prepSearchDeploy(): void {
396+
this._logger.info(this._currJob._id, 'Preparing search deploy');
397+
}
398+
394399
// TODO: Reduce state changes
395400
protected prepBuildCommands(): void {
396401
this.currJob.buildCommands = [
@@ -459,7 +464,17 @@ export abstract class JobHandler {
459464
await this._logger.save(this.currJob._id, `${this._config.get<string>('stage').padEnd(15)}Pushing to ${this.name}`);
460465

461466
if ((this.currJob?.deployCommands?.length ?? 0) > 0) {
462-
const resp = await this._commandExecutor.execute(this.currJob.deployCommands);
467+
// extract search deploy job to time and test
468+
const searchCommandIdx = this.currJob.deployCommands.findIndex((c) => c.match(/^mut\-index/));
469+
let deployCmdsNoSearch = this.currJob.deployCommands;
470+
if (searchCommandIdx > -1) {
471+
await this.callWithBenchmark(this.currJob.deployCommands[searchCommandIdx], 'search');
472+
deployCmdsNoSearch = this.currJob.deployCommands
473+
.slice(0, searchCommandIdx)
474+
.concat(this.currJob.deployCommands.slice(searchCommandIdx + 1, this.currJob.deployCommands.length));
475+
}
476+
477+
const resp = await this._commandExecutor.execute(deployCmdsNoSearch);
463478
if (resp?.error?.includes?.('ERROR')) {
464479
await this._logger.save(
465480
this.currJob._id,

src/job/manifestJobHandler.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// TODO: remove manifest job handler
2+
// not run as a separate job, handled in productionJobHandler prepSearchDeploy
3+
14
import { JobHandler } from './jobHandler';
25
import { IConfig } from 'config';
36
import type { Job } from '../entities/job';
@@ -12,7 +15,7 @@ import { RepoBranchesRepository } from '../repositories/repoBranchesRepository';
1215
import { InvalidJobError } from '../errors/errors';
1316

1417
// TODO: Move this to a generic util and out of this job file
15-
const joinUrlAndPrefix = (url, prefix) => {
18+
export const joinUrlAndPrefix = (url: string, prefix: string) => {
1619
const needsTrim = url.endsWith('/') && prefix.startsWith('/');
1720
const needsSlash = !url.endsWith('/') && !prefix.startsWith('/');
1821

@@ -94,7 +97,7 @@ export class ManifestJobHandler extends JobHandler {
9497
`cd repos/${this.currJob.payload.repoName}`,
9598
'echo IGNORE: testing manifest generation deploy commands',
9699
'ls -al',
97-
`mut-index upload bundle.zip -b ${b} -o ${f}/${maP}.json -u ${jUaP(url, muP)} ${globalSearch}`,
100+
`mut-index upload bundle.zip -b ${b} -o ${f}/${maP}.json -u ${jUaP(url, muP || '')} ${globalSearch}`,
98101
];
99102
}
100103

src/job/productionJobHandler.ts

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { IJobRepoLogger } from '../services/logger';
1010
import { IRepoConnector } from '../services/repo';
1111
import { JobHandler } from './jobHandler';
1212
import { IJobValidator } from './jobValidator';
13+
import { joinUrlAndPrefix } from './manifestJobHandler';
1314

1415
export class ProductionJobHandler extends JobHandler {
1516
constructor(
@@ -48,18 +49,82 @@ export class ProductionJobHandler extends JobHandler {
4849

4950
// TODO: Reduce confusion between job.manifestPrefix and job.payload.manifestPrefix
5051
if (this.currJob.payload.isNextGen) {
51-
const manifestPrefix = this.currJob.payload.manifestPrefix;
52+
this.currJob.manifestPrefix = this.currJob.manifestPrefix ?? this.constructManifestPrefix();
5253
this.currJob.deployCommands[
5354
this.currJob.deployCommands.length - 1
5455
] = `make next-gen-deploy MUT_PREFIX=${this.currJob.payload.mutPrefix}`;
5556
// TODO: Remove when satisfied with new manifestJobHandler infrastructure
56-
if (manifestPrefix) {
57+
if (this.currJob.manifestPrefix) {
5758
const searchFlag = this.currJob.payload.stable ? '-g' : '';
5859
this.currJob.deployCommands[
5960
this.currJob.deployCommands.length - 1
60-
] += ` MANIFEST_PREFIX=${manifestPrefix} GLOBAL_SEARCH_FLAG=${searchFlag}`;
61+
] += ` MANIFEST_PREFIX=${this.currJob.manifestPrefix} GLOBAL_SEARCH_FLAG=${searchFlag}`;
6162
}
6263
}
64+
// have to combine search deploy commands
65+
// manifestJobHandler.prepDeployCommands
66+
67+
this.currJob.shouldGenerateSearchManifest = this.shouldGenerateSearchManifest();
68+
this.logger.save(
69+
this.currJob._id,
70+
`this.currJob.shouldGenerateSearchManifest ${this.currJob.shouldGenerateSearchManifest}`
71+
);
72+
if (this.currJob.shouldGenerateSearchManifest) {
73+
this.prepSearchDeploy();
74+
}
75+
}
76+
77+
prepSearchDeploy(): void {
78+
const b = this._config.get<string>('searchIndexBucket') ?? 'docs-search-indexes-test';
79+
// /deploy -> send to /prd folder. /test-deploy -> send to /preprd folder
80+
const env = this._config.get<string>('env');
81+
// Note: mut-index automatically prepends 'search-indexes/' to the folder.
82+
const f = this._config.get<string>('searchIndexFolder')?.[env] ?? 'fallback-folder';
83+
this.logger.save(this.currJob._id, `Manifest attempt to upload to bucket: ${b}, folder: ${f}`);
84+
// Due to the dual existence of prefixes, check for both for redundancy
85+
const maP = this.currJob.manifestPrefix ?? this.currJob.payload.manifestPrefix;
86+
const muP = this.currJob.mutPrefix ?? this.currJob.payload.mutPrefix;
87+
const url = this.currJob.payload?.repoBranches?.url?.[env];
88+
const jUaP = joinUrlAndPrefix;
89+
const globalSearch = this.currJob.payload.stable ? '-g' : '';
90+
91+
// Rudimentary error logging
92+
if (!b) {
93+
this.logger.save(this.currJob._id, `searchIndexBucket not found`);
94+
}
95+
if (!f) {
96+
this.logger.save(this.currJob._id, `searchIndexFolder not found`);
97+
}
98+
99+
if (!url) {
100+
this.logger.error(
101+
this.currJob._id,
102+
`repoBranches.url entry for this environment (${env}) not found for ${this.currJob._id}`
103+
);
104+
return;
105+
}
106+
107+
if (!this.currJob.manifestPrefix) {
108+
this.logger.error(this.currJob._id, `Manifest prefix not found for ${this.currJob._id}`);
109+
return;
110+
}
111+
const searchCommands = [
112+
'. /venv/bin/activate',
113+
`cd repos/${this.currJob.payload.repoName}`,
114+
'echo IGNORE: testing manifest generation deploy commands',
115+
'ls -al',
116+
// For mut-index usage info, see: https://github.com/mongodb/mut/blob/master/mut/index/main.py#L2
117+
`mut-index upload bundle.zip -b ${b} -o ${f}/${maP}.json -u ${jUaP(url, muP || '')} ${globalSearch}`,
118+
];
119+
for (const command of searchCommands) {
120+
if (this.currJob.deployCommands.indexOf(command) === -1) {
121+
this.currJob.deployCommands.push(command);
122+
}
123+
}
124+
this.logger.save(
125+
this.currJob._id,
126+
`deploy commands: ${this.currJob.deployCommands.map((command) => command + '\n')}`
127+
);
63128
}
64129

65130
prepStageSpecificNextGenCommands(): void {
@@ -126,10 +191,6 @@ export class ProductionJobHandler extends JobHandler {
126191
await this.logger.save(this.currJob._id, `${'(prod)'.padEnd(15)}Deploy details:\n\n${resp.output}`);
127192
}
128193

129-
this.currJob.shouldGenerateSearchManifest = this.shouldGenerateSearchManifest();
130-
if (this.currJob.shouldGenerateSearchManifest) {
131-
this.queueManifestJob();
132-
}
133194
return resp;
134195
} catch (errResult) {
135196
await this.logger.save(this.currJob._id, `${'(prod)'.padEnd(15)}stdErr: ${errResult.stderr}`);

tests/data/data.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,6 @@ export class TestDataProvider {
266266
const ret = Array<string>().concat(genericCommands.slice(0, genericCommands.length - 1), [
267267
`make next-gen-deploy MUT_PREFIX=${job.payload.mutPrefix}`,
268268
]);
269-
if (job.payload.manifestPrefix) {
270-
// TODO: is job.payload.stableBranch supposed to be includeInGlobalSearch?
271-
const stable = job.payload.stable ? '-g' : '';
272-
ret[ret.length - 1] += ` MANIFEST_PREFIX=${job.payload.manifestPrefix} GLOBAL_SEARCH_FLAG=${stable}`;
273-
}
274269
return ret;
275270
}
276271

tests/unit/job/productionJobHandler.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ describe('ProductionJobHandler Tests', () => {
173173
);
174174
});
175175

176-
test('Default production deploy kicks off manifest generation', async () => {
176+
test('Default production deploy does not kick off manifest generation', async () => {
177177
jobHandlerTestHelper.jobRepo.insertJob = jest.fn();
178178
const queueManifestJobSpy = jest.spyOn(jobHandlerTestHelper.jobHandler, 'queueManifestJob');
179179

@@ -183,10 +183,8 @@ describe('ProductionJobHandler Tests', () => {
183183
await jobHandlerTestHelper.jobHandler.execute();
184184
jobHandlerTestHelper.verifyNextGenSuccess();
185185

186-
expect(queueManifestJobSpy).toBeCalledTimes(1);
187-
expect(jobHandlerTestHelper.jobRepo.insertJob).toBeCalledTimes(1);
188-
189-
expect(jobHandlerTestHelper.jobRepo.insertJob.mock.calls[0][0]).toEqual(getManifestJobDef());
186+
expect(queueManifestJobSpy).toBeCalledTimes(0);
187+
expect(jobHandlerTestHelper.jobRepo.insertJob).toBeCalledTimes(0);
190188
});
191189

192190
test('Production deploy with false shouldGenerateManifest() result does not kick off manifest job', async () => {

0 commit comments

Comments
 (0)