Skip to main content
Glama
status.ts6.08 kB
/** * CI/CD Status Command */ import chalk from 'chalk'; import * as fs from 'fs'; import * as path from 'path'; import { execSync } from 'child_process'; import { Platform } from './templates.js'; interface CICDStatus { hasGitea: boolean; hasGitHub: boolean; giteaFiles: string[]; githubFiles: string[]; hasContributing: boolean; branches: { current: string; main: string | null; dev: string | null; }; remoteInfo: { platform: Platform | null; owner: string; repo: string; url: string; } | null; } /** * 获取 CI/CD 状态 */ function getCICDStatus(): CICDStatus { const status: CICDStatus = { hasGitea: false, hasGitHub: false, giteaFiles: [], githubFiles: [], hasContributing: false, branches: { current: '', main: null, dev: null, }, remoteInfo: null, }; // 检查工作流目录 const giteaDir = '.gitea/workflows'; const githubDir = '.github/workflows'; if (fs.existsSync(giteaDir)) { status.hasGitea = true; status.giteaFiles = fs.readdirSync(giteaDir).filter((f) => f.endsWith('.yaml') || f.endsWith('.yml')); } if (fs.existsSync(githubDir)) { status.hasGitHub = true; status.githubFiles = fs.readdirSync(githubDir).filter((f) => f.endsWith('.yaml') || f.endsWith('.yml')); } // 检查 CONTRIBUTING.md status.hasContributing = fs.existsSync('CONTRIBUTING.md'); // 获取分支信息 try { status.branches.current = execSync('git branch --show-current', { encoding: 'utf-8' }).trim(); // 获取所有分支 const branches = execSync('git branch -a', { encoding: 'utf-8' }) .split('\n') .map((b) => b.trim().replace('* ', '')); // 检测主分支 for (const mainName of ['main', 'master']) { if (branches.some((b) => b === mainName || b.endsWith(`/${mainName}`))) { status.branches.main = mainName; break; } } // 检测开发分支 for (const devName of ['dev', 'develop', 'development']) { if (branches.some((b) => b === devName || b.endsWith(`/${devName}`))) { status.branches.dev = devName; break; } } } catch { // 忽略错误 } // 获取远程信息 try { const remoteUrl = execSync('git remote get-url origin', { encoding: 'utf-8' }).trim(); let platform: Platform | null = null; let owner = ''; let repo = ''; if (remoteUrl.includes('github.com')) { platform = 'github'; } else if (remoteUrl.includes('gitea') || remoteUrl.includes('git.')) { platform = 'gitea'; } // 解析 URL if (remoteUrl.startsWith('https://')) { const urlPath = remoteUrl.replace(/^https:\/\/[^/]+\//, '').replace(/\.git$/, ''); const parts = urlPath.split('/'); if (parts.length >= 2) { owner = parts[0]; repo = parts[1]; } } else if (remoteUrl.startsWith('git@')) { const urlPath = remoteUrl.replace(/^git@[^:]+:/, '').replace(/\.git$/, ''); const parts = urlPath.split('/'); if (parts.length >= 2) { owner = parts[0]; repo = parts[1]; } } status.remoteInfo = { platform, owner, repo, url: remoteUrl }; } catch { // 忽略错误 } return status; } /** * 显示 CI/CD 状态 */ export async function showStatus(options: { json?: boolean }): Promise<void> { const status = getCICDStatus(); if (options.json) { console.log(JSON.stringify(status, null, 2)); return; } console.log(chalk.bold('\n📊 CI/CD 配置状态\n')); // 仓库信息 if (status.remoteInfo) { console.log(chalk.bold('🔗 仓库信息')); console.log(` 所有者: ${chalk.cyan(status.remoteInfo.owner)}`); console.log(` 仓库名: ${chalk.cyan(status.remoteInfo.repo)}`); console.log(` 平台: ${chalk.cyan(status.remoteInfo.platform || '未知')}`); console.log(` URL: ${chalk.gray(status.remoteInfo.url)}`); console.log(); } else { console.log(chalk.yellow('⚠️ 未检测到 Git 仓库\n')); } // 分支信息 console.log(chalk.bold('🌳 分支信息')); console.log(` 当前分支: ${chalk.cyan(status.branches.current || '未知')}`); console.log( ` 主分支: ${status.branches.main ? chalk.green(status.branches.main) : chalk.yellow('未检测到')}` ); console.log( ` 开发分支: ${status.branches.dev ? chalk.green(status.branches.dev) : chalk.yellow('未检测到')}` ); console.log(); // Gitea Actions console.log(chalk.bold('🔧 Gitea Actions')); if (status.hasGitea) { console.log(` 状态: ${chalk.green('已配置')}`); console.log(` 工作流文件:`); for (const file of status.giteaFiles) { console.log(` - ${chalk.cyan(file)}`); } } else { console.log(` 状态: ${chalk.yellow('未配置')}`); } console.log(); // GitHub Actions console.log(chalk.bold('🐙 GitHub Actions')); if (status.hasGitHub) { console.log(` 状态: ${chalk.green('已配置')}`); console.log(` 工作流文件:`); for (const file of status.githubFiles) { console.log(` - ${chalk.cyan(file)}`); } } else { console.log(` 状态: ${chalk.yellow('未配置')}`); } console.log(); // 文档 console.log(chalk.bold('📝 文档')); console.log( ` CONTRIBUTING.md: ${status.hasContributing ? chalk.green('存在') : chalk.yellow('不存在')}` ); console.log(); // 建议 const suggestions: string[] = []; if (!status.hasGitea && !status.hasGitHub) { suggestions.push('运行 `keactl cicd init` 初始化 CI/CD 配置'); } if (!status.branches.dev && status.branches.main) { suggestions.push(`创建开发分支: git checkout -b dev && git push -u origin dev`); } if (!status.hasContributing) { suggestions.push('运行 `keactl cicd init` 生成 CONTRIBUTING.md'); } if (suggestions.length > 0) { console.log(chalk.bold('💡 建议')); for (const suggestion of suggestions) { console.log(` - ${suggestion}`); } console.log(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SupenBysz/gitea-mcp-tool'

If you have feedback or need assistance with the MCP directory API, please join our Discord server