diff --git a/.github/workflows/development_codepush-devml.yml b/.github/workflows/development_codepush-devml.yml index 35ebc7de2..56102f89b 100644 --- a/.github/workflows/development_codepush-devml.yml +++ b/.github/workflows/development_codepush-devml.yml @@ -18,10 +18,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Node.js version + - name: Setup Node.js using .nvmrc uses: actions/setup-node@v3 with: - node-version: "18.x" + node-version-file: "custom/.nvmrc" - name: npm install, build, and test working-directory: ./api diff --git a/.github/workflows/production_codepush-prodml.yml b/.github/workflows/production_codepush-prodml.yml index 0069a48d2..20687a4a9 100644 --- a/.github/workflows/production_codepush-prodml.yml +++ b/.github/workflows/production_codepush-prodml.yml @@ -18,10 +18,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Node.js version + - name: Setup Node.js using .nvmrc uses: actions/setup-node@v3 with: - node-version: "18.x" + node-version-file: "custom/.nvmrc" - name: npm install, build, and test working-directory: ./api diff --git a/custom/.nvmrc b/custom/.nvmrc new file mode 100644 index 000000000..cae4e8455 --- /dev/null +++ b/custom/.nvmrc @@ -0,0 +1 @@ +22.13.1 \ No newline at end of file diff --git a/api/FRIENDLY_DOCS.md b/custom/guildes/API_FRIENDLY_DOCS.md similarity index 83% rename from api/FRIENDLY_DOCS.md rename to custom/guildes/API_FRIENDLY_DOCS.md index beae4112e..bfd76e9d5 100644 --- a/api/FRIENDLY_DOCS.md +++ b/custom/guildes/API_FRIENDLY_DOCS.md @@ -103,7 +103,9 @@ OAuth Apps are **essential** for your CodePush server deployment because: Without at least one OAuth provider configured, your CodePush server would have no way to authenticate users, making it impossible to use the system for deploying updates. -### Setting Up a GitHub OAuth App +### Setting Up a GitHub OAuth App (Recommended) + +GitHub OAuth is the recommended authentication method for CodePush Server. To set up: 1. Go to https://github.com/settings/developers 2. Click "New OAuth App" @@ -115,7 +117,9 @@ Without at least one OAuth provider configured, your CodePush server would have 5. Generate a new Client Secret 6. Save both values for your CodePush server configuration -### Setting Up a Microsoft OAuth App +### Setting Up a Microsoft OAuth App (Optional) + +Microsoft OAuth is optional and only needed if you want to support Microsoft account authentication: 1. Register an app at https://portal.azure.com → Azure Active Directory → App registrations → New registration 2. Name your application (e.g., "CodePush Server") @@ -137,15 +141,15 @@ Without at least one OAuth provider configured, your CodePush server would have Add to your `.env` file: ``` -# GitHub OAuth +# GitHub OAuth (Required) GITHUB_CLIENT_ID=your_github_client_id GITHUB_CLIENT_SECRET=your_github_client_secret -# Microsoft OAuth -MICROSOFT_CLIENT_ID=your_microsoft_client_id -MICROSOFT_CLIENT_SECRET=your_microsoft_client_secret +# Microsoft OAuth (Optional) +# MICROSOFT_CLIENT_ID=your_microsoft_client_id +# MICROSOFT_CLIENT_SECRET=your_microsoft_client_secret # Only needed for single tenant work account setup -MICROSOFT_TENANT_ID=your_tenant_id +# MICROSOFT_TENANT_ID=your_tenant_id ``` #### For Azure Deployment: @@ -191,18 +195,16 @@ az deployment group create \ --parameters project_suffix= \ az_location=eastus \ github_client_id= \ - github_client_secret= \ - microsoft_client_id= \ - microsoft_client_secret= + github_client_secret= ``` Notes: - Choose a unique suffix (letters only, max 15 chars) -- OAuth parameters are optional but recommended for authentication -- **Important**: At least one OAuth provider (GitHub or Microsoft) must be configured for the system to work properly -- If using Microsoft single tenant work accounts, you'll need to add the `MICROSOFT_TENANT_ID` parameter after deployment +- GitHub OAuth parameters are required for authentication +- Microsoft OAuth parameters (`microsoft_client_id`, `microsoft_client_secret`) are now optional and can be omitted if you're only using GitHub authentication - Your server URL will be: https://codepush-{suffix}.azurewebsites.net +- First-time users will need to register with the CLI using `code-push-standalone register https://codepush-{suffix}.azurewebsites.net` before accessing the web interface ### Step 5: Manual Deployment to Azure Web App @@ -268,9 +270,18 @@ If you want to monitor release activity via the CLI: ### Common Issues: 1. **Deployment Fails**: Check that your project suffix meets naming requirements (letters only, max 15 chars) -2. **Authentication Issues**: Verify OAuth callback URLs match your server URL exactly -3. **Storage Errors**: Ensure Azurite is running for local development, or check storage account access keys -4. **Node.js Version**: Make sure you're using Node.js 18 LTS as specified + +2. **GitHub Authentication Issues**: + + - **Redirect URI Mismatch**: If you see an error about redirect_uri not being associated with the application, ensure your GitHub OAuth app's callback URL exactly matches what your server is using (including protocol, domain, and path) + - **Account Not Found Error**: If you see "Account not found. Have you registered with the CLI?" after GitHub authentication, you need to first register using the CLI with `code-push-standalone register ` before accessing the web interface + - **Authentication Failed**: Double-check your GitHub OAuth credentials are correctly set in environment variables + +3. **Microsoft Authentication Issues**: Verify that the redirect URIs and account types in your Microsoft application registration match your server configuration + +4. **Storage Errors**: Ensure Azurite is running for local development, or check storage account access keys + +5. **Node.js Version**: Make sure you're using Node.js 18 LTS as specified For more detailed troubleshooting, check the logs in your Azure Web App or local development environment. @@ -347,9 +358,7 @@ az deployment group create \ --parameters project_suffix="" \ az_location="eastus" \ github_client_id="" \ - github_client_secret="" \ - microsoft_client_id="" \ - microsoft_client_secret="" + github_client_secret="" # 5. Build the application for deployment npm run build @@ -370,14 +379,17 @@ az webapp deployment source config-zip \ # Install the CodePush CLI npm install -g code-push-cli -# Login to your CodePush server -code-push login --serverUrl https://codepush-.azurewebsites.net +# First-time users must register (creates your account) +code-push-standalone register https://codepush-.azurewebsites.net + +# For subsequent logins +code-push-standalone login --serverUrl https://codepush-.azurewebsites.net # Register your app -code-push app add +code-push-standalone app add # Deploy an update -code-push release-react --development +code-push-standalone release-react --development ``` -Remember to replace placeholder values (``, ``, etc.) with your actual values. Also, make sure you have set up at least one OAuth provider (GitHub or Microsoft) before deployment. +Remember to replace placeholder values (``, ``, etc.) with your actual values. Also, make sure you have set up GitHub OAuth authentication before deployment. diff --git a/custom/guildes/CLI_GUIDE_DOCS.md b/custom/guildes/CLI_GUIDE_DOCS.md new file mode 100644 index 000000000..a2699ef7d --- /dev/null +++ b/custom/guildes/CLI_GUIDE_DOCS.md @@ -0,0 +1,237 @@ +# CodePush CLI Guide + +This guide explains how to use the local CodePush CLI with your self-hosted CodePush servers. + +## Installation + +To install and use the local CodePush CLI: + +```bash +# Clone the CodePush Service repository +git clone + +# Navigate to the project directory +cd ml-code-push-server + +# Install dependencies +npm install + +# Build the CLI +npm run build + +# Install CLI globally +npm install -g +``` + +After installation, the CLI will be available as `code-push-standalone`. + +## Configuration + +Before using the CLI, you need to log in to your CodePush server: + +```bash +# For development environment +code-push-standalone login https://codepush-devml.azurewebsites.net + +# For production environment +code-push-standalone login https://codepush-prodml.azurewebsites.net +``` + +This will open a browser for authentication. + +## Common Commands + +### Account Management + +```bash +# Register new account (if needed) +code-push-standalone register https://codepush-devml.azurewebsites.net + +# Check current logged in account +code-push-standalone whoami + +# Logout +code-push-standalone logout +``` + +### App Management + +```bash +# List all apps +code-push-standalone app ls + +# Add a new app (create separate apps for iOS and Android) +code-push-standalone app add MyApp-iOS +code-push-standalone app add MyApp-Android + +# Rename an app +code-push-standalone app rename CurrentName NewName + +# Remove an app +code-push-standalone app rm AppName +``` + +### Deployment Management + +Every app automatically gets "Staging" and "Production" deployments, but you can add more: + +```bash +# List deployments for an app +code-push-standalone deployment ls MyApp-iOS + +# Add a deployment +code-push-standalone deployment add MyApp-iOS QA + +# Rename a deployment +code-push-standalone deployment rename MyApp-iOS QA Beta + +# Remove a deployment +code-push-standalone deployment rm MyApp-iOS QA +``` + +### Releasing Updates + +#### Standard Release + +```bash +# Release an update +code-push-standalone release MyApp-iOS ./updates 1.0.0 +``` + +Parameters: + +- **App name**: Name of your app +- **Update contents**: Path to the update files or folder +- **Target binary version**: App store version this is for (can be a semver range) + +Optional flags: + +- `--deploymentName` or `-d`: Target deployment (defaults to Staging) +- `--description` or `-des`: Release notes +- `--mandatory` or `-m`: Force users to update +- `--rollout` or `-r`: Percentage of users to deploy to (e.g., "25%") +- `--disabled`: Prevent the update from being downloaded + +#### React Native Release + +```bash +# Release a React Native update +code-push-standalone release-react MyApp-iOS ios +``` + +Parameters: + +- **App name**: Name of your app +- **Platform**: "ios" or "android" + +Common options: + +- `--deploymentName` or `-d`: Target deployment (defaults to Staging) +- `--description` or `-des`: Release notes +- `--mandatory` or `-m`: Force users to update +- `--targetBinaryVersion` or `-t`: App store version this is for +- `--development` or `--dev`: Generate an unminified bundle with warnings + +Full command example: + +```bash +# Comprehensive React Native release example with common options +code-push-standalone release-react MyAwesomeApp-iOS ios \ + --deploymentName Production \ + --description "Fixed login issues and improved performance" \ + --mandatory true \ + --targetBinaryVersion "~1.2.3" \ + --development false \ + --sourcemapOutput ./sourcemaps \ + --rollout 25 \ + --entryFile index.ios.js \ + --plistFile ./ios/MyAwesomeApp/Info.plist \ + --gradleFile ./android/app/build.gradle +``` + +This example: + +- Releases to the "Production" deployment +- Includes descriptive release notes +- Makes the update mandatory for all users +- Targets app binary version 1.2.x (compatibility with semver range) +- Disables development mode for a minified production bundle +- Generates sourcemaps for debugging +- Rolls out to 25% of users initially +- Specifies custom entry file and build configuration files + +### Managing Releases + +```bash +# View release history +code-push-standalone deployment history MyApp-iOS Staging + +# Promote a release from Staging to Production +code-push-standalone promote MyApp-iOS Staging Production + +# Rollback a deployment to a previous release +code-push-standalone rollback MyApp-iOS Production +``` + +## Debugging + +```bash +# View debug logs for a running app +code-push-standalone debug android +code-push-standalone debug ios +``` + +## Working with Collaborators + +```bash +# List collaborators +code-push-standalone collaborator ls MyApp-iOS + +# Add a collaborator +code-push-standalone collaborator add MyApp-iOS user@example.com + +# Remove a collaborator +code-push-standalone collaborator rm MyApp-iOS user@example.com +``` + +## Additional Security with Code Signing + +If using code signing: + +```bash +# Release with a private key for signing +code-push-standalone release-react MyApp-iOS ios --privateKeyPath private.pem +``` + +## Example Workflow + +A typical workflow with CodePush might look like: + +1. Create your apps for each platform: + + ```bash + code-push-standalone app add MyAwesomeApp-iOS + code-push-standalone app add MyAwesomeApp-Android + ``` + +2. Deploy an update to staging: + + ```bash + code-push-standalone release-react MyAwesomeApp-iOS ios --deploymentName Staging + ``` + +3. Test the update in the staging environment + +4. Promote to production when ready: + ```bash + code-push-standalone promote MyAwesomeApp-iOS Staging Production + ``` + +## Troubleshooting + +- **Server errors**: Make sure your server URL is correct and server is running +- **Authentication issues**: Check your authentication configuration +- **Deployment errors**: Verify app name and deployment name +- **Release issues**: Check target binary version compatibility + +For more information, refer to the [CLI documentation](../cli/README.md). diff --git a/custom/guildes/GITHUB_OAUTH_APP_DOCS.md b/custom/guildes/GITHUB_OAUTH_APP_DOCS.md new file mode 100644 index 000000000..309491969 --- /dev/null +++ b/custom/guildes/GITHUB_OAUTH_APP_DOCS.md @@ -0,0 +1,96 @@ +# GitHub OAuth Setup for CodePush Server + +> **NOTE:** This document replaces the previous Microsoft Entra ID setup instructions, as the project has been switched to use GitHub OAuth for authentication. + +This document provides guidance on setting up and verifying GitHub OAuth applications for authentication with CodePush Server. + +## GitHub OAuth Configuration + +### 1. Create a GitHub OAuth App + +1. Go to https://github.com/settings/developers +2. Click on "New OAuth App" +3. Fill in the required information: + - **Application name**: "CodePush Server" (or your preferred name) + - **Homepage URL**: Your CodePush server URL + - For Azure: `https://codepush-.azurewebsites.net` + - For local development: `http://localhost:3000` + - **Authorization callback URL**: + - For Azure: `https://codepush-.azurewebsites.net/auth/callback/github` + - For local development: `http://localhost:3000/auth/callback/github` +4. Click "Register application" +5. After registration, you'll see your **Client ID** +6. Click "Generate a new client secret" to create a **Client Secret** +7. Save both the Client ID and Client Secret securely + +### 2. Configure Environment Variables + +#### For Azure Deployments: + +1. Go to Azure Portal → App Services → codepush-{your-suffix} +2. Navigate to Configuration → Application settings +3. Add or verify these settings: + - `GITHUB_CLIENT_ID`: Your GitHub OAuth App's Client ID + - `GITHUB_CLIENT_SECRET`: Your GitHub OAuth App's Client Secret + - Remove Microsoft OAuth settings if not needed: + - `MICROSOFT_CLIENT_ID` + - `MICROSOFT_CLIENT_SECRET` + - `MICROSOFT_TENANT_ID` + +#### For Local Development: + +Create or update your `.env` file in the `api` directory: + +``` +# GitHub OAuth +GITHUB_CLIENT_ID=your_github_client_id +GITHUB_CLIENT_SECRET=your_github_client_secret +SERVER_URL=http://localhost:3000 +CORS_ORIGIN=http://localhost:3000 + +# Remove or comment out Microsoft OAuth settings +# MICROSOFT_CLIENT_ID= +# MICROSOFT_CLIENT_SECRET= +# MICROSOFT_TENANT_ID= +``` + +### 3. First-Time User Registration + +To use your CodePush server with GitHub authentication, you must follow this sequence: + +1. First register your account using the CLI: + + ```bash + code-push-standalone register https://codepush-.azurewebsites.net + ``` + + This will open a browser window where you'll authenticate with GitHub and create your account in the CodePush system. + +2. After registration, you'll be automatically logged in to the CLI. If you need to log in again later: + + ```bash + code-push-standalone login https://codepush-.azurewebsites.net + ``` + +3. Once registered and logged in via the CLI, you can access the web interface at your CodePush server URL. + +### 4. Troubleshooting + +#### Common Issues: + +1. **Redirect URI Mismatch Error**: If you see "The redirect_uri is not associated with this application", ensure your callback URL in GitHub exactly matches what your CodePush server is using. + +2. **Account Not Found Error**: If you see "Account not found. Have you registered with the CLI?" after GitHub authentication, it means you need to register first using the CLI command mentioned in section 3. + +3. **Authentication Failed**: Verify your GitHub OAuth credentials are correctly set in your environment variables. + +4. **Login Session Issues**: If CLI login fails, try checking your session status with: + ```bash + code-push-standalone whoami + ``` + If needed, log out and try again: + ```bash + code-push-standalone logout + ``` + +For more detailed instructions, refer to the main documentation in FRIENDLY_DOCS.md. diff --git a/custom/guildes/SYSTEM_FLOW.md b/custom/guildes/SYSTEM_FLOW.md new file mode 100644 index 000000000..e52864a25 --- /dev/null +++ b/custom/guildes/SYSTEM_FLOW.md @@ -0,0 +1,453 @@ +# Complete CodePush System Architecture & Workflow + +## System Components Overview + +CodePush consists of three main components: + +1. **CodePush Server**: Backend service (Node.js) that manages app updates +2. **CodePush CLI**: Command-line tool for interacting with the server +3. **CodePush SDK**: Client library embedded in React Native apps + +Let's explore how these components work together in detail: + +## 1. Infrastructure and Storage + +### Azure Storage + +CodePush uses Azure's cloud storage services to manage both the actual update files and their metadata: + +- **Blob Storage**: + + - Stores the actual update packages (JavaScript bundles, images, and assets) + - Handles large binary data efficiently + - Each update package has a unique blob ID + - Also stores package history as JSON (limited to 50 most recent releases per deployment) + +- **Table Storage**: + + - NoSQL database that stores structured metadata using a hierarchical key system + - Uses partition/row keys for efficient lookups + - Key tables include: + - **Accounts table**: User information (id, email, name, authentication details) + - **Apps table**: App records (id, name, owner, collaborators) + - **Deployments table**: Environment configurations (id, name, key, latest package reference) + - **Packages table**: Release metadata (version, hash, description, rollout settings) + - **Access Keys table**: CLI authentication tokens + +- **Storage Relationships**: + - Each Account can have multiple Apps + - Each App can have multiple Deployments + - Each Deployment can have multiple Packages (as history) + - Complex relationships encoded in hierarchical keys (e.g., "appId_123_deploymentId\*\_456") + - Shortcut keys for quick access (by email, deployment key, etc.) + +### Redis (Optional) + +- Used only for metrics functionality +- Tracks download statistics and active deployments +- Enables analytics on update adoption rates + +## 2. Authentication Flow + +### OAuth App Registration (One-time Setup) + +1. Developer creates OAuth app in GitHub/Microsoft +2. Developer configures CodePush server with OAuth credentials: + - `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`, or + - `MICROSOFT_CLIENT_ID` and `MICROSOFT_CLIENT_SECRET` + +### User Registration & Authentication + +1. New user runs: `code-push-standalone register https://your-server-url` +2. CLI makes API call to `/auth/login` endpoint +3. Server generates unique state token and authorization URL +4. Browser opens to OAuth provider (GitHub/Microsoft) +5. User authenticates with OAuth provider +6. Provider redirects to callback URL with authorization code +7. Server exchanges code for OAuth access token via provider's API +8. Server creates user record in Azure Table Storage +9. Server generates CodePush-specific JWT access token +10. Browser sends token back to CLI via local callback server +11. CLI stores token in local config file (~/.code-push.json) + +### Subsequent CLI Authentication + +1. User runs: `code-push-standalone login https://your-server-url` +2. Same OAuth flow occurs but user record already exists +3. All subsequent CLI commands include JWT token in API requests + +## 3. App & Deployment Management + +### Creating Apps + +1. User runs: `code-push-standalone app add MyApp-iOS ios` +2. CLI makes POST request to `/apps` endpoint with app name and platform +3. Server: + - Generates unique app identifier + - Creates app record in Azure Table Storage + - Creates default deployments (Staging/Production) + - Generates deployment keys for each environment + +### Managing Deployments + +1. User runs: `code-push-standalone deployment add MyApp-iOS QA` +2. CLI makes POST request to `/apps/MyApp-iOS/deployments` +3. Server: + - Creates new deployment in Azure Table Storage + - Generates unique deployment key + - Associates deployment with parent app + +## 4. Release Management + +### Publishing an Update + +1. Developer makes code changes to React Native app +2. Developer runs: `code-push-standalone release-react MyApp-iOS ios` +3. CLI: + + - Bundles app's JavaScript and assets (using Metro bundler) + - Creates zip package with manifest.json + - Makes POST request to `/apps/MyApp-iOS/deployments/Staging/releases` + - Uploads package data in multipart/form-data request + +4. Server: + - Validates request and user permissions + - Generates unique release identifier + - Uploads package to Azure Blob Storage + - Creates release record in Table Storage with: + - Target binary version + - Release notes + - Package hash + - Upload time + - Mandatory flag + - Rollout percentage + - Updates deployment's latest release reference + +### Promoting Updates + +1. Developer runs: `code-push-standalone promote MyApp-iOS Staging Production` +2. CLI makes POST request to `/apps/MyApp-iOS/deployments/Staging/promote` with target +3. Server: + - Validates request + - Copies release metadata from Staging to Production + - Updates Production deployment's latest release reference + - Re-uses same package blob (no duplication) + +### Rollback + +1. Developer runs: `code-push-standalone rollback MyApp-iOS Production` +2. CLI makes POST request to `/apps/MyApp-iOS/deployments/Production/rollback` +3. Server: + - Finds previous release + - Updates deployment to point to that release + +## 5. Client Update Process + +### SDK Integration + +1. Developer adds react-native-code-push to app +2. Configures deployment keys in: + - iOS: Info.plist + - Android: strings.xml +3. Configures custom server URL: + - iOS: `CodePushServerURL` in Info.plist + - Android: `CodePushServerUrl` in strings.xml +4. Wraps app's root component with CodePush HOC + +### Update Check Flow + +1. React Native app launches or triggers check +2. CodePush SDK: + + - Retrieves deployment key and server URL from app config + - Makes GET request to `/deployments/{deploymentKey}/updates/check` with: + - App version + - Package hash (if any previous update) + - Locale information + +3. Server: + + - Finds deployment by key + - Checks if update is available based on: + - Target binary version compatibility + - Package hash comparison + - Rollout percentage + - Returns update metadata if available + +4. CodePush SDK: + - If update available, makes GET request to download package from blob storage + - Verifies package hash + - Unzips package to local storage + - Applies update based on configured install mode: + - `IMMEDIATE`: Applies immediately + - `ON_NEXT_RESTART`: Saves for next app launch + - `ON_NEXT_RESUME`: Applies when app resumes from background + +### Metrics Collection (if enabled) + +1. SDK reports download success/failure +2. Server stores metrics in Redis +3. Metrics data accessible via CLI: `code-push-standalone deployment histogram` + +## 6. Security Mechanisms + +1. **JWT Authentication**: All API calls require valid JWT token +2. **API Permission Checks**: Server validates user permissions for each operation +3. **Package Hashing**: Updates verified by SHA256 hash +4. **Optional Code Signing**: Updates can be cryptographically signed and verified + +## 7. Data Model and Entity Relationships + +### Account + +- **Purpose**: Represents a user of the CodePush system +- **Key Fields**: + - `id`: Unique identifier + - `email`: User's email (unique) + - `name`: User's name + - `createdTime`: When account was created + - Authentication IDs: `gitHubId`, `microsoftId`, or `azureAdId` +- **Relationships**: + - One Account can own many Apps + - One Account can have many AccessKeys + +### App + +- **Purpose**: Represents a mobile application registered with CodePush +- **Key Fields**: + - `id`: Unique identifier + - `name`: App name + - `createdTime`: When app was created + - `collaborators`: Map of email addresses to collaborator properties +- **Relationships**: + - Belongs to an Account (ownership) + - One App can have many Deployments + - One App can have many Collaborators + +### Deployment + +- **Purpose**: Represents an environment (Staging, Production, etc.) +- **Key Fields**: + - `id`: Unique identifier + - `name`: Deployment name (e.g., "Staging", "Production") + - `key`: Unique deployment key used in app configuration + - `createdTime`: When deployment was created + - `package`: Optional reference to the latest release package +- **Relationships**: + - Belongs to an App (parent-child) + - One Deployment can have many Packages (release history) + +### Understanding CodePush Deployments vs. Server Environments + +It's important to understand the distinction between CodePush "deployments" and traditional server environments: + +1. **Server Environments** (Dev/Staging/Production servers): + + - Separate physical or virtual infrastructure + - Different URLs (e.g., `dev-server.com`, `staging-server.com`, `prod-server.com`) + - Typically used for different stages of backend development + +2. **CodePush Deployments** (Staging/Production/etc.): + - Logical environments within a single CodePush server + - Share the same server infrastructure and URL + - Control how app updates are distributed to different user segments + +#### Why CodePush Uses This Model + +CodePush deployments provide a release pipeline for app updates, allowing you to: + +- Test updates with internal users before general release +- Gradually roll out changes to production users +- Maintain separate channels for beta testers and regular users +- Quickly roll back problematic updates + +#### How CodePush Deployments Work Together + +A typical workflow using multiple deployments: + +1. **Development**: + + - Developers make changes to the app's JavaScript and assets + +2. **Staging Release**: + + - Updates are pushed to the "Staging" deployment + - Internal testers verify the update using the same app binary but with a different deployment key + - Bugs are found and fixed before reaching external users + +3. **Production Release**: + + - Once verified, updates are promoted from Staging to Production + - This copies the release metadata but keeps the same package blob + - End users with the Production deployment key receive the update + +4. **Emergency Rollback**: + - If issues appear in Production, rollback to a previous release + - No need to rebuild or resubmit the app to app stores + +This multi-deployment model on a single CodePush server gives you the flexibility of multiple environments without the overhead of managing separate infrastructure for each release channel. + +### Package + +- **Purpose**: Represents a specific release/update +- **Key Fields**: + - `appVersion`: Compatible app version + - `blobUrl`: URL to the actual update package + - `manifestBlobUrl`: URL to the manifest file + - `packageHash`: Hash of the package content + - `description`: Release notes + - `isDisabled`: Whether the update is disabled + - `isMandatory`: Whether the update is mandatory + - `size`: Size of the package + - `uploadTime`: When the package was uploaded + - `label`: Auto-generated version + - `releaseMethod`: How package was created (Upload, Promote, Rollback) + - `originalDeployment`: Source deployment if promoted + - `originalLabel`: Original label if promoted or rolled back + - `rollout`: Percentage of users receiving the update +- **Relationships**: + - Belongs to a Deployment (parent-child) + - Referenced by Deployment's `package` field (latest release) + +### Collaborator + +- **Purpose**: Links an Account to an App with permissions +- **Structure**: + ``` + collaborators: { + "user@example.com": { + accountId: "accountId", + permission: "Owner" | "Collaborator", + isCurrentAccount: boolean + } + } + ``` +- **Relationships**: + - Stored as a map within the App object + - Links an Account to an App with specific permissions + +### AccessKey + +- **Purpose**: Used for CLI authentication +- **Key Fields**: + - `id`: Unique identifier + - `name`: Key name + - `friendlyName`: Human-readable name + - `createdBy`: Email of creator + - `createdTime`: When key was created + - `expires`: Expiration timestamp + - `isSession`: Whether it's a temporary session key +- **Relationships**: + - Belongs to an Account (parent-child) + +### Storage Implementation + +- Azure Table Storage uses a hierarchical key structure to represent relationships +- Partition/row keys encode entity relationships (e.g., "appId_123_deploymentId\*\_456") +- Shortcut keys for efficient lookups (by email, deployment key, etc.) +- Package history stored as JSON in blob storage (limited to 50 most recent releases) + +### Accessing Azure Table Storage in the Portal + +To view and inspect your CodePush data in the Azure portal: + +1. **Log in to Azure Portal**: + + - Open your browser and navigate to: https://portal.azure.com + - Sign in with your Azure credentials + - Note: If you can't click the link above, copy and paste the URL into your browser + +2. **Find Your Storage Account**: + + - In the left menu, click on "Storage accounts" + - Locate and select the storage account used by your CodePush server (typically named "codepushstorage{suffix}") + +3. **Access Table Service**: + + - In the storage account menu, scroll down to the "Data storage" section + - Click on "Tables" + +4. **View Table Data**: + + - You'll see a table named "storagev2" (the main CodePush table) + - Click on the table name to open it + - Use the "Query" button to view table entities + +5. **Running Queries**: + + - To view all records: Leave the query empty and click "Run" + - To filter by a specific partition key: + ``` + PartitionKey eq 'accountId 12345' + ``` + - To find a specific app: + ``` + PartitionKey eq 'appId 67890' + ``` + - To view deployments for an app: + ``` + PartitionKey eq 'appId 67890' and RowKey ge 'appId 67890 deploymentId' + ``` + +6. **Understanding Table Structure**: + + - Each entity has a PartitionKey and RowKey that encode relationships + - Entity data is stored as properties + - Hierarchical keys use space and asterisk delimiters + - The asterisk (\*) is used to mark leaf nodes in hierarchical keys + +7. **Storage Explorer Alternative**: + - For a more user-friendly experience, use Azure Storage Explorer + - Download from: https://azure.microsoft.com/features/storage-explorer/ + - Copy and paste this URL into your browser to download + - Connect to your storage account and navigate to Tables → storagev2 + +This direct access to Table Storage can be useful for debugging, manual data inspection, or recovering from corrupted states when needed. + +## Complete End-to-End Example + +1. **Initial Setup**: + + - Developer deploys CodePush server to Azure + - Sets up GitHub OAuth app with callback URL + - Configures server with OAuth credentials + - Registers account: `code-push-standalone register https://my-codepush.azurewebsites.net` + +2. **App Creation**: + + - Creates apps: + ``` + code-push-standalone app add MyApp-iOS ios + code-push-standalone app add MyApp-Android android + ``` + - Server creates records in Azure Tables and generates deployment keys + +3. **SDK Integration**: + + - Adds CodePush SDK to React Native app + - Configures custom server URL and deployment keys + - Wraps app with CodePush HOC + +4. **Update Workflow**: + + - Makes changes to app code + - Releases update to Staging: + ``` + code-push-standalone release-react MyApp-iOS ios -d Staging + ``` + - CLI bundles app and uploads to server + - Server stores bundle in Blob Storage and metadata in Tables + - Tests update on test devices + - Promotes to Production: + ``` + code-push-standalone promote MyApp-iOS Staging Production + ``` + +5. **User Update Experience**: + - End user opens app + - SDK checks for updates from server + - Server determines if update is available + - SDK downloads, verifies, and applies update + - App restarts with new code without App Store submission + +This comprehensive workflow allows for rapid iteration and deployment of JavaScript and asset changes, bypassing the traditional app store review process while maintaining a robust, secure update mechanism.