fix(GOV-009): 完成仅源码部署最终复审
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { access, readFile } from 'node:fs/promises';
|
||||
import { access, readFile, readdir } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
@@ -32,6 +32,16 @@ const serverProcesses = Object.freeze([
|
||||
['worker', 'Worker'],
|
||||
]);
|
||||
|
||||
const ignoredScanDirectories = new Set([
|
||||
'.git',
|
||||
'.gitnexus',
|
||||
'.local',
|
||||
'dist',
|
||||
'node_modules',
|
||||
'playwright-report',
|
||||
'test-results',
|
||||
]);
|
||||
|
||||
function resolveRoot(repositoryRoot) {
|
||||
return repositoryRoot instanceof URL
|
||||
? fileURLToPath(repositoryRoot)
|
||||
@@ -54,6 +64,34 @@ async function assertDockerArtifactsAbsent(repositoryRoot) {
|
||||
throw new Error(`禁止存在 Docker 活动文件:${relativePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
const pendingDirectories = [repositoryRoot];
|
||||
while (pendingDirectories.length > 0) {
|
||||
const currentDirectory = pendingDirectories.pop();
|
||||
const entries = await readdir(currentDirectory, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory() && ignoredScanDirectories.has(entry.name)) continue;
|
||||
const absolutePath = path.join(currentDirectory, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
pendingDirectories.push(absolutePath);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile()) continue;
|
||||
|
||||
const relativePath = path.relative(repositoryRoot, absolutePath).split(path.sep).join('/');
|
||||
const segments = relativePath.split('/');
|
||||
const fileName = segments.at(-1);
|
||||
const isDockerfile = /^Dockerfile(?:\..+)?$/i.test(fileName);
|
||||
const isDockerIgnore = fileName === '.dockerignore';
|
||||
const isDockerCompose = /^docker-compose.*\.ya?ml$/i.test(fileName);
|
||||
const isComposeYaml = segments.includes('compose') && /\.ya?ml$/i.test(fileName);
|
||||
|
||||
if (isDockerfile || isDockerIgnore || isDockerCompose || isComposeYaml) {
|
||||
throw new Error(`禁止存在 Docker 活动文件:${relativePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function assertBuildOutputsPresent(repositoryRoot) {
|
||||
|
||||
@@ -81,6 +81,20 @@ test('任一 Docker 活动文件会阻断源码发布', async () => {
|
||||
await assert.rejects(() => verifySourceDeployment(root), /禁止存在 Docker 活动文件.*Dockerfile/);
|
||||
});
|
||||
|
||||
test('未预先列举的 Dockerfile 和 Compose 文件仍会阻断源码发布', async () => {
|
||||
for (const relativePath of ['ops/Dockerfile', 'deploy/compose/extra.yml']) {
|
||||
const root = await createSourceReleaseFixture();
|
||||
const absolutePath = path.join(root, relativePath);
|
||||
await mkdir(path.dirname(absolutePath), { recursive: true });
|
||||
await writeFile(absolutePath, 'services: {}\n');
|
||||
|
||||
await assert.rejects(
|
||||
() => verifySourceDeployment(root),
|
||||
new RegExp(`禁止存在 Docker 活动文件.*${relativePath.replace('/', '\\/')}`),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('Server 构建入口缺失会阻断源码发布', async () => {
|
||||
const root = await createSourceReleaseFixture({ omit: 'server/dist/apps/worker/main.js' });
|
||||
|
||||
|
||||
@@ -169,6 +169,16 @@ test('部署文档要求本机外部 Redis 和唯一 Ubuntu 源码生产路径',
|
||||
assert.match(source, /pnpm verify:release/);
|
||||
assert.match(source, /\/opt\/a-share-analysis\/releases\//);
|
||||
assert.match(source, /\/opt\/a-share-analysis\/current/);
|
||||
for (const processName of ['api', 'scheduler', 'worker']) {
|
||||
assert.match(
|
||||
source,
|
||||
new RegExp(
|
||||
`install -m 0644 deploy/systemd/a-share-${processName}\\.service\\.example /etc/systemd/system/a-share-${processName}\\.service`,
|
||||
),
|
||||
);
|
||||
assert.match(source, new RegExp(`systemctl restart a-share-${processName}\\.service`));
|
||||
}
|
||||
assert.doesNotMatch(source, /systemctl (?:restart|status) a-share-\w+\.service\.example/);
|
||||
assert.match(source, /不负责安装/);
|
||||
for (const document of [local, source]) {
|
||||
assert.match(document, /MySQL 5\.7\.42/);
|
||||
|
||||
Reference in New Issue
Block a user