{"id":35170076,"url":"https://github.com/reactnativecn/react-native-update-cli","last_synced_at":"2026-04-12T17:57:20.309Z","repository":{"id":271091275,"uuid":"241402903","full_name":"reactnativecn/react-native-update-cli","owner":"reactnativecn","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-22T04:03:53.000Z","size":956,"stargazers_count":4,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-27T22:08:35.899Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reactnativecn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-18T15:55:14.000Z","updated_at":"2026-01-22T04:03:26.000Z","dependencies_parsed_at":"2025-01-05T13:18:57.896Z","dependency_job_id":"b3ba0a52-8ee4-4436-8079-4a35840ffc96","html_url":"https://github.com/reactnativecn/react-native-update-cli","commit_stats":null,"previous_names":["reactnativecn/react-native-pushy-cli","reactnativecn/react-native-update-cli","sunnylqm/react-native-update-cli"],"tags_count":125,"template":false,"template_full_name":null,"purl":"pkg:github/reactnativecn/react-native-update-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactnativecn%2Freact-native-update-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactnativecn%2Freact-native-update-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactnativecn%2Freact-native-update-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactnativecn%2Freact-native-update-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reactnativecn","download_url":"https://codeload.github.com/reactnativecn/react-native-update-cli/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactnativecn%2Freact-native-update-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28949274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T14:26:55.697Z","status":"ssl_error","status_checked_at":"2026-01-31T14:26:52.545Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-28T20:05:57.324Z","updated_at":"2026-01-31T18:06:52.625Z","avatar_url":"https://github.com/reactnativecn.png","language":"TypeScript","readme":"# React Native Update CLI\n\n[中文文档](./README.zh-CN.md) | [Chinese Documentation](./README.zh-CN.md)\n\nA unified React Native Update CLI that supports both traditional commands and modular architecture with custom publishing workflows.\n\n## 🚀 Features\n\n- **Unified CLI**: Single `pushy` command for all functionality\n- **Backward Compatibility**: All existing commands work as before\n- **Modular Architecture**: Split CLI functionality into independent modules\n- **Custom Workflows**: Support for creating custom publishing workflows\n- **Extensibility**: Users can import and register custom modules\n- **Type Safety**: Complete TypeScript type support\n\n## 📦 Installation\n\n```bash\nnpm install react-native-update-cli\n```\n\n## 🎯 Quick Start\n\n### Basic Usage\n\n```bash\n# Use unified CLI\nnpx pushy help\n\n# List all available commands and workflows\nnpx pushy list\n\n# Execute built-in workflow\nnpx pushy workflow setup-app\n\n# Execute custom workflow\nnpx pushy workflow custom-publish\n```\n\n### Programmatic Usage\n\n```typescript\nimport { moduleManager, CLIProviderImpl } from 'react-native-update-cli';\n\n// Get CLI provider\nconst provider = moduleManager.getProvider();\n\n// Execute bundling\nconst bundleResult = await provider.bundle({\n  platform: 'ios',\n  dev: false,\n  sourcemap: true,\n});\n\n// Publish version\nconst publishResult = await provider.publish({\n  name: 'v1.2.3',\n  description: 'Bug fixes and improvements',\n  rollout: 100,\n});\n```\n\n## 🔧 Creating Custom Modules\n\n### 1. Define Module\n\n```typescript\nimport type {\n  CLIModule,\n  CommandDefinition,\n  CustomWorkflow,\n} from 'react-native-update-cli';\n\nexport const myCustomModule: CLIModule = {\n  name: 'my-custom',\n  version: '1.0.0',\n\n  commands: [\n    {\n      name: 'custom-command',\n      description: 'My custom command',\n      handler: async (context) =\u003e {\n        console.log('Executing custom command...');\n        return {\n          success: true,\n          data: { message: 'Custom command executed' },\n        };\n      },\n      options: {\n        param: { hasValue: true, description: 'Custom parameter' },\n      },\n    },\n  ],\n\n  workflows: [\n    {\n      name: 'my-workflow',\n      description: 'My custom workflow',\n      steps: [\n        {\n          name: 'step1',\n          description: 'First step',\n          execute: async (context, previousResult) =\u003e {\n            console.log('Executing step 1...');\n            return { step1Completed: true };\n          },\n        },\n        {\n          name: 'step2',\n          description: 'Second step',\n          execute: async (context, previousResult) =\u003e {\n            console.log('Executing step 2...');\n            return { ...previousResult, step2Completed: true };\n          },\n        },\n      ],\n    },\n  ],\n\n  init: (provider) =\u003e {\n    console.log('Custom module initialized');\n  },\n\n  cleanup: () =\u003e {\n    console.log('Custom module cleanup');\n  },\n};\n```\n\n### 2. Register Module\n\n```typescript\nimport { moduleManager } from 'react-native-update-cli';\nimport { myCustomModule } from './my-custom-module';\n\n// Register custom module\nmoduleManager.registerModule(myCustomModule);\n\n// Execute custom command\nconst result = await moduleManager.executeCommand('custom-command', {\n  args: [],\n  options: { param: 'value' },\n});\n\n// Execute custom workflow\nconst workflowResult = await moduleManager.executeWorkflow('my-workflow', {\n  args: [],\n  options: {},\n});\n```\n\n## 🔄 Workflow System\n\n### Workflow Steps\n\nEach workflow step contains:\n\n- `name`: Step name\n- `description`: Step description\n- `execute`: Execution function\n- `condition`: Optional condition function\n\n### Conditional Execution\n\n```typescript\n{\n  name: 'conditional-step',\n  description: 'Only execute in production',\n  execute: async (context, previousResult) =\u003e {\n    // Execution logic\n  },\n  condition: (context) =\u003e {\n    return context.options.environment === 'production';\n  }\n}\n```\n\n### Workflow Validation\n\n```typescript\n{\n  name: 'validated-workflow',\n  description: 'Workflow with validation',\n  steps: [...],\n  validate: (context) =\u003e {\n    if (!context.options.requiredParam) {\n      console.error('Required parameter missing');\n      return false;\n    }\n    return true;\n  }\n}\n```\n\n## 📋 Built-in Modules\n\n### Bundle Module (`bundle`)\n\n- `bundle`: Bundle JavaScript code and optionally publish\n- `diff`: Generate differences between two PPK files\n- `hdiff`: Generate hdiff between two PPK files\n- `diffFromApk`: Generate differences from APK files\n- `hdiffFromApk`: Generate hdiff from APK files\n- `hdiffFromApp`: Generate hdiff from APP files\n- `diffFromIpa`: Generate differences from IPA files\n- `hdiffFromIpa`: Generate hdiff from IPA files\n\n### Version Module (`version`)\n\n- `publish`: Publish new version\n- `versions`: List all versions\n- `update`: Update version information\n- `updateVersionInfo`: Update version metadata\n\n### App Module (`app`)\n\n- `createApp`: Create new application\n- `apps`: List all applications\n- `selectApp`: Select application\n- `deleteApp`: Delete application\n\n### Package Module (`package`)\n\n- `uploadIpa`: Upload IPA files (supports `--version` to override extracted version)\n- `uploadApk`: Upload APK files (supports `--version` to override extracted version)\n- `uploadAab`: Upload AAB files (converted to APK, supports `--version`, `--includeAllSplits`, `--splits`)\n- `uploadApp`: Upload APP files (supports `--version` to override extracted version)\n- `parseApp`: Parse APP file information\n- `parseIpa`: Parse IPA file information\n- `parseApk`: Parse APK file information\n- `extractApk`: Extract a universal APK from an AAB (supports `--output`, `--includeAllSplits`, `--splits`)\n- `packages`: List packages\n\n### User Module (`user`)\n\n- `login`: Login\n- `logout`: Logout\n- `me`: Show user information\n\n## 🛠️ CLI Provider API\n\n### Core Functionality\n\n```typescript\ninterface CLIProvider {\n  // Bundle\n  bundle(options: BundleOptions): Promise\u003cCommandResult\u003e;\n\n  // Publish\n  publish(options: PublishOptions): Promise\u003cCommandResult\u003e;\n\n  // Upload\n  upload(options: UploadOptions): Promise\u003cCommandResult\u003e;\n\n  // Application management\n  getSelectedApp(\n    platform?: Platform,\n  ): Promise\u003c{ appId: string; platform: Platform }\u003e;\n  listApps(platform?: Platform): Promise\u003cCommandResult\u003e;\n  createApp(name: string, platform: Platform): Promise\u003cCommandResult\u003e;\n\n  // Version management\n  listVersions(appId: string): Promise\u003cCommandResult\u003e;\n  getVersion(appId: string, versionId: string): Promise\u003cCommandResult\u003e;\n  updateVersion(\n    appId: string,\n    versionId: string,\n    updates: Partial\u003cVersion\u003e,\n  ): Promise\u003cCommandResult\u003e;\n\n  // Package management\n  listPackages(appId: string, platform?: Platform): Promise\u003cCommandResult\u003e;\n  getPackage(appId: string, packageId: string): Promise\u003cCommandResult\u003e;\n\n  // Utility functions\n  getPlatform(platform?: Platform): Promise\u003cPlatform\u003e;\n  loadSession(): Promise\u003cSession\u003e;\n  saveToLocal(key: string, value: string): void;\n  question(prompt: string): Promise\u003cstring\u003e;\n\n  // Workflows\n  registerWorkflow(workflow: CustomWorkflow): void;\n  executeWorkflow(\n    workflowName: string,\n    context: CommandContext,\n  ): Promise\u003cCommandResult\u003e;\n}\n```\n\n### Custom Commands\n\n```typescript\n// Execute custom bundle command\nconst bundleResult = await moduleManager.executeCommand('custom-bundle', {\n  args: [],\n  options: {\n    platform: 'android',\n    validate: true,\n    optimize: true,\n  },\n});\n\n// Generate diff file\nconst diffResult = await moduleManager.executeCommand('diff', {\n  args: [],\n  options: {\n    origin: './build/v1.0.0.ppk',\n    next: './build/v1.1.0.ppk',\n    output: './build/diff.patch',\n  },\n});\n\n// Generate diff from APK files\nconst apkDiffResult = await moduleManager.executeCommand('diffFromApk', {\n  args: [],\n  options: {\n    origin: './build/app-v1.0.0.apk',\n    next: './build/app-v1.1.0.apk',\n    output: './build/apk-diff.patch',\n  },\n});\n```\n\n## 🔧 Configuration\n\n### Environment Variables\n\n```bash\n# Set API endpoint\nexport PUSHY_REGISTRY=https://your-api-endpoint.com\n\n# Set non-interactive mode\nexport NO_INTERACTIVE=true\n```\n\n### Configuration File\n\nCreate `update.json` file:\n\n```json\n{\n  \"ios\": {\n    \"appId\": \"your-ios-app-id\",\n    \"appKey\": \"your-ios-app-key\"\n  },\n  \"android\": {\n    \"appId\": \"your-android-app-id\",\n    \"appKey\": \"your-android-app-key\"\n  }\n}\n```\n\n## 🚨 Important Notes\n\n1. **Backward Compatibility**: The new modular CLI maintains compatibility with existing CLI\n2. **Type Safety**: All APIs have complete TypeScript type definitions\n3. **Error Handling**: All operations return standardized result formats\n4. **Resource Cleanup**: Modules support cleanup functions to release resources\n5. **Module Separation**: Functionality is logically separated into different modules for easy maintenance and extension\n\n## 🤝 Contributing\n\nWelcome to submit Issues and Pull Requests to improve this project!\n\n## 🚀 Provider API Usage Guide\n\nProvider provides a concise programming interface suitable for integrating React Native Update CLI functionality in applications.\n\n### 📋 Core API Methods\n\n#### Core Business Functions\n\n```typescript\n// Bundle application\nawait provider.bundle({\n  platform: 'ios',\n  dev: false,\n  sourcemap: true,\n});\n\n// Publish version\nawait provider.publish({\n  name: 'v1.0.0',\n  description: 'Bug fixes',\n  rollout: 100,\n});\n\n// Upload file\nawait provider.upload({\n  filePath: 'app.ipa',\n  platform: 'ios',\n});\n```\n\n#### Application Management\n\n```typescript\n// Create application\nawait provider.createApp('MyApp', 'ios');\n\n// List applications\nawait provider.listApps('ios');\n\n// Get current application\nconst { appId, platform } = await provider.getSelectedApp('ios');\n```\n\n#### Version Management\n\n```typescript\n// List versions\nawait provider.listVersions('app123');\n\n// Update version\nawait provider.updateVersion('app123', 'version456', {\n  name: 'v1.1.0',\n  description: 'New features',\n});\n```\n\n#### Utility Functions\n\n```typescript\n// Get platform\nconst platform = await provider.getPlatform('ios');\n\n// Load session\nconst session = await provider.loadSession();\n```\n\n### 🎯 Use Cases\n\n#### 1. Automated Build Scripts\n\n```typescript\nimport { moduleManager } from 'react-native-update-cli';\n\nasync function buildAndPublish() {\n  const provider = moduleManager.getProvider();\n\n  // 1. Bundle\n  const bundleResult = await provider.bundle({\n    platform: 'ios',\n    dev: false,\n    sourcemap: true,\n  });\n\n  if (!bundleResult.success) {\n    throw new Error(`Bundle failed: ${bundleResult.error}`);\n  }\n\n  // 2. Publish\n  const publishResult = await provider.publish({\n    name: 'v1.2.3',\n    description: 'Bug fixes and performance improvements',\n    rollout: 100,\n  });\n\n  if (!publishResult.success) {\n    throw new Error(`Publish failed: ${publishResult.error}`);\n  }\n\n  console.log('Build and publish completed!');\n}\n```\n\n#### 2. CI/CD Integration\n\n```typescript\nasync function ciBuild() {\n  const provider = moduleManager.getProvider();\n\n  const result = await provider.bundle({\n    platform: process.env.PLATFORM as 'ios' | 'android',\n    dev: process.env.NODE_ENV !== 'production',\n    sourcemap: process.env.NODE_ENV === 'production',\n  });\n\n  return result;\n}\n```\n\n#### 3. Application Management Service\n\n```typescript\nclass AppManagementService {\n  private provider = moduleManager.getProvider();\n\n  async setupNewApp(name: string, platform: Platform) {\n    // Create application\n    const createResult = await this.provider.createApp(name, platform);\n\n    if (createResult.success) {\n      // Get application information\n      const { appId } = await this.provider.getSelectedApp(platform);\n\n      // List versions\n      await this.provider.listVersions(appId);\n\n      return { appId, success: true };\n    }\n\n    return { success: false, error: createResult.error };\n  }\n}\n```\n\n### ⚠️ Important Notes\n\n1. **Error Handling**: All Provider methods return `CommandResult`, need to check the `success` field\n2. **Type Safety**: Provider provides complete TypeScript type support\n3. **Session Management**: Ensure login before use, can check via `loadSession()`\n4. **Platform Support**: Supports `'ios' | 'android' | 'harmony'` three platforms\n\n### 🔧 Advanced Features\n\n#### Custom Workflows\n\n```typescript\n// Register custom workflow\nprovider.registerWorkflow({\n  name: 'quick-release',\n  description: 'Quick release process',\n  steps: [\n    {\n      name: 'bundle',\n      execute: async () =\u003e {\n        return await provider.bundle({ platform: 'ios', dev: false });\n      },\n    },\n    {\n      name: 'publish',\n      execute: async (context, bundleResult) =\u003e {\n        if (!bundleResult.success) {\n          throw new Error('Bundle failed, cannot publish');\n        }\n        return await provider.publish({ name: 'auto-release', rollout: 50 });\n      },\n    },\n  ],\n});\n\n// Execute workflow\nawait provider.executeWorkflow('quick-release', { args: [], options: {} });\n```\n\n### 📚 Complete Example\n\n```typescript\nimport { moduleManager } from 'react-native-update-cli';\n\nclass ReactNativeUpdateService {\n  private provider = moduleManager.getProvider();\n\n  async initialize() {\n    // Load session\n    await this.provider.loadSession();\n  }\n\n  async buildAndDeploy(platform: Platform, version: string) {\n    try {\n      // 1. Bundle\n      const bundleResult = await this.provider.bundle({\n        platform,\n        dev: false,\n        sourcemap: true,\n      });\n\n      if (!bundleResult.success) {\n        throw new Error(`Bundle failed: ${bundleResult.error}`);\n      }\n\n      // 2. Publish\n      const publishResult = await this.provider.publish({\n        name: version,\n        description: `Release ${version}`,\n        rollout: 100,\n      });\n\n      if (!publishResult.success) {\n        throw new Error(`Publish failed: ${publishResult.error}`);\n      }\n\n      return { success: true, data: publishResult.data };\n    } catch (error) {\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : 'Unknown error',\n      };\n    }\n  }\n\n  async getAppInfo(platform: Platform) {\n    const { appId } = await this.provider.getSelectedApp(platform);\n    const versions = await this.provider.listVersions(appId);\n\n    return { appId, versions };\n  }\n}\n\n// Usage example\nconst service = new ReactNativeUpdateService();\nawait service.initialize();\nawait service.buildAndDeploy('ios', 'v1.0.0');\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactnativecn%2Freact-native-update-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactnativecn%2Freact-native-update-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactnativecn%2Freact-native-update-cli/lists"}