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

Commit 0f8fc24

Browse files
committed
DOP-3341: Integrate OAS Page Builder module as part of build process (#723)
1 parent a908f6e commit 0f8fc24

File tree

10 files changed

+99
-8
lines changed

10 files changed

+99
-8
lines changed

Dockerfile

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,19 @@ RUN npm install
88
COPY . ./
99
RUN npm run build
1010

11+
# Build modules
12+
# OAS Page Builder
13+
RUN cd ./modules/oas-page-builder \
14+
&& npm install \
15+
&& npm run build
16+
1117
# where repo work will happen
1218
FROM ubuntu:20.04
1319
ARG SNOOTY_PARSER_VERSION=0.13.15
1420
ARG SNOOTY_FRONTEND_VERSION=0.13.35
21+
# The Redoc CLI branch will most likely stay static. Updates to the branch should
22+
# be limited to CLI bug fixes and Redoc dependency version bumps
23+
ARG REDOC_CLI_VERSION=0.1.0
1524
ARG FLIT_VERSION=3.0.0
1625
ARG NPM_BASE_64_AUTH
1726
ARG NPM_EMAIL
@@ -54,7 +63,8 @@ RUN useradd -ms /bin/bash docsworker-xlarge
5463
RUN npm -g config set user root
5564
USER docsworker-xlarge
5665

57-
WORKDIR /home/docsworker-xlarge
66+
ARG WORK_DIRECTORY=/home/docsworker-xlarge
67+
WORKDIR ${WORK_DIRECTORY}
5868

5969
# get shared.mk
6070
RUN curl https://raw.githubusercontent.com/mongodb/docs-worker-pool/meta/makefiles/shared.mk -o shared.mk
@@ -79,10 +89,32 @@ RUN git clone --depth 1 https://github.com/mongodb/devhub.git snooty-devhub
7989
&& cd snooty-devhub \
8090
&& npm install --production
8191

92+
# install redoc fork
93+
RUN git clone -b redoc-cli@${REDOC_CLI_VERSION} --depth 1 https://github.com/mongodb-forks/redoc.git redoc \
94+
# Install dependencies for Redoc CLI
95+
&& cd redoc/cli \
96+
&& npm ci --omit=dev \
97+
# Install dependencies for Redoc component and building/compiling
98+
&& cd ../ \
99+
&& npm ci --omit=dev --ignore-scripts \
100+
&& npm run compile:cli
101+
82102
COPY --from=ts-compiler /home/docsworker-xlarge/package*.json ./
83103
COPY --from=ts-compiler /home/docsworker-xlarge/config config/
84104
COPY --from=ts-compiler /home/docsworker-xlarge/build ./
85105
RUN npm install
106+
107+
# OAS Page Builder module copy
108+
# Create directory and add permissions to allow node module installation
109+
RUN mkdir -p modules/oas-page-builder && chmod 755 modules/oas-page-builder
110+
COPY --from=ts-compiler /home/docsworker-xlarge/modules/oas-page-builder/package*.json ./modules/oas-page-builder/
111+
COPY --from=ts-compiler /home/docsworker-xlarge/modules/oas-page-builder/dist ./modules/oas-page-builder/
112+
RUN cd ./modules/oas-page-builder/ && npm install
113+
114+
# Needed for OAS Page Builder module in shared.mk
115+
ENV REDOC_PATH=${WORK_DIRECTORY}/redoc/cli/index.js
116+
ENV OAS_MODULE_PATH=${WORK_DIRECTORY}/modules/oas-page-builder/index.js
117+
86118
RUN mkdir repos && chmod 755 repos
87119
EXPOSE 3000
88120
CMD ["node", "app.js"]

modules/oas-page-builder/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,7 @@ npm run start -- --bundle /home/docsworker-xlarge/repos/cloud-docs/bundle.zip --
6060
| output | Path to the directory that the OpenAPI content pages should be built to. Typically, this would be the same output `public/` directory of a Snooty frontend build. |
6161
| redoc | Path to the local installation of Redoc CLI to use. This should point to the team's [fork of Redoc](https://github.com/mongodb-forks/redoc), with the target being a compiled JS file. |
6262
| repo | Path to the parsed docs repo's directory. This is to ensure that OpenAPI content pages using local OAS files can be properly sourced and passed down as an argument to Redoc CLI. |
63+
64+
## Usage in Production
65+
66+
In production, this module is installed as part of the [Docker](https://github.com/mongodb/docs-worker-pool/blob/master/Dockerfile) image build and is called as part of a target in [shared.mk](https://github.com/mongodb/docs-worker-pool/blob/meta/makefiles/shared.mk) by the autobuilder. The module is intended to be used after the frontend has completed building pages, but before `mut` uploads them.

modules/oas-page-builder/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Command } from 'commander';
55
import { getOASMetadata } from './src/services/buildMetadata';
66
import { buildOpenAPIPages } from './src/services/pageBuilder';
77
import { ModuleOptions } from './src/types';
8+
import { normalizeUrl } from './src/utils/normalizeUrl';
89

910
const program = new Command();
1011
program
@@ -31,6 +32,9 @@ const app = async (options: ModuleOptions) => {
3132
const numOASPages = oasMetadataEntries.length;
3233
console.log(`OpenAPI content pages found: ${numOASPages}.`);
3334

35+
// Normalize url since Autobuilder's MUT_PREFIX could be malformed
36+
options.siteUrl = normalizeUrl(options.siteUrl);
37+
3438
await buildOpenAPIPages(oasMetadataEntries, { ...options, siteTitle });
3539
};
3640

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
# The following env variables are typically expected to be passed down from the Autobuilder.
2+
# For local development, populate them as needed in a separate .env file.
3+
14
# Mongo instance username
2-
DB_USER=user
5+
MONGO_ATLAS_USERNAME=user
36
# Mongo instance password, corresponding to user
4-
DB_PASSWORD=password
7+
MONGO_ATLAS_PASSWORD=password
58
# Mongo instance host url
6-
DB_HOST=localhost:27017
9+
MONGO_ATLAS_HOST=localhost:27017
10+
# Snooty environment to select appropriate snooty_* database
11+
SNOOTY_ENV=dotcomprd

modules/oas-page-builder/src/services/database.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,46 @@
11
import { Db, MongoClient } from 'mongodb';
22
import { OASFile, OASFileGitHash } from './models/OASFile';
33

4-
const DB_NAME = process.env.DB_NAME || 'snooty_dotcomprd';
54
const COLLECTION_NAME = 'oas_files';
65

76
const getAtlasURL = () => {
87
const isHostLocal = process.env.DB_HOST?.includes('localhost');
98
if (isHostLocal) {
10-
return `mongodb://${process.env.DB_HOST}/?retryWrites=true&w=majority`;
9+
return `mongodb://${process.env.MONGO_ATLAS_HOST}/?retryWrites=true&w=majority`;
1110
}
12-
return `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASSWORD}@${process.env.DB_HOST}/?retryWrites=true&w=majority`;
11+
return `mongodb+srv://${process.env.MONGO_ATLAS_USERNAME}:${process.env.MONGO_ATLAS_PASSWORD}@${process.env.MONGO_ATLAS_HOST}/?retryWrites=true&w=majority`;
1312
};
1413

1514
const atlasURL = getAtlasURL();
1615
const client = new MongoClient(atlasURL);
1716
// cached db object, so we can handle initial connection process once if unitialized
1817
let dbInstance: Db;
1918

19+
const getDbName = () => {
20+
const env = process.env.SNOOTY_ENV ?? '';
21+
22+
switch (env) {
23+
// Autobuilder's prd env
24+
case 'production':
25+
case 'dotcomprd':
26+
return 'snooty_dotcomprd';
27+
// Autobuilder's pre-prd env
28+
case 'staging':
29+
case 'dotcomstg':
30+
return 'snooty_dotcomstg';
31+
default:
32+
// snooty_dotcomprd.oas_files should be guaranteed to have the latest data
33+
return 'snooty_dotcomprd';
34+
}
35+
};
36+
2037
// Handles memoization of db object, and initial connection logic if needs to be initialized
2138
const db = async () => {
2239
if (!dbInstance) {
2340
try {
2441
await client.connect();
25-
dbInstance = client.db(DB_NAME);
42+
const dbName = getDbName();
43+
dbInstance = client.db(dbName);
2644
} catch (error) {
2745
console.error(`Error at db client connection: ${error}`);
2846
throw error;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { normalizePath } from './normalizePath';
2+
3+
// Normalizes the pathname of a URL by removing repeated forward slashes
4+
export const normalizeUrl = (url: string) => {
5+
const urlObject = new URL(url);
6+
urlObject.pathname = normalizePath(urlObject.pathname);
7+
return urlObject.href;
8+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { normalizeUrl } from '../../../src/utils/normalizeUrl';
2+
3+
describe('normalizeUrl', () => {
4+
it('removes extra consecutive forward slashes', () => {
5+
const httpsUrl = 'https://mongodbcom-cdn.website.staging.corp.mongodb.com//docs-qa/atlas/app-services';
6+
let result = normalizeUrl(httpsUrl);
7+
expect(result).toBe('https://mongodbcom-cdn.website.staging.corp.mongodb.com/docs-qa/atlas/app-services');
8+
9+
// Should work regardless of protocol
10+
const httpUrl = 'http://mongodbcom-cdn.website.staging.corp.mongodb.com//docs-qa/atlas/app-services';
11+
result = normalizeUrl(httpUrl);
12+
expect(result).toBe('http://mongodbcom-cdn.website.staging.corp.mongodb.com/docs-qa/atlas/app-services');
13+
});
14+
});

src/job/productionJobHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export class ProductionJobHandler extends JobHandler {
6666
if (this.currJob?.buildCommands) {
6767
this.currJob.buildCommands[this.currJob.buildCommands.length - 1] = 'make get-build-dependencies';
6868
this.currJob.buildCommands.push('make next-gen-html');
69+
this.currJob.buildCommands.push(`make oas-page-build MUT_PREFIX=${this.currJob.payload.mutPrefix}`);
6970
}
7071
}
7172

src/job/stagingJobHandler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export class StagingJobHandler extends JobHandler {
5757
this.currJob.buildCommands[this.currJob.buildCommands.length - 1] = 'make next-gen-html';
5858
if (this.currJob.payload.repoName === 'devhub-content-integration') {
5959
this.currJob.buildCommands[this.currJob.buildCommands.length - 1] += ` STRAPI_PUBLICATION_STATE=preview`;
60+
} else {
61+
this.currJob.buildCommands.push(`make oas-page-build MUT_PREFIX=${this.currJob.payload.mutPrefix}`);
6062
}
6163
}
6264
}

tests/data/data.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export class TestDataProvider {
145145
return Array<string>().concat(genericCommands.slice(0, genericCommands.length - 1), [
146146
'make get-build-dependencies',
147147
'make next-gen-html',
148+
`make oas-page-build MUT_PREFIX=${job.payload.mutPrefix}`,
148149
]);
149150
}
150151

@@ -163,6 +164,8 @@ export class TestDataProvider {
163164
]);
164165
if (job.payload.repoName == 'devhub-content-integration') {
165166
commands[commands.length - 1] += ` STRAPI_PUBLICATION_STATE=preview`;
167+
} else {
168+
commands.push(`make oas-page-build MUT_PREFIX=${job.payload.mutPrefix}`);
166169
}
167170
return commands;
168171
}

0 commit comments

Comments
 (0)