mirror of
				https://gitcode.com/github-mirrors/react-native-update-cli.git
				synced 2025-10-31 06:43:10 +08:00 
			
		
		
		
	cli modular refactor (#16)
* add logic to support SENTRY_PROPERTIES parameter * remove update.json and meta.json files in ppk * udpapte * refactor modles * update * add package-module file * update * update readme file * modifu cli.json file * fix command issues * improve version workflow logic * udpate * update * update * update * udpate * udpate * add example * update readme file * udpate version * change logic to use pushy command uniformly
This commit is contained in:
		
							
								
								
									
										149
									
								
								example/modules/analytics-module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								example/modules/analytics-module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | ||||
| import type { | ||||
|   CLIModule, | ||||
|   CLIProvider, | ||||
|   CommandContext, | ||||
|   CommandResult, | ||||
| } from '../../src/types'; | ||||
|  | ||||
| /** | ||||
|  * 分析统计模块示例 | ||||
|  * 演示一个简单的分析统计功能模块 | ||||
|  */ | ||||
| export const analyticsModule: CLIModule = { | ||||
|   name: 'analytics', | ||||
|   version: '1.0.0', | ||||
|   commands: [ | ||||
|     { | ||||
|       name: 'track-deployment', | ||||
|       description: '记录部署统计信息', | ||||
|       handler: async (context: CommandContext): Promise<CommandResult> => { | ||||
|         console.log('📊 记录部署统计信息...'); | ||||
|  | ||||
|         const { platform, environment, version } = context.options; | ||||
|  | ||||
|         const deploymentData = { | ||||
|           timestamp: new Date().toISOString(), | ||||
|           platform: platform || 'unknown', | ||||
|           environment: environment || 'unknown', | ||||
|           version: version || 'unknown', | ||||
|           success: true, | ||||
|           duration: Math.floor(Math.random() * 1000) + 500, // 模拟部署时长 | ||||
|         }; | ||||
|  | ||||
|         console.log('✅ 部署统计已记录:'); | ||||
|         console.log(JSON.stringify(deploymentData, null, 2)); | ||||
|  | ||||
|         return { | ||||
|           success: true, | ||||
|           data: deploymentData, | ||||
|         }; | ||||
|       }, | ||||
|       options: { | ||||
|         platform: { | ||||
|           hasValue: true, | ||||
|           description: '平台', | ||||
|         }, | ||||
|         environment: { | ||||
|           hasValue: true, | ||||
|           description: '环境', | ||||
|         }, | ||||
|         version: { | ||||
|           hasValue: true, | ||||
|           description: '版本', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       name: 'deployment-report', | ||||
|       description: '生成部署报告', | ||||
|       handler: async (context: CommandContext): Promise<CommandResult> => { | ||||
|         console.log('📈 生成部署报告...'); | ||||
|  | ||||
|         const { days = 7 } = context.options; | ||||
|  | ||||
|         // 模拟生成报告数据 | ||||
|         const report = { | ||||
|           period: `最近 ${days} 天`, | ||||
|           totalDeployments: Math.floor(Math.random() * 50) + 10, | ||||
|           successRate: 95.5, | ||||
|           averageDuration: '2.3分钟', | ||||
|           platformBreakdown: { | ||||
|             ios: 45, | ||||
|             android: 38, | ||||
|             harmony: 12, | ||||
|           }, | ||||
|           environmentBreakdown: { | ||||
|             development: 60, | ||||
|             staging: 25, | ||||
|             production: 15, | ||||
|           }, | ||||
|         }; | ||||
|  | ||||
|         console.log('📊 部署报告:'); | ||||
|         console.log(JSON.stringify(report, null, 2)); | ||||
|  | ||||
|         return { | ||||
|           success: true, | ||||
|           data: report, | ||||
|         }; | ||||
|       }, | ||||
|       options: { | ||||
|         days: { | ||||
|           hasValue: true, | ||||
|           default: 7, | ||||
|           description: '报告天数', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
|  | ||||
|   workflows: [ | ||||
|     { | ||||
|       name: 'deploy-with-analytics', | ||||
|       description: '带统计的部署流程', | ||||
|       steps: [ | ||||
|         { | ||||
|           name: 'pre-deployment', | ||||
|           description: '部署前准备', | ||||
|           execute: async (context: CommandContext) => { | ||||
|             console.log('📋 部署前准备...'); | ||||
|             return { startTime: Date.now() }; | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           name: 'deployment', | ||||
|           description: '执行部署', | ||||
|           execute: async (context: CommandContext, previousResult: any) => { | ||||
|             console.log('🚀 执行部署...'); | ||||
|             await new Promise((resolve) => setTimeout(resolve, 2000)); | ||||
|             return { ...previousResult, deploymentCompleted: true }; | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           name: 'record-analytics', | ||||
|           description: '记录统计信息', | ||||
|           execute: async (context: CommandContext, previousResult: any) => { | ||||
|             console.log('📊 记录统计信息...'); | ||||
|             const duration = Date.now() - previousResult.startTime; | ||||
|             const analytics = { | ||||
|               duration, | ||||
|               timestamp: new Date().toISOString(), | ||||
|               success: true, | ||||
|             }; | ||||
|             console.log(`✅ 部署完成,耗时 ${duration}ms`); | ||||
|             return { ...previousResult, analytics }; | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   ], | ||||
|  | ||||
|   init: (provider: CLIProvider) => { | ||||
|     console.log('📊 分析统计模块已初始化'); | ||||
|   }, | ||||
|  | ||||
|   cleanup: () => { | ||||
|     console.log('🧹 分析统计模块清理完成'); | ||||
|   }, | ||||
| }; | ||||
							
								
								
									
										315
									
								
								example/modules/custom-deploy-module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								example/modules/custom-deploy-module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,315 @@ | ||||
| import type { | ||||
|   CLIModule, | ||||
|   CLIProvider, | ||||
|   CommandContext, | ||||
|   CommandDefinition, | ||||
|   CommandResult, | ||||
|   CustomWorkflow, | ||||
| } from '../../src/types'; | ||||
|  | ||||
| /** | ||||
|  * 自定义部署模块示例 | ||||
|  * 演示如何创建一个包含多个命令和工作流的自定义模块 | ||||
|  */ | ||||
| export const customDeployModule: CLIModule = { | ||||
|   name: 'custom-deploy', | ||||
|   version: '1.0.0', | ||||
|  | ||||
|   commands: [ | ||||
|     { | ||||
|       name: 'deploy-dev', | ||||
|       description: '部署到开发环境', | ||||
|       handler: async (context: CommandContext): Promise<CommandResult> => { | ||||
|         console.log('🚀 开始部署到开发环境...'); | ||||
|  | ||||
|         const { platform = 'ios', force = false } = context.options; | ||||
|  | ||||
|         try { | ||||
|           // 模拟部署逻辑 | ||||
|           console.log(`📱 平台: ${platform}`); | ||||
|           console.log(`🔧 强制部署: ${force ? '是' : '否'}`); | ||||
|  | ||||
|           // 模拟一些部署步骤 | ||||
|           console.log('1. 检查环境配置...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1000)); | ||||
|  | ||||
|           console.log('2. 构建应用包...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1500)); | ||||
|  | ||||
|           console.log('3. 上传到开发服务器...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1000)); | ||||
|  | ||||
|           console.log('✅ 部署到开发环境完成!'); | ||||
|  | ||||
|           return { | ||||
|             success: true, | ||||
|             data: { | ||||
|               environment: 'development', | ||||
|               platform, | ||||
|               deployTime: new Date().toISOString(), | ||||
|               buildId: `dev-${Date.now()}`, | ||||
|             }, | ||||
|           }; | ||||
|         } catch (error) { | ||||
|           return { | ||||
|             success: false, | ||||
|             error: error instanceof Error ? error.message : '部署失败', | ||||
|           }; | ||||
|         } | ||||
|       }, | ||||
|       options: { | ||||
|         platform: { | ||||
|           hasValue: true, | ||||
|           default: 'ios', | ||||
|           description: '目标平台 (ios/android/harmony)', | ||||
|         }, | ||||
|         force: { | ||||
|           hasValue: false, | ||||
|           default: false, | ||||
|           description: '强制部署,跳过确认', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       name: 'deploy-prod', | ||||
|       description: '部署到生产环境', | ||||
|       handler: async (context: CommandContext): Promise<CommandResult> => { | ||||
|         console.log('🔥 开始部署到生产环境...'); | ||||
|  | ||||
|         const { version, rollout = 100 } = context.options; | ||||
|  | ||||
|         if (!version) { | ||||
|           return { | ||||
|             success: false, | ||||
|             error: '生产部署必须指定版本号', | ||||
|           }; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|           console.log(`📦 版本: ${version}`); | ||||
|           console.log(`📊 发布比例: ${rollout}%`); | ||||
|  | ||||
|           console.log('1. 安全检查...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1000)); | ||||
|  | ||||
|           console.log('2. 生产构建...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 2000)); | ||||
|  | ||||
|           console.log('3. 部署到生产环境...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1500)); | ||||
|  | ||||
|           console.log('4. 健康检查...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 800)); | ||||
|  | ||||
|           console.log('🎉 生产部署完成!'); | ||||
|  | ||||
|           return { | ||||
|             success: true, | ||||
|             data: { | ||||
|               environment: 'production', | ||||
|               version, | ||||
|               rollout, | ||||
|               deployTime: new Date().toISOString(), | ||||
|               buildId: `prod-${Date.now()}`, | ||||
|             }, | ||||
|           }; | ||||
|         } catch (error) { | ||||
|           return { | ||||
|             success: false, | ||||
|             error: error instanceof Error ? error.message : '生产部署失败', | ||||
|           }; | ||||
|         } | ||||
|       }, | ||||
|       options: { | ||||
|         version: { | ||||
|           hasValue: true, | ||||
|           description: '版本号 (必需)', | ||||
|         }, | ||||
|         rollout: { | ||||
|           hasValue: true, | ||||
|           default: 100, | ||||
|           description: '发布比例 (0-100)', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       name: 'rollback', | ||||
|       description: '回滚到指定版本', | ||||
|       handler: async (context: CommandContext): Promise<CommandResult> => { | ||||
|         console.log('🔄 开始回滚操作...'); | ||||
|  | ||||
|         const { version, immediate = false } = context.options; | ||||
|  | ||||
|         if (!version) { | ||||
|           return { | ||||
|             success: false, | ||||
|             error: '回滚操作必须指定目标版本', | ||||
|           }; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|           console.log(`🎯 目标版本: ${version}`); | ||||
|           console.log(`⚡ 立即回滚: ${immediate ? '是' : '否'}`); | ||||
|  | ||||
|           console.log('1. 验证目标版本...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 800)); | ||||
|  | ||||
|           console.log('2. 准备回滚...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1000)); | ||||
|  | ||||
|           console.log('3. 执行回滚...'); | ||||
|           await new Promise((resolve) => setTimeout(resolve, 1200)); | ||||
|  | ||||
|           console.log('✅ 回滚完成!'); | ||||
|  | ||||
|           return { | ||||
|             success: true, | ||||
|             data: { | ||||
|               targetVersion: version, | ||||
|               rollbackTime: new Date().toISOString(), | ||||
|               immediate, | ||||
|             }, | ||||
|           }; | ||||
|         } catch (error) { | ||||
|           return { | ||||
|             success: false, | ||||
|             error: error instanceof Error ? error.message : '回滚失败', | ||||
|           }; | ||||
|         } | ||||
|       }, | ||||
|       options: { | ||||
|         version: { | ||||
|           hasValue: true, | ||||
|           description: '目标版本号 (必需)', | ||||
|         }, | ||||
|         immediate: { | ||||
|           hasValue: false, | ||||
|           default: false, | ||||
|           description: '立即回滚,不等待确认', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
|  | ||||
|   workflows: [ | ||||
|     { | ||||
|       name: 'full-deploy', | ||||
|       description: '完整部署流程:开发 -> 测试 -> 生产', | ||||
|       steps: [ | ||||
|         { | ||||
|           name: 'deploy-to-dev', | ||||
|           description: '部署到开发环境', | ||||
|           execute: async (context: CommandContext) => { | ||||
|             console.log('🔧 步骤 1: 部署到开发环境'); | ||||
|             // 这里可以调用其他命令或执行自定义逻辑 | ||||
|             return { environment: 'dev', status: 'completed' }; | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           name: 'run-tests', | ||||
|           description: '运行自动化测试', | ||||
|           execute: async (context: CommandContext, previousResult: any) => { | ||||
|             console.log('🧪 步骤 2: 运行自动化测试'); | ||||
|             console.log('   - 单元测试...'); | ||||
|             await new Promise((resolve) => setTimeout(resolve, 1000)); | ||||
|             console.log('   - 集成测试...'); | ||||
|             await new Promise((resolve) => setTimeout(resolve, 1500)); | ||||
|             console.log('   - E2E测试...'); | ||||
|             await new Promise((resolve) => setTimeout(resolve, 2000)); | ||||
|             return { ...previousResult, tests: 'passed' }; | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           name: 'deploy-to-prod', | ||||
|           description: '部署到生产环境', | ||||
|           execute: async (context: CommandContext, previousResult: any) => { | ||||
|             console.log('🚀 步骤 3: 部署到生产环境'); | ||||
|             if (previousResult.tests !== 'passed') { | ||||
|               throw new Error('测试未通过,无法部署到生产环境'); | ||||
|             } | ||||
|             return { | ||||
|               ...previousResult, | ||||
|               environment: 'production', | ||||
|               status: 'deployed', | ||||
|             }; | ||||
|           }, | ||||
|           condition: (context: CommandContext) => { | ||||
|             // 只有在非跳过生产部署的情况下才执行 | ||||
|             return !context.options.skipProd; | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|       validate: (context: CommandContext) => { | ||||
|         if (!context.options.version) { | ||||
|           console.error('❌ 完整部署流程需要指定版本号'); | ||||
|           return false; | ||||
|         } | ||||
|         return true; | ||||
|       }, | ||||
|       options: { | ||||
|         version: { | ||||
|           hasValue: true, | ||||
|           description: '版本号 (必需)', | ||||
|         }, | ||||
|         skipProd: { | ||||
|           hasValue: false, | ||||
|           default: false, | ||||
|           description: '跳过生产部署', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       name: 'hotfix-deploy', | ||||
|       description: '热修复快速部署流程', | ||||
|       steps: [ | ||||
|         { | ||||
|           name: 'validate-hotfix', | ||||
|           description: '验证热修复', | ||||
|           execute: async (context: CommandContext) => { | ||||
|             console.log('🔍 验证热修复内容...'); | ||||
|             const { hotfixId } = context.options; | ||||
|             if (!hotfixId) { | ||||
|               throw new Error('缺少热修复ID'); | ||||
|             } | ||||
|             return { hotfixId, validated: true }; | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           name: 'emergency-deploy', | ||||
|           description: '紧急部署', | ||||
|           execute: async (context: CommandContext, previousResult: any) => { | ||||
|             console.log('🚨 执行紧急部署...'); | ||||
|             console.log('⚡ 快速构建...'); | ||||
|             await new Promise((resolve) => setTimeout(resolve, 800)); | ||||
|             console.log('🚀 立即发布...'); | ||||
|             await new Promise((resolve) => setTimeout(resolve, 600)); | ||||
|             return { | ||||
|               ...previousResult, | ||||
|               deployed: true, | ||||
|               deployTime: new Date().toISOString(), | ||||
|             }; | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|       options: { | ||||
|         hotfixId: { | ||||
|           hasValue: true, | ||||
|           description: '热修复ID (必需)', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
|  | ||||
|   init: (provider: CLIProvider) => { | ||||
|     console.log('🎯 自定义部署模块已初始化'); | ||||
|     console.log('   可用命令: deploy-dev, deploy-prod, rollback'); | ||||
|     console.log('   可用工作流: full-deploy, hotfix-deploy'); | ||||
|   }, | ||||
|  | ||||
|   cleanup: () => { | ||||
|     console.log('🧹 自定义部署模块清理完成'); | ||||
|   }, | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user
	 波仔糕
					波仔糕