Skip to content

Commit e02a02f

Browse files
committed
🏗️ chore(build): generate docs markdown before MkDocs; add staged build modes
Fix the docs page still showing a placeholder after builds by splitting the pipeline and reordering steps so docs markdown is generated first and API artifacts are produced last without being overwritten. Changes: - scripts/build.js: - Add staged modes: `--docs-md-only` and `--api-only` - Skip `dist/api` writes and public copy when `--docs-md-only` - Skip docs (`docs/data.md`) generation when `--api-only` - Keep existing behavior for default (no flag) runs - package.json: - Update `build:all` to run in three stages: `node scripts/build.js --docs-md-only && npm run docs:build && node scripts/build.js --api-only` - .github/workflows/build.yml: - New order: generate docs markdown → mkdocs build → build API data - Use the new flags in CI to prevent cross-step overwrites Outcome: - `docs/data.md` is populated with full provider/model tables before MkDocs runs - MkDocs outputs to `dist/` without clobbering `/api/*` - API endpoints remain available at `/api/*` on GitHub Pages - Deterministic, reproducible builds locally and in CI
1 parent f6eb828 commit e02a02f

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

.github/workflows/build.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ jobs:
6161
npm run check || echo "CHANGED=$?" >> $GITHUB_OUTPUT
6262
shell: bash
6363

64+
- name: Generate docs markdown from API
65+
if: ${{ steps.check.outputs.CHANGED == '2' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' }}
66+
run: |
67+
node scripts/build.js --docs-md-only
68+
6469
- name: Build MkDocs documentation
6570
if: ${{ steps.check.outputs.CHANGED == '2' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' }}
6671
run: |
@@ -70,9 +75,9 @@ jobs:
7075
if: ${{ steps.check.outputs.CHANGED == '2' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' }}
7176
run: |
7277
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.force }}" = "true" ]; then
73-
npm run build:force
78+
node scripts/build.js --api-only --force
7479
else
75-
npm run build
80+
node scripts/build.js --api-only
7681
fi
7782
7883
- name: Commit and push changes

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"docs:install": "pip install -r requirements.txt",
1616
"docs:build": "mkdocs build --site-dir dist",
1717
"docs:serve": "mkdocs serve",
18-
"build:all": "npm run docs:build && npm run build"
18+
"build:all": "node scripts/build.js --docs-md-only && npm run docs:build && node scripts/build.js --api-only"
1919
},
2020
"dependencies": {},
2121
"devDependencies": {}

scripts/build.js

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,17 @@ async function main() {
117117
const args = parseArgv(process.argv);
118118
const dryRun = !!args.check;
119119
const force = !!args.force;
120+
const docsMdOnly = !!args['docs-md-only'] || !!args.docsMdOnly;
121+
const apiOnly = !!args['api-only'] || !!args.apiOnly;
120122

121123
ensureDirSync(CACHE_DIR);
122-
ensureDirSync(DIST_DIR);
123-
ensureDirSync(API_DIR);
124124
ensureDirSync(DATA_DIR);
125-
// 拷贝 public 到 dist 根
126-
copyDirSyncIfExists(path.join(ROOT, 'public'), DIST_DIR);
125+
if (!docsMdOnly) {
126+
ensureDirSync(DIST_DIR);
127+
ensureDirSync(API_DIR);
128+
// 拷贝 public 到 dist 根
129+
copyDirSyncIfExists(path.join(ROOT, 'public'), DIST_DIR);
130+
}
127131

128132
const SOURCE_URL = 'https://models.dev/api.json';
129133
let source;
@@ -171,10 +175,10 @@ async function main() {
171175
const warnings = [];
172176

173177
// 写索引
174-
if (writeJSONIfChanged(path.join(API_DIR, 'index.json'), { providers: providerIndex, models: modelIndex }, { dryRun })) changes += 1;
178+
if (!docsMdOnly && writeJSONIfChanged(path.join(API_DIR, 'index.json'), { providers: providerIndex, models: modelIndex }, { dryRun })) changes += 1;
175179

176180
// 写单独的供应商信息接口
177-
if (writeJSONIfChanged(path.join(API_DIR, 'providers.json'), { providers: providerIndex }, { dryRun })) changes += 1;
181+
if (!docsMdOnly && writeJSONIfChanged(path.join(API_DIR, 'providers.json'), { providers: providerIndex }, { dryRun })) changes += 1;
178182

179183
// 写完整模型信息(类似 models.dev/api.json 格式)
180184
const allModelsData = {};
@@ -223,7 +227,7 @@ async function main() {
223227
allModelsData[providerId].models = processedModels;
224228
}
225229

226-
if (writeJSONIfChanged(path.join(API_DIR, 'all.json'), allModelsData, { dryRun })) changes += 1;
230+
if (!docsMdOnly && writeJSONIfChanged(path.join(API_DIR, 'all.json'), allModelsData, { dryRun })) changes += 1;
227231

228232
// 生成价格换算接口
229233
const priceConversionData = {
@@ -257,14 +261,14 @@ async function main() {
257261
}
258262
}
259263

260-
if (writeJSONIfChanged(path.join(API_DIR, 'newapi-ratio_config-v1-base.json'), priceConversionData, { dryRun })) changes += 1;
264+
if (!docsMdOnly && writeJSONIfChanged(path.join(API_DIR, 'newapi-ratio_config-v1-base.json'), priceConversionData, { dryRun })) changes += 1;
261265

262266
// 写 providers 与 models 详情,且支持 overrides 与 auto 策略
263267
for (const [providerId, provider] of Object.entries(normalized.providers || {})) {
264268
const safeProvider = sanitizeFileSegment(providerId);
265269
const providerOut = applyOverrides(provider, overrides.providers?.[providerId]);
266270
const providerPath = path.join(API_DIR, 'providers', `${safeProvider}.json`);
267-
if (writeJSONIfChanged(providerPath, providerOut, { dryRun })) changes += 1;
271+
if (!docsMdOnly && writeJSONIfChanged(providerPath, providerOut, { dryRun })) changes += 1;
268272

269273
const providerModelsDir = path.join(API_DIR, 'models', safeProvider);
270274
ensureDirSync(providerModelsDir);
@@ -316,7 +320,7 @@ async function main() {
316320
continue;
317321
}
318322

319-
if (writeJSONIfChanged(existingPath, next, { dryRun })) changes += 1;
323+
if (!docsMdOnly && writeJSONIfChanged(existingPath, next, { dryRun })) changes += 1;
320324
}
321325
}
322326

@@ -335,12 +339,14 @@ async function main() {
335339
manifest.warnings = warnings;
336340
for (const w of warnings) console.warn('[warn]', w);
337341
}
338-
if (writeJSONIfChanged(path.join(API_DIR, 'manifest.json'), manifest, { dryRun })) changes += 1;
342+
if (!docsMdOnly && writeJSONIfChanged(path.join(API_DIR, 'manifest.json'), manifest, { dryRun })) changes += 1;
339343

340-
// 生成数据浏览页面的 Markdown
341-
const dataMarkdown = generateDataMarkdown(allModelsData, providerIndex, modelIndex, manifest);
342-
const dataMarkdownPath = path.join(ROOT, 'docs', 'data.md');
343-
if (writeMarkdownIfChanged(dataMarkdownPath, dataMarkdown, { dryRun })) changes += 1;
344+
// 生成数据浏览页面的 Markdown(当未指定 api-only 时)
345+
if (!apiOnly) {
346+
const dataMarkdown = generateDataMarkdown(allModelsData, providerIndex, modelIndex, manifest);
347+
const dataMarkdownPath = path.join(ROOT, 'docs', 'data.md');
348+
if (writeMarkdownIfChanged(dataMarkdownPath, dataMarkdown, { dryRun })) changes += 1;
349+
}
344350

345351
if (dryRun) {
346352
if (changes > 0) {

0 commit comments

Comments
 (0)