Merge pull request #24 from HuangLuGuang/main

feat(repoScan): 基于项目 repository_type 决定仓库类型,支持私有 GitLab 域名/IP;移除 URL正则判断
This commit is contained in:
lintsinghua 2025-10-30 14:19:02 +08:00 committed by GitHub
commit 7d1a9aac74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 23 additions and 15 deletions

View File

@ -67,10 +67,13 @@ export async function runRepositoryAudit(params: {
} as any); } as any);
const taskId = (task as any).id as string; const taskId = (task as any).id as string;
// 基于项目的 repository_type 决定仓库类型,不再使用正则
// 检测仓库类型 const project = await api.getProjectById(params.projectId);
const isGitHub = /github\.com/i.test(params.repoUrl); const repoUrl = params.repoUrl || project?.repository_url || '';
const isGitLab = /gitlab\.com|gitlab\./i.test(params.repoUrl); if (!repoUrl) throw new Error('仓库地址为空,请在项目中填写 repository_url');
const repoTypeKey = project?.repository_type;
const isGitHub = repoTypeKey === 'github';
const isGitLab = repoTypeKey === 'gitlab';
const repoType = isGitHub ? "GitHub" : isGitLab ? "GitLab" : "Git"; const repoType = isGitHub ? "GitHub" : isGitLab ? "GitLab" : "Git";
console.log(`🚀 ${repoType}任务已创建: ${taskId},准备启动后台扫描...`); console.log(`🚀 ${repoType}任务已创建: ${taskId},准备启动后台扫描...`);
@ -80,7 +83,7 @@ export async function runRepositoryAudit(params: {
logger.info(LogCategory.SYSTEM, `开始审计任务: ${taskId}`, { logger.info(LogCategory.SYSTEM, `开始审计任务: ${taskId}`, {
taskId, taskId,
projectId: params.projectId, projectId: params.projectId,
repoUrl: params.repoUrl, repoUrl,
branch, branch,
repoType, repoType,
}); });
@ -96,7 +99,7 @@ export async function runRepositoryAudit(params: {
if (isGitHub) { if (isGitHub) {
// GitHub 仓库处理 // GitHub 仓库处理
const m = params.repoUrl.match(/github\.com\/(.+?)\/(.+?)(?:\.git)?$/i); const m = repoUrl.match(/github\.com\/(.+?)\/(.+?)(?:\.git)?$/i);
if (!m) throw new Error("GitHub 仓库 URL 格式错误,例如 https://github.com/owner/repo"); if (!m) throw new Error("GitHub 仓库 URL 格式错误,例如 https://github.com/owner/repo");
const owner = m[1]; const owner = m[1];
const repo = m[2]; const repo = m[2];
@ -107,12 +110,17 @@ export async function runRepositoryAudit(params: {
.filter(i => i.type === "blob" && isTextFile(i.path) && !matchExclude(i.path, excludes)) .filter(i => i.type === "blob" && isTextFile(i.path) && !matchExclude(i.path, excludes))
.map(i => ({ path: i.path, url: `https://raw.githubusercontent.com/${owner}/${repo}/${encodeURIComponent(branch)}/${i.path}` })); .map(i => ({ path: i.path, url: `https://raw.githubusercontent.com/${owner}/${repo}/${encodeURIComponent(branch)}/${i.path}` }));
} else if (isGitLab) { } else if (isGitLab) {
// GitLab 仓库处理 // GitLab 仓库处理(支持自定义域名/IP基于仓库 URL 动态构建 API 基地址
const m = params.repoUrl.match(/gitlab\.com\/(.+?)\/(.+?)(?:\.git)?$/i); const u = new URL(repoUrl);
if (!m) throw new Error("GitLab 仓库 URL 格式错误,例如 https://gitlab.com/owner/repo"); const base = `${u.protocol}//${u.host}`; // 例如 https://git.dev-rs.com 或 http://192.168.1.10
const projectPath = encodeURIComponent(`${m[1]}/${m[2]}`); // 解析项目路径,支持多级 group/subgroup去除开头/结尾斜杠与 .git 后缀
const path = u.pathname.replace(/^\/+|\/+$/g, '').replace(/\.git$/i, '');
if (!path) {
throw new Error("GitLab 仓库 URL 格式错误,例如 https://<your-gitlab-host>/<group>/<project>");
}
const projectPath = encodeURIComponent(path);
const treeUrl = `https://gitlab.com/api/v4/projects/${projectPath}/repository/tree?ref=${encodeURIComponent(branch)}&recursive=true&per_page=100`; const treeUrl = `${base}/api/v4/projects/${projectPath}/repository/tree?ref=${encodeURIComponent(branch)}&recursive=true&per_page=100`;
console.log(`📡 GitLab API: 获取仓库文件树 - ${treeUrl}`); console.log(`📡 GitLab API: 获取仓库文件树 - ${treeUrl}`);
const tree = await gitlabApi<Array<{ path: string; type: string }>>(treeUrl, params.gitlabToken); const tree = await gitlabApi<Array<{ path: string; type: string }>>(treeUrl, params.gitlabToken);
console.log(`✅ GitLab API: 获取到 ${tree.length} 个项目`); console.log(`✅ GitLab API: 获取到 ${tree.length} 个项目`);
@ -122,7 +130,7 @@ export async function runRepositoryAudit(params: {
.map(i => ({ .map(i => ({
path: i.path, path: i.path,
// GitLab 文件 API 路径需要完整的 URL 编码(包括斜杠) // GitLab 文件 API 路径需要完整的 URL 编码(包括斜杠)
url: `https://gitlab.com/api/v4/projects/${projectPath}/repository/files/${encodeURIComponent(i.path)}/raw?ref=${encodeURIComponent(branch)}` url: `${base}/api/v4/projects/${projectPath}/repository/files/${encodeURIComponent(i.path)}/raw?ref=${encodeURIComponent(branch)}`
})); }));
console.log(`📝 GitLab: 过滤后可分析文件 ${files.length}`); console.log(`📝 GitLab: 过滤后可分析文件 ${files.length}`);