功能(文档与桌面):完善文件预览下载与客户端构建基线
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

- 保存文档版本原始文件名,规范下载响应并持久化上传目录\n- 增加 PDF.js 预览、桌面保存打开流程及统一错误反馈\n- 统一 Node.js 22.13 构建基线并收紧临时文件权限门禁\n- 补充迁移、单元测试、发布检查与运维文档
This commit is contained in:
Cheng Zhou
2026-07-13 18:40:48 +08:00
parent ab59476d10
commit 44db5db838
40 changed files with 1817 additions and 87 deletions
@@ -114,6 +114,12 @@ const verifyCapabilities = async () => {
"notification:allow-request-permission",
"notification:allow-notify",
];
const requiredTemporaryFilePermissions = [
"fs:allow-read-file",
"fs:allow-write-file",
"fs:allow-mkdir",
"fs:allow-remove",
];
for (const file of files) {
const capability = await readJson(resolve(capabilitiesDir, file));
@@ -141,6 +147,9 @@ const verifyCapabilities = async () => {
for (const identifier of requiredNotificationPermissions) {
assert(identifiers.includes(identifier), `${file}: missing ${identifier}.`);
}
for (const identifier of requiredTemporaryFilePermissions) {
assert(identifiers.includes(identifier), `${file}: missing ${identifier}.`);
}
const fsScope = permissions.find((permission) => permissionIdentifier(permission) === "fs:scope");
assert(Boolean(fsScope), `${file}: fs:scope is required and must be constrained to temporary files.`);
@@ -320,6 +329,7 @@ const verifyUpdaterBoundary = async () => {
const verifyWorkflowGates = async () => {
const packageInfo = await readJson(resolve(frontendDir, "package.json"));
assert(packageInfo.engines?.node === ">=22.13.0", "package.json must require Node.js >=22.13.0.");
const requiredScripts = [
"desktop:build:macos-release",
"desktop:update-feed:create",
@@ -350,6 +360,7 @@ const verifyWorkflowGates = async () => {
}
assert(workflow.includes("VITE_BUILD_CHANNEL"), "Client quality gates workflow must inject VITE_BUILD_CHANNEL.");
assert(workflow.includes("VITE_BUILD_COMMIT"), "Client quality gates workflow must inject VITE_BUILD_COMMIT.");
assert(workflow.match(/node-version: "22\.13"/g)?.length === 2, "Client quality gates must use Node.js 22.13 for Web and Desktop jobs.");
const releaseWorkflow = await readFile(resolve(rootDir, ".github/workflows/desktop-release-candidate.yml"), "utf8");
const requiredReleaseWorkflowTokens = [
@@ -368,6 +379,7 @@ const verifyWorkflowGates = async () => {
for (const token of requiredReleaseWorkflowTokens) {
assert(releaseWorkflow.includes(token), `Desktop release candidate workflow must include ${token}.`);
}
assert(releaseWorkflow.includes('node-version: "22.13"'), "Desktop release candidates must use Node.js 22.13.");
const windowsInternalWorkflow = await readFile(resolve(rootDir, ".github/workflows/desktop-windows-internal.yml"), "utf8");
const requiredWindowsInternalWorkflowTokens = [
@@ -407,6 +419,22 @@ const verifyWorkflowGates = async () => {
for (const token of forbiddenWindowsInternalWorkflowTokens) {
assert(!windowsInternalWorkflow.includes(token), `Desktop Windows internal workflow must not include ${token}.`);
}
assert(windowsInternalWorkflow.includes('node-version: "22.13"'), "Desktop Windows internal builds must use Node.js 22.13.");
for (const dockerfile of [resolve(frontendDir, "Dockerfile"), resolve(rootDir, "nginx/Dockerfile")]) {
const dockerSource = await readFile(dockerfile, "utf8");
assert(dockerSource.startsWith("FROM node:22.13-alpine"), `${relative(rootDir, dockerfile)} must build with Node.js 22.13.`);
}
const developmentCompose = await readFile(resolve(rootDir, "docker-compose.dev.yaml"), "utf8");
assert(developmentCompose.includes("image: node:22.13-alpine"), "Development frontend container must use Node.js 22.13.");
assert(developmentCompose.includes('dependency_hash="$$lock_hash:$$(node --version)"'), "Development dependency cache must include the Node.js version.");
assert(developmentCompose.includes("pdfjs-dist"), "Development dependency checks must include PDF.js.");
assert(
developmentCompose.includes("frontend_node_modules_node22:/app/node_modules") &&
developmentCompose.includes("frontend_node_modules_node22:"),
"Development dependencies must use the Node.js 22-specific volume.",
);
};
await verifyTauriConfig();