Skip to content

reactnativecn/react-native-update-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

React Native Update CLI

δΈ­ζ–‡ζ–‡ζ‘£ | Chinese Documentation

A unified React Native Update CLI that supports both traditional commands and modular architecture with custom publishing workflows.

πŸš€ Features

  • Unified CLI: Single pushy command for all functionality
  • Backward Compatibility: All existing commands work as before
  • Modular Architecture: Split CLI functionality into independent modules
  • Custom Workflows: Support for creating custom publishing workflows
  • Extensibility: Users can import and register custom modules
  • Type Safety: Complete TypeScript type support

πŸ“¦ Installation

npm install react-native-update-cli

🎯 Quick Start

Basic Usage

# Use unified CLI
npx pushy help

# List all available commands and workflows
npx pushy list

# Execute built-in workflow
npx pushy workflow setup-app

# Execute custom workflow
npx pushy workflow custom-publish

Programmatic Usage

import { moduleManager, CLIProviderImpl } from 'react-native-update-cli';

// Get CLI provider
const provider = moduleManager.getProvider();

// Execute bundling
const bundleResult = await provider.bundle({
  platform: 'ios',
  dev: false,
  sourcemap: true
});

// Publish version
const publishResult = await provider.publish({
  name: 'v1.2.3',
  description: 'Bug fixes and improvements',
  rollout: 100
});

πŸ”§ Creating Custom Modules

1. Define Module

import type { CLIModule, CommandDefinition, CustomWorkflow } from 'react-native-update-cli';

export const myCustomModule: CLIModule = {
  name: 'my-custom',
  version: '1.0.0',
  
  commands: [
    {
      name: 'custom-command',
      description: 'My custom command',
      handler: async (context) => {
        console.log('Executing custom command...');
        return {
          success: true,
          data: { message: 'Custom command executed' }
        };
      },
      options: {
        param: { hasValue: true, description: 'Custom parameter' }
      }
    }
  ],
  
  workflows: [
    {
      name: 'my-workflow',
      description: 'My custom workflow',
      steps: [
        {
          name: 'step1',
          description: 'First step',
          execute: async (context, previousResult) => {
            console.log('Executing step 1...');
            return { step1Completed: true };
          }
        },
        {
          name: 'step2',
          description: 'Second step',
          execute: async (context, previousResult) => {
            console.log('Executing step 2...');
            return { ...previousResult, step2Completed: true };
          }
        }
      ]
    }
  ],
  
  init: (provider) => {
    console.log('Custom module initialized');
  },
  
  cleanup: () => {
    console.log('Custom module cleanup');
  }
};

2. Register Module

import { moduleManager } from 'react-native-update-cli';
import { myCustomModule } from './my-custom-module';

// Register custom module
moduleManager.registerModule(myCustomModule);

// Execute custom command
const result = await moduleManager.executeCommand('custom-command', {
  args: [],
  options: { param: 'value' }
});

// Execute custom workflow
const workflowResult = await moduleManager.executeWorkflow('my-workflow', {
  args: [],
  options: {}
});

πŸ”„ Workflow System

Workflow Steps

Each workflow step contains:

  • name: Step name
  • description: Step description
  • execute: Execution function
  • condition: Optional condition function

Conditional Execution

{
  name: 'conditional-step',
  description: 'Only execute in production',
  execute: async (context, previousResult) => {
    // Execution logic
  },
  condition: (context) => {
    return context.options.environment === 'production';
  }
}

Workflow Validation

{
  name: 'validated-workflow',
  description: 'Workflow with validation',
  steps: [...],
  validate: (context) => {
    if (!context.options.requiredParam) {
      console.error('Required parameter missing');
      return false;
    }
    return true;
  }
}

πŸ“‹ Built-in Modules

Bundle Module (bundle)

  • bundle: Bundle JavaScript code and optionally publish
  • diff: Generate differences between two PPK files
  • hdiff: Generate hdiff between two PPK files
  • diffFromApk: Generate differences from APK files
  • hdiffFromApk: Generate hdiff from APK files
  • hdiffFromApp: Generate hdiff from APP files
  • diffFromIpa: Generate differences from IPA files
  • hdiffFromIpa: Generate hdiff from IPA files

Version Module (version)

  • publish: Publish new version
  • versions: List all versions
  • update: Update version information
  • updateVersionInfo: Update version metadata

App Module (app)

  • createApp: Create new application
  • apps: List all applications
  • selectApp: Select application
  • deleteApp: Delete application

Package Module (package)

  • uploadIpa: Upload IPA files
  • uploadApk: Upload APK files
  • uploadApp: Upload APP files
  • parseApp: Parse APP file information
  • parseIpa: Parse IPA file information
  • parseApk: Parse APK file information
  • packages: List packages

User Module (user)

  • login: Login
  • logout: Logout
  • me: Show user information

πŸ› οΈ CLI Provider API

Core Functionality

interface CLIProvider {
  // Bundle
  bundle(options: BundleOptions): Promise<CommandResult>;
  
  // Publish
  publish(options: PublishOptions): Promise<CommandResult>;
  
  // Upload
  upload(options: UploadOptions): Promise<CommandResult>;
  
  // Application management
  getSelectedApp(platform?: Platform): Promise<{ appId: string; platform: Platform }>;
  listApps(platform?: Platform): Promise<CommandResult>;
  createApp(name: string, platform: Platform): Promise<CommandResult>;
  
  // Version management
  listVersions(appId: string): Promise<CommandResult>;
  getVersion(appId: string, versionId: string): Promise<CommandResult>;
  updateVersion(appId: string, versionId: string, updates: Partial<Version>): Promise<CommandResult>;
  
  // Package management
  listPackages(appId: string, platform?: Platform): Promise<CommandResult>;
  getPackage(appId: string, packageId: string): Promise<CommandResult>;
  
  // Utility functions
  getPlatform(platform?: Platform): Promise<Platform>;
  loadSession(): Promise<Session>;
  saveToLocal(key: string, value: string): void;
  question(prompt: string): Promise<string>;
  
  // Workflows
  registerWorkflow(workflow: CustomWorkflow): void;
  executeWorkflow(workflowName: string, context: CommandContext): Promise<CommandResult>;
}

Custom Commands

// Execute custom bundle command
const bundleResult = await moduleManager.executeCommand('custom-bundle', {
  args: [],
  options: {
    platform: 'android',
    validate: true,
    optimize: true
  }
});

// Generate diff file
const diffResult = await moduleManager.executeCommand('diff', {
  args: [],
  options: {
    origin: './build/v1.0.0.ppk',
    next: './build/v1.1.0.ppk',
    output: './build/diff.patch'
  }
});

// Generate diff from APK files
const apkDiffResult = await moduleManager.executeCommand('diffFromApk', {
  args: [],
  options: {
    origin: './build/app-v1.0.0.apk',
    next: './build/app-v1.1.0.apk',
    output: './build/apk-diff.patch'
  }
});

πŸ”§ Configuration

Environment Variables

# Set API endpoint
export PUSHY_REGISTRY=https://your-api-endpoint.com

# Set non-interactive mode
export NO_INTERACTIVE=true

Configuration File

Create update.json file:

{
  "ios": {
    "appId": "your-ios-app-id",
    "appKey": "your-ios-app-key"
  },
  "android": {
    "appId": "your-android-app-id",
    "appKey": "your-android-app-key"
  }
}

🚨 Important Notes

  1. Backward Compatibility: The new modular CLI maintains compatibility with existing CLI
  2. Type Safety: All APIs have complete TypeScript type definitions
  3. Error Handling: All operations return standardized result formats
  4. Resource Cleanup: Modules support cleanup functions to release resources
  5. Module Separation: Functionality is logically separated into different modules for easy maintenance and extension

🀝 Contributing

Welcome to submit Issues and Pull Requests to improve this project!

πŸš€ Provider API Usage Guide

Provider provides a concise programming interface suitable for integrating React Native Update CLI functionality in applications.

πŸ“‹ Core API Methods

Core Business Functions

// Bundle application
await provider.bundle({
  platform: 'ios',
  dev: false,
  sourcemap: true
});

// Publish version
await provider.publish({
  name: 'v1.0.0',
  description: 'Bug fixes',
  rollout: 100
});

// Upload file
await provider.upload({
  filePath: 'app.ipa',
  platform: 'ios'
});

Application Management

// Create application
await provider.createApp('MyApp', 'ios');

// List applications
await provider.listApps('ios');

// Get current application
const { appId, platform } = await provider.getSelectedApp('ios');

Version Management

// List versions
await provider.listVersions('app123');

// Update version
await provider.updateVersion('app123', 'version456', {
  name: 'v1.1.0',
  description: 'New features'
});

Utility Functions

// Get platform
const platform = await provider.getPlatform('ios');

// Load session
const session = await provider.loadSession();

🎯 Use Cases

1. Automated Build Scripts

import { moduleManager } from 'react-native-update-cli';

async function buildAndPublish() {
  const provider = moduleManager.getProvider();
  
  // 1. Bundle
  const bundleResult = await provider.bundle({
    platform: 'ios',
    dev: false,
    sourcemap: true
  });
  
  if (!bundleResult.success) {
    throw new Error(`Bundle failed: ${bundleResult.error}`);
  }
  
  // 2. Publish
  const publishResult = await provider.publish({
    name: 'v1.2.3',
    description: 'Bug fixes and performance improvements',
    rollout: 100
  });
  
  if (!publishResult.success) {
    throw new Error(`Publish failed: ${publishResult.error}`);
  }
  
  console.log('Build and publish completed!');
}

2. CI/CD Integration

async function ciBuild() {
  const provider = moduleManager.getProvider();
  
  const result = await provider.bundle({
    platform: process.env.PLATFORM as 'ios' | 'android',
    dev: process.env.NODE_ENV !== 'production',
    sourcemap: process.env.NODE_ENV === 'production'
  });
  
  return result;
}

3. Application Management Service

class AppManagementService {
  private provider = moduleManager.getProvider();
  
  async setupNewApp(name: string, platform: Platform) {
    // Create application
    const createResult = await this.provider.createApp(name, platform);
    
    if (createResult.success) {
      // Get application information
      const { appId } = await this.provider.getSelectedApp(platform);
      
      // List versions
      await this.provider.listVersions(appId);
      
      return { appId, success: true };
    }
    
    return { success: false, error: createResult.error };
  }
}

⚠️ Important Notes

  1. Error Handling: All Provider methods return CommandResult, need to check the success field
  2. Type Safety: Provider provides complete TypeScript type support
  3. Session Management: Ensure login before use, can check via loadSession()
  4. Platform Support: Supports 'ios' | 'android' | 'harmony' three platforms

πŸ”§ Advanced Features

Custom Workflows

// Register custom workflow
provider.registerWorkflow({
  name: 'quick-release',
  description: 'Quick release process',
  steps: [
    {
      name: 'bundle',
      execute: async () => {
        return await provider.bundle({ platform: 'ios', dev: false });
      }
    },
    {
      name: 'publish',
      execute: async (context, bundleResult) => {
        if (!bundleResult.success) {
          throw new Error('Bundle failed, cannot publish');
        }
        return await provider.publish({ name: 'auto-release', rollout: 50 });
      }
    }
  ]
});

// Execute workflow
await provider.executeWorkflow('quick-release', { args: [], options: {} });

πŸ“š Complete Example

import { moduleManager } from 'react-native-update-cli';

class ReactNativeUpdateService {
  private provider = moduleManager.getProvider();
  
  async initialize() {
    // Load session
    await this.provider.loadSession();
  }
  
  async buildAndDeploy(platform: Platform, version: string) {
    try {
      // 1. Bundle
      const bundleResult = await this.provider.bundle({
        platform,
        dev: false,
        sourcemap: true
      });
      
      if (!bundleResult.success) {
        throw new Error(`Bundle failed: ${bundleResult.error}`);
      }
      
      // 2. Publish
      const publishResult = await this.provider.publish({
        name: version,
        description: `Release ${version}`,
        rollout: 100
      });
      
      if (!publishResult.success) {
        throw new Error(`Publish failed: ${publishResult.error}`);
      }
      
      return { success: true, data: publishResult.data };
      
    } catch (error) {
      return { 
        success: false, 
        error: error instanceof Error ? error.message : 'Unknown error' 
      };
    }
  }
  
  async getAppInfo(platform: Platform) {
    const { appId } = await this.provider.getSelectedApp(platform);
    const versions = await this.provider.listVersions(appId);
    
    return { appId, versions };
  }
}

// Usage example
const service = new ReactNativeUpdateService();
await service.initialize();
await service.buildAndDeploy('ios', 'v1.0.0');

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •