1
0
mirror of https://gitcode.com/github-mirrors/react-native-update-cli.git synced 2025-09-16 09:41:38 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee

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:
波仔糕
2025-07-24 11:46:20 +08:00
committed by GitHub
parent 4cb5f7fa4e
commit e98bcf504f
53 changed files with 10853 additions and 855 deletions

View 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('🧹 分析统计模块清理完成');
},
};

View 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('🧹 自定义部署模块清理完成');
},
};