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' });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user