按系统性审计修复 M3:指纹反判断、守卫死代码、fail-open 与卫生项
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m23s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m55s
Project CI / Native shell tests (pull_request) Failing after 1m26s
Project CI / Frontend tests (pull_request) Successful in 1m36s
Project CI / Backend tests (pull_request) Successful in 3m37s
Project CI / AI game creator shell web tests (pull_request) Failing after 34s
Project CI / Repository checks (pull_request) Successful in 1m49s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 7m37s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m19s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m23s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m55s
Project CI / Native shell tests (pull_request) Failing after 1m26s
Project CI / Frontend tests (pull_request) Successful in 1m36s
Project CI / Backend tests (pull_request) Successful in 3m37s
Project CI / AI game creator shell web tests (pull_request) Failing after 34s
Project CI / Repository checks (pull_request) Successful in 1m49s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 7m37s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m19s
- P1-1:pluginSourceFingerprint 的判断取反(prepared 内容与交付态真正进入指纹);pluginTreeMatches 的「当前目标/feature 下不该存在却存在 → 重建」从死代码修活 - P1-7:package_layout 的 `sha256_file(x).ok() != ...` 改为 map_err 传播,两侧读失败不再被判为「相等」 - P3-2:copyNativePayloads 的 'plugins' 字面量改由声明 sourceDirectory 派生 - P3-5:payload 交付内容一致时跳过写入(命中缓存保持零写入、时间戳稳定) - P3-7:门禁提示里的脚本名改为 agc:bundled-resources:sync - P3-8:删除已无写入方的 resources/cocos-editor-bridge 占位目录 - P2-4:root 包装脚本补结尾 `--`,文档里的 prepare 命令可直接复制执行 - 验证:工具用例全绿、声明门禁通过
This commit is contained in:
@@ -453,7 +453,7 @@ function renderGenerated(declaration) {
|
||||
return `// @generated by apps/ai-game-creator-shell/scripts/check-package-layout.mjs
|
||||
// 来源:build_support/package-layout.json。不要手工编辑本文件。
|
||||
// 修改随包资源布局请编辑声明文件,然后运行
|
||||
// npm run agc:package-layout:sync(在仓库根目录)
|
||||
// npm run agc:bundled-resources:sync(在仓库根目录)
|
||||
// 门禁会校验两者一致(npm run agc:typecheck 链内含 check-package-layout.mjs)。
|
||||
|
||||
pub const DECLARATION_SCHEMA: &str = ${rustString(EXPECTED_SCHEMA)};
|
||||
@@ -615,7 +615,7 @@ function main() {
|
||||
`随包资源声明与 Rust 常量不一致:`,
|
||||
` 声明:${path.relative(process.cwd(), DECLARATION_PATH)}`,
|
||||
` 生成:${path.relative(process.cwd(), GENERATED_PATH)}`,
|
||||
'请运行:npm run agc:package-layout:sync',
|
||||
'请运行:npm run agc:bundled-resources:sync',
|
||||
].join('\n'),
|
||||
);
|
||||
process.exit(1);
|
||||
|
||||
@@ -660,8 +660,8 @@ function pluginSourceFingerprint(declaration, plugins, target, features) {
|
||||
for (const plugin of plugins) {
|
||||
for (const subdirectory of declaration.plugins.subdirectories) {
|
||||
if (
|
||||
subdirectoryAppliesToPlugin(subdirectory, plugin.name) ||
|
||||
subdirectoryEnabled(subdirectory, target, features)
|
||||
!subdirectoryAppliesToPlugin(subdirectory, plugin.name) ||
|
||||
!subdirectoryEnabled(subdirectory, target, features)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@@ -747,10 +747,7 @@ function pluginTreeMatches(
|
||||
return false;
|
||||
}
|
||||
for (const subdirectory of declaration.plugins.subdirectories) {
|
||||
if (
|
||||
!subdirectoryAppliesToPlugin(subdirectory, plugin.name) ||
|
||||
!subdirectoryEnabled(subdirectory, target, features)
|
||||
) {
|
||||
if (!subdirectoryAppliesToPlugin(subdirectory, plugin.name)) {
|
||||
continue;
|
||||
}
|
||||
const stagedDirectory = path.join(pluginDestination, subdirectory.path);
|
||||
@@ -763,10 +760,7 @@ function pluginTreeMatches(
|
||||
}
|
||||
const sourceRoot = path.join(plugin.root, subdirectory.path);
|
||||
if (subdirectory.origin !== 'source') {
|
||||
if (
|
||||
existsSync(sourceRoot) &&
|
||||
!existsSync(path.join(pluginDestination, subdirectory.path))
|
||||
) {
|
||||
if (existsSync(sourceRoot) && !existsSync(stagedDirectory)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
@@ -1053,6 +1047,21 @@ function copyPreparedPayloads({
|
||||
}
|
||||
}
|
||||
|
||||
/// 内容一致时不重写(保住时间戳与「命中缓存零写入」口径)。
|
||||
function copyFilePreservingModeIfChanged(source, destination) {
|
||||
if (existsSync(destination)) {
|
||||
const sourceInfo = statSync(source);
|
||||
const destinationInfo = statSync(destination);
|
||||
if (
|
||||
sourceInfo.size === destinationInfo.size &&
|
||||
Buffer.compare(readFileSync(source), readFileSync(destination)) === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
copyFilePreservingMode(source, destination);
|
||||
}
|
||||
|
||||
/// Cocos bridge 的 dll 既要进插件工作区(唯一真源),也要进随包目录。
|
||||
function copyNativePayloads({
|
||||
declaration,
|
||||
@@ -1100,7 +1109,7 @@ function copyNativePayloads({
|
||||
}
|
||||
const destinationName =
|
||||
payload.destinationFileName ?? payload.sourceFileName;
|
||||
copyFilePreservingMode(
|
||||
copyFilePreservingModeIfChanged(
|
||||
source,
|
||||
path.join(
|
||||
repoRoot,
|
||||
@@ -1110,7 +1119,7 @@ function copyNativePayloads({
|
||||
destinationName,
|
||||
),
|
||||
);
|
||||
copyFilePreservingMode(
|
||||
copyFilePreservingModeIfChanged(
|
||||
source,
|
||||
path.join(
|
||||
staging,
|
||||
|
||||
@@ -280,7 +280,15 @@ pub fn validate_staged_plugins(
|
||||
if !staged_manifest.is_file() {
|
||||
return Err(format!("随包插件缺少清单:{}", staged_manifest.display()));
|
||||
}
|
||||
if sha256_file(&source_manifest).ok() != sha256_file(&staged_manifest).ok() {
|
||||
let source_manifest_digest = sha256_file(&source_manifest)
|
||||
.map_err(|error| format!("读取插件清单失败 {}:{error}", source_manifest.display()))?;
|
||||
let staged_manifest_digest = sha256_file(&staged_manifest).map_err(|error| {
|
||||
format!(
|
||||
"读取随包插件清单失败 {}:{error}",
|
||||
staged_manifest.display()
|
||||
)
|
||||
})?;
|
||||
if source_manifest_digest != staged_manifest_digest {
|
||||
return Err(format!(
|
||||
"随包插件清单与源码不一致:{}",
|
||||
staged_manifest.display()
|
||||
@@ -319,7 +327,13 @@ pub fn validate_staged_plugins(
|
||||
if !staged_file.is_file() {
|
||||
return Err(format!("随包插件缺少文件:{}", staged_file.display()));
|
||||
}
|
||||
if sha256_file(&source_file).ok() != sha256_file(&staged_file).ok() {
|
||||
let source_digest = sha256_file(&source_file).map_err(|error| {
|
||||
format!("读取插件文件失败 {}:{error}", source_file.display())
|
||||
})?;
|
||||
let staged_digest = sha256_file(&staged_file).map_err(|error| {
|
||||
format!("读取随包插件文件失败 {}:{error}", staged_file.display())
|
||||
})?;
|
||||
if source_digest != staged_digest {
|
||||
return Err(format!(
|
||||
"随包插件文件与源码不一致:{}",
|
||||
staged_file.display()
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
*.dll
|
||||
+2
-2
@@ -170,8 +170,8 @@
|
||||
"agc:skill-pack:sync": "npm --prefix apps/ai-game-creator-shell run skill-pack:sync",
|
||||
"agc:bundled-resources:check": "npm --prefix apps/ai-game-creator-shell run bundled-resources:check",
|
||||
"agc:bundled-resources:sync": "npm --prefix apps/ai-game-creator-shell run bundled-resources:sync",
|
||||
"agc:bundled-resources:prepare": "npm --prefix apps/ai-game-creator-shell run bundled-resources:prepare",
|
||||
"agc:bundled-resources:test": "npm --prefix apps/ai-game-creator-shell run bundled-resources:test",
|
||||
"agc:bundled-resources:prepare": "npm --prefix apps/ai-game-creator-shell run bundled-resources:prepare --",
|
||||
"agc:bundled-resources:test": "npm --prefix apps/ai-game-creator-shell run bundled-resources:test --",
|
||||
"agc:plugins:test": "node --test plugins/agc-cocos-editor/src/entry.test.mjs plugins/agc-unity-editor/src/entry.test.mjs plugins/agc-godot-editor/src/entry.test.mjs",
|
||||
"agc:plugins:native-test": "cargo test --manifest-path plugins/agc-cocos-editor/native/cocos-editor-bridge/Cargo.toml && cargo test --locked --manifest-path plugins/agc-unity-editor/native/unity-editor-bridge/Cargo.toml && cargo test --locked --manifest-path plugins/agc-godot-editor/native/godot-editor-bridge/Cargo.toml",
|
||||
"agc:plugins:check": "npm run agc:plugins:test && npm run agc:plugins:native-test",
|
||||
|
||||
Reference in New Issue
Block a user