build(docs): Better API docs cleaning (#23153)

The API docs directories for the website contain a mix of generated and
manually authored files, so cleaning the API docs is not as simple as
just deleting the entire directory.

We previously had a sketchy workaround the cleaned all `.md` files, but
left any `.mdx` files alone, and had a script override in place to
ensure we ran `clean:api-documentation` before running
`build:api-documentation`.

This PR introduces a more wholistic solution to the fundamental problem,
which is that we want to clean up all of the git-ignored contents of the
API docs directories, while leaving the checked-in files alone.


[AB#24394](https://dev.azure.com/fluidframework/235294da-091d-4c29-84fc-cdfc3d90890b/_workitems/edit/24394)
This commit is contained in:
Joshua Smithrud 2024-11-20 10:37:42 -08:00 коммит произвёл GitHub
Родитель 8e4df0d886
Коммит 6330f4a687
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
6 изменённых файлов: 75 добавлений и 8 удалений

Просмотреть файл

@ -69,6 +69,8 @@ module.exports = {
files: ["docusaurus.config.ts", "playwright.config.ts", "infra/**/*"],
rules: {
"import/no-internal-modules": "off",
"import/no-nodejs-modules": "off",
"unicorn/no-process-exit": "off",
},
},
],

Просмотреть файл

@ -18,6 +18,7 @@ import chalk from "chalk";
import fs from "fs-extra";
import path from "path";
import { cleanIgnored } from "../clean-ignored.mjs";
import { admonitionNodeType } from "./admonition-node.mjs";
import { layoutContent } from "./api-documentation-layout.mjs";
import {
@ -60,12 +61,8 @@ export async function renderApiDocumentation(inputDir, outputDir, uriRootDir, ap
logProgress("Removing existing generated API docs...");
await fs.ensureDir(outputDir);
// TODO:AB#24394: Add logic to clean existing API docs output directory while respecting our .gitignore config.
// Most of the files in the `api` directories are generated and git-ignored, but not all of them.
// We need to clean up all of the git-ignored files, but not the user-created files.
// Currently we work around this by running the `clean:api-documentation` script before running the script that
// builds the API documentation, but ideally that shouldn't be required.
// await fs.emptyDir(outputDir);
// Clean existing generated API documentation files, skipping any manually authored files under the same parent directory.
await cleanIgnored(outputDir);
// Process API reports
logProgress("Loading API model...");

Просмотреть файл

@ -0,0 +1,43 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
import path from "node:path";
import { fileURLToPath } from "node:url";
import config from "../config/docs-versions.mjs";
import { cleanIgnored } from "./clean-ignored.mjs";
const dirname = path.dirname(fileURLToPath(import.meta.url));
const docsRootDirectory = path.join(dirname, "..");
/**
* Cleans all generated API documentation files.
*
* @remarks
* The API docs directories contain a mix of generated and manually authored files, so cleaning is not
* as simple as just deleting the entire directory.
* To better support this pattern, this script uses `git clean` to remove only the files that are git-ignored,
* and leave other files intact.
*/
// Build list of paths from our config's set of API docs versions.
// Expressed relative to the root of the docs directory.
const apiDocsPaths = [
path.relative(docsRootDirectory, config.currentVersion.apiDocs.outputPath),
...config.otherVersions.map((versionConfig) =>
path.relative(docsRootDirectory, versionConfig.apiDocs.outputPath),
),
path.relative(docsRootDirectory, config.local.apiDocs.outputPath),
];
console.log(`Cleaning generated API documentation under: [${apiDocsPaths.join(", ")}]...`);
try {
await Promise.all(apiDocsPaths.map(async (pathSpec) => cleanIgnored(pathSpec)));
} catch (error) {
console.error("Error cleaning API docs:", error);
process.exit(1);
}
console.log("API documentation cleaned successfully.");

Просмотреть файл

@ -0,0 +1,22 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
import path from "node:path";
import { fileURLToPath } from "node:url";
import { simpleGit, CleanOptions } from "simple-git";
const dirname = path.dirname(fileURLToPath(import.meta.url));
const docsRootDirectory = path.join(dirname, "..");
const git = simpleGit({ cwd: docsRootDirectory });
/**
* Cleans up all git-ignored files under the provided path.
* @param {string} pathSpec - The path to clean. Expressed relative to the root of the docs directory.
*/
export async function cleanIgnored(pathSpec) {
await git.clean(CleanOptions.FORCE + CleanOptions.IGNORED_ONLY, [pathSpec]);
}

Просмотреть файл

@ -12,7 +12,6 @@
"author": "Microsoft and contributors",
"scripts": {
"build": "concurrently npm:build:site npm:build:test",
"prebuild:api-documentation": "npm run clean:api-documentation",
"build:api-documentation": "npm run download-doc-models && npm run generate-api-documentation",
"prebuild:docusaurus": "npm run generate-versions",
"build:docusaurus": "docusaurus build",
@ -23,7 +22,7 @@
"check-links": "linkcheck http://localhost:3000 --skip-file skipped-urls.txt",
"ci:check-links": "start-server-and-test \"npm run serve -- --no-open\" 3000 check-links",
"clean": "concurrently \"npm:clean:*\"",
"clean:api-documentation": "rimraf --glob \"docs/api/**/*.md\" \"versioned_docs/*/api/**/*.md\"",
"clean:api-documentation": "node ./infra/clean-api-documentation.mjs",
"clean:doc-models": "rimraf --glob .doc-models",
"clean:docusaurus": "docusaurus clear",
"clean:test": "rimraf --glob test-results",
@ -95,6 +94,7 @@
"react": "^18.0.0",
"react-dom": "^18.0.0",
"rimraf": "^5.0.10",
"simple-git": "^3.27.0",
"start-server-and-test": "^2.0.8",
"typescript": "~5.5.2"
},

Просмотреть файл

@ -113,6 +113,9 @@ importers:
rimraf:
specifier: ^5.0.10
version: 5.0.10
simple-git:
specifier: ^3.27.0
version: 3.27.0
start-server-and-test:
specifier: ^2.0.8
version: 2.0.8