3fc3399032
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m41s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m8s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 7m16s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 7m38s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m11s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m11s
Project CI / Repository checks (pull_request) Successful in 4m22s
Project CI / Frontend tests (pull_request) Successful in 5m52s
Project CI / Native shell tests (pull_request) Successful in 9m52s
Project CI / Backend tests (pull_request) Successful in 11m3s
Project CI / AI game creator shell web tests (pull_request) Successful in 6m41s
新增内置 Unity 插件与自包含 Attach helper,固定上游版本并保留许可证 统一 Runner 执行归属、项目身份校验、回执确认和不确定结果阻断 接入 Unity 工程导入、Agent 工具目录及 Windows 构建分发 补齐插件测试、CI 执行入口和 Windows .NET 10 工具链检查 记录真实 Unity 连接、执行、重载恢复及 Runner 边界验证
176 lines
6.1 KiB
JavaScript
176 lines
6.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { afterEach, test } from 'node:test';
|
|
|
|
import {
|
|
collectNpmWorkspaceErrors,
|
|
REQUIRED_PACKAGE_MANAGER,
|
|
REQUIRED_WORKSPACES,
|
|
} from './check-npm-workspaces.mjs';
|
|
|
|
const fixtureDirectories = [];
|
|
|
|
const workspaceNames = {
|
|
'apps/admin-web': '@genarrative/admin-web',
|
|
'apps/ai-game-creator-shell': '@genarrative/ai-game-creator-shell',
|
|
'apps/desktop-shell': '@genarrative/desktop-shell',
|
|
'apps/mobile-shell': '@genarrative/mobile-shell',
|
|
'apps/preview-deployer-web': '@genarrative/preview-deployer-web',
|
|
'packages/image-canvas-core': '@genarrative/image-canvas-core',
|
|
'packages/image-canvas-react': '@genarrative/image-canvas-react',
|
|
'packages/agc-plugin-sdk': '@genarrative/agc-plugin-sdk',
|
|
'packages/shared': '@genarrative/shared',
|
|
'plugins/agc-cocos-editor': '@genarrative/agc-plugin-cocos-editor',
|
|
'plugins/agc-unity-editor': '@genarrative/agc-plugin-unity-editor',
|
|
'tools/spine-json-export-validator':
|
|
'@genarrative/spine-json-export-validator',
|
|
};
|
|
|
|
const localDependencies = {
|
|
'apps/admin-web': { '@genarrative/shared': '0.1.0' },
|
|
'apps/ai-game-creator-shell': {
|
|
'@genarrative/image-canvas-core': '0.1.0',
|
|
'@genarrative/image-canvas-react': '0.1.0',
|
|
'@genarrative/shared': '0.1.0',
|
|
},
|
|
'apps/mobile-shell': { '@genarrative/shared': '0.1.0' },
|
|
'packages/image-canvas-react': { '@genarrative/image-canvas-core': '0.1.0' },
|
|
'plugins/agc-cocos-editor': { '@genarrative/agc-plugin-sdk': '0.1.0' },
|
|
'plugins/agc-unity-editor': { '@genarrative/agc-plugin-sdk': '0.1.0' },
|
|
};
|
|
|
|
afterEach(() => {
|
|
for (const fixtureDirectory of fixtureDirectories.splice(0)) {
|
|
fs.rmSync(fixtureDirectory, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
function writeJson(rootDir, relativePath, value) {
|
|
const absolutePath = path.join(rootDir, relativePath);
|
|
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
|
|
fs.writeFileSync(absolutePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
}
|
|
|
|
function createValidFixture() {
|
|
const rootDir = fs.mkdtempSync(
|
|
path.join(os.tmpdir(), 'genarrative-npm-workspaces-'),
|
|
);
|
|
fixtureDirectories.push(rootDir);
|
|
|
|
writeJson(rootDir, 'package.json', {
|
|
name: 'fixture-root',
|
|
private: true,
|
|
version: '0.0.0',
|
|
packageManager: REQUIRED_PACKAGE_MANAGER,
|
|
workspaces: REQUIRED_WORKSPACES,
|
|
dependencies: {
|
|
'@genarrative/image-canvas-core': '0.1.0',
|
|
'@genarrative/image-canvas-react': '0.1.0',
|
|
'@genarrative/shared': '0.1.0',
|
|
},
|
|
});
|
|
|
|
const packages = {
|
|
'': {
|
|
name: 'fixture-root',
|
|
version: '0.0.0',
|
|
workspaces: REQUIRED_WORKSPACES,
|
|
},
|
|
};
|
|
for (const workspacePath of REQUIRED_WORKSPACES) {
|
|
const manifest = {
|
|
name: workspaceNames[workspacePath],
|
|
private: true,
|
|
version:
|
|
workspacePath === 'apps/ai-game-creator-shell' ? '0.1.12' : '0.1.0',
|
|
dependencies: localDependencies[workspacePath],
|
|
};
|
|
writeJson(rootDir, `${workspacePath}/package.json`, manifest);
|
|
packages[workspacePath] = manifest;
|
|
packages[`node_modules/${manifest.name}`] = {
|
|
resolved: workspacePath,
|
|
link: true,
|
|
};
|
|
}
|
|
writeJson(rootDir, 'package-lock.json', {
|
|
name: 'fixture-root',
|
|
version: '0.0.0',
|
|
lockfileVersion: 3,
|
|
requires: true,
|
|
packages,
|
|
});
|
|
|
|
return rootDir;
|
|
}
|
|
|
|
function readJson(rootDir, relativePath) {
|
|
return JSON.parse(fs.readFileSync(path.join(rootDir, relativePath), 'utf8'));
|
|
}
|
|
|
|
test('accepts the fixed npm workspace topology and root lock links', () => {
|
|
const rootDir = createValidFixture();
|
|
assert.deepEqual(collectNpmWorkspaceErrors(rootDir), []);
|
|
});
|
|
|
|
test('rejects workspace protocol and non-exact local package versions', () => {
|
|
const rootDir = createValidFixture();
|
|
const manifestPath = 'apps/admin-web/package.json';
|
|
const manifest = readJson(rootDir, manifestPath);
|
|
manifest.dependencies['@genarrative/shared'] = 'workspace:*';
|
|
writeJson(rootDir, manifestPath, manifest);
|
|
|
|
const errors = collectNpmWorkspaceErrors(rootDir).join('\n');
|
|
assert.match(errors, /must not use the unsupported workspace: protocol/u);
|
|
assert.match(errors, /must use exact version 0\.1\.0/u);
|
|
});
|
|
|
|
test('rejects missing workspace entries and links in the root lock', () => {
|
|
const rootDir = createValidFixture();
|
|
const lockfile = readJson(rootDir, 'package-lock.json');
|
|
delete lockfile.packages['apps/mobile-shell'];
|
|
delete lockfile.packages['node_modules/@genarrative/mobile-shell'];
|
|
writeJson(rootDir, 'package-lock.json', lockfile);
|
|
|
|
const errors = collectNpmWorkspaceErrors(rootDir).join('\n');
|
|
assert.match(errors, /packages\["apps\/mobile-shell"\]/u);
|
|
assert.match(errors, /node_modules\/@genarrative\/mobile-shell/u);
|
|
});
|
|
|
|
test('rejects nested package locks and shrinkwrap files', () => {
|
|
const rootDir = createValidFixture();
|
|
writeJson(rootDir, 'apps/admin-web/package-lock.json', {});
|
|
writeJson(rootDir, 'packages/shared/fixtures/npm-shrinkwrap.json', {});
|
|
|
|
const errors = collectNpmWorkspaceErrors(rootDir).join('\n');
|
|
assert.match(errors, /apps\/admin-web\/package-lock\.json/u);
|
|
assert.match(errors, /packages\/shared\/fixtures\/npm-shrinkwrap\.json/u);
|
|
});
|
|
|
|
test('rejects package manager and explicit workspace list drift', () => {
|
|
const rootDir = createValidFixture();
|
|
const rootPackage = readJson(rootDir, 'package.json');
|
|
rootPackage.packageManager = 'npm@11.0.0';
|
|
rootPackage.workspaces = ['apps/*', 'packages/*'];
|
|
writeJson(rootDir, 'package.json', rootPackage);
|
|
|
|
const errors = collectNpmWorkspaceErrors(rootDir).join('\n');
|
|
assert.match(errors, /packageManager must be npm@10\.9\.7/u);
|
|
assert.match(errors, /workspaces must be the explicit ordered list/u);
|
|
});
|
|
|
|
test('rejects test and build aliases tied to a nested workspace install', () => {
|
|
const rootDir = createValidFixture();
|
|
fs.writeFileSync(
|
|
path.join(rootDir, 'vitest.config.ts'),
|
|
"const cubone = 'apps/ai-game-creator-shell/node_modules/@cubone/react-file-manager';\n",
|
|
);
|
|
|
|
const errors = collectNpmWorkspaceErrors(rootDir).join('\n');
|
|
assert.match(
|
|
errors,
|
|
/vitest\.config\.ts: resolve dependencies from the workspace manifest/u,
|
|
);
|
|
});
|