mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
fix(docs): correct versioned nav links and local dev version routing (#74)
This commit is contained in:
@@ -1,10 +1,27 @@
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
||||
import {
|
||||
cpSync,
|
||||
existsSync,
|
||||
lstatSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
readdirSync,
|
||||
readlinkSync,
|
||||
rmSync,
|
||||
symlinkSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs';
|
||||
import { join, resolve } from 'node:path';
|
||||
import {
|
||||
collectSharedAssetPaths,
|
||||
dedupeVersionedPublicAssets,
|
||||
pruneArchiveCacheGenerations,
|
||||
} from './docs-versioned-assets';
|
||||
import {
|
||||
buildVersionManifest,
|
||||
stableTagsWithDocs,
|
||||
versionArchiveCacheKey,
|
||||
versionArchiveCacheName,
|
||||
versionOutputPath,
|
||||
versionPath,
|
||||
@@ -18,7 +35,11 @@ const archiveCacheRoot = join(repoRoot, '.tmp/docs-versioned-archive-cache');
|
||||
const maxCloudflareFiles = 20_000;
|
||||
const maxCloudflareFileBytes = 25 * 1024 * 1024;
|
||||
|
||||
function run(command: string, args: string[], options: { cwd?: string; env?: NodeJS.ProcessEnv } = {}) {
|
||||
function run(
|
||||
command: string,
|
||||
args: string[],
|
||||
options: { cwd?: string; env?: NodeJS.ProcessEnv } = {},
|
||||
) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd: options.cwd ?? repoRoot,
|
||||
env: options.env ?? process.env,
|
||||
@@ -144,12 +165,14 @@ function buildDocs(options: {
|
||||
latestStable: string;
|
||||
manifestJson: string;
|
||||
}) {
|
||||
console.info(`[docs] building ${options.version ?? options.channel} -> ${options.base}`);
|
||||
run('bun', ['run', '--cwd', currentDocsSite, 'vitepress', 'build', options.snapshotDocsSite], {
|
||||
cwd: repoRoot,
|
||||
env: {
|
||||
...process.env,
|
||||
SUBMINER_DOCS_BASE: options.base,
|
||||
SUBMINER_DOCS_OUT_DIR: options.outDir,
|
||||
SUBMINER_DOCS_SOURCE_DIR: options.snapshotDocsSite,
|
||||
SUBMINER_DOCS_CHANNEL: options.channel,
|
||||
SUBMINER_DOCS_VERSION: options.version ?? '',
|
||||
SUBMINER_DOCS_LATEST_STABLE: options.latestStable,
|
||||
@@ -160,25 +183,28 @@ function buildDocs(options: {
|
||||
}
|
||||
|
||||
function updateHashWithPath(hash: ReturnType<typeof createHash>, path: string) {
|
||||
if (isGeneratedVitePressPath(path)) {
|
||||
if (isSharedInternalsHashIgnoredPath(path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stat = lstatSync(path);
|
||||
hash.update(path.replace(repoRoot, ''));
|
||||
hash.update(String(stat.mode));
|
||||
const relativePath = path.replace(repoRoot, '');
|
||||
|
||||
if (stat.isSymbolicLink()) {
|
||||
hash.update(`symlink:${relativePath}`);
|
||||
hash.update(readlinkSync(path));
|
||||
return;
|
||||
}
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
hash.update(`dir:${relativePath}`);
|
||||
for (const entry of readdirSync(path).sort()) {
|
||||
updateHashWithPath(hash, join(path, entry));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
hash.update(`file:${relativePath}`);
|
||||
hash.update(readFileSync(path));
|
||||
}
|
||||
|
||||
@@ -186,8 +212,15 @@ function isGeneratedVitePressPath(path: string): boolean {
|
||||
return /[\\/]\\.vitepress[\\/](cache|dist)([\\/]|$)/.test(path);
|
||||
}
|
||||
|
||||
function isSharedInternalsHashIgnoredPath(path: string): boolean {
|
||||
return isGeneratedVitePressPath(path) || /\.test\.[cm]?[jt]s$/.test(path);
|
||||
}
|
||||
|
||||
function computeSharedInternalsHash(): string {
|
||||
const hash = createHash('sha256');
|
||||
hash.update(
|
||||
`version-link-origin:${process.env.SUBMINER_DOCS_VERSION_LINK_ORIGIN === 'local' ? 'local' : 'production'}`,
|
||||
);
|
||||
const paths = [
|
||||
join(currentDocsSite, '.vitepress'),
|
||||
join(currentDocsSite, 'public/assets/fonts'),
|
||||
@@ -216,6 +249,7 @@ function restoreCachedArchive(version: string, sharedInternalsHash: string): boo
|
||||
return false;
|
||||
}
|
||||
|
||||
console.info(`[docs] cache hit ${version}`);
|
||||
cpSync(cachedArchive, join(aggregateOutDir, versionOutputPath(version)), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
@@ -267,9 +301,7 @@ function assertCloudflarePagesLimits(root: string) {
|
||||
}
|
||||
|
||||
if (oversizedFiles.length > 0) {
|
||||
throw new Error(
|
||||
`Versioned docs output has files over 25 MiB:\n${oversizedFiles.join('\n')}`,
|
||||
);
|
||||
throw new Error(`Versioned docs output has files over 25 MiB:\n${oversizedFiles.join('\n')}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +316,9 @@ function main() {
|
||||
const manifest = buildVersionManifest({ latestStable, stableVersions });
|
||||
const manifestJson = JSON.stringify(manifest);
|
||||
const sharedInternalsHash = computeSharedInternalsHash();
|
||||
const archiveCacheKey = versionArchiveCacheKey({ sharedInternalsHash, manifestJson });
|
||||
const sharedAssetPaths = collectSharedAssetPaths(join(currentDocsSite, 'public/assets'));
|
||||
console.info(`[docs] archive cache key ${archiveCacheKey.slice(0, 12)}`);
|
||||
|
||||
rmSync(buildRoot, { recursive: true, force: true });
|
||||
rmSync(aggregateOutDir, { recursive: true, force: true });
|
||||
@@ -302,11 +337,13 @@ function main() {
|
||||
});
|
||||
|
||||
for (const version of stableVersions) {
|
||||
if (restoreCachedArchive(version, sharedInternalsHash)) {
|
||||
if (restoreCachedArchive(version, archiveCacheKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const snapshot = version === latestStable ? latestStableSnapshot : prepareSnapshot(version, version);
|
||||
console.info(`[docs] rebuilding archive ${version}`);
|
||||
const snapshot =
|
||||
version === latestStable ? latestStableSnapshot : prepareSnapshot(version, version);
|
||||
buildDocs({
|
||||
snapshotDocsSite: snapshot,
|
||||
base: versionPath(version),
|
||||
@@ -316,7 +353,12 @@ function main() {
|
||||
latestStable,
|
||||
manifestJson,
|
||||
});
|
||||
saveArchiveCache(version, sharedInternalsHash);
|
||||
dedupeVersionedPublicAssets({
|
||||
outDir: join(aggregateOutDir, versionOutputPath(version)),
|
||||
base: versionPath(version),
|
||||
sharedAssetPaths,
|
||||
});
|
||||
saveArchiveCache(version, archiveCacheKey);
|
||||
}
|
||||
|
||||
const mainSnapshot = prepareSnapshot('main');
|
||||
@@ -329,9 +371,22 @@ function main() {
|
||||
latestStable,
|
||||
manifestJson,
|
||||
});
|
||||
dedupeVersionedPublicAssets({
|
||||
outDir: join(aggregateOutDir, 'main'),
|
||||
base: '/main/',
|
||||
sharedAssetPaths,
|
||||
});
|
||||
|
||||
writeFileSync(join(aggregateOutDir, 'versions.json'), `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
assertCloudflarePagesLimits(aggregateOutDir);
|
||||
const prunedArchives = pruneArchiveCacheGenerations({
|
||||
cacheRoot: archiveCacheRoot,
|
||||
activeCacheKey: archiveCacheKey,
|
||||
});
|
||||
if (prunedArchives.length > 0) {
|
||||
console.info(`[docs] pruned ${prunedArchives.length} stale archive cache directories`);
|
||||
}
|
||||
rmSync(buildRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user