Skip to content

Deploy Command

Deploy an over-the-air update bundle to your users.

Synopsis

bash
silverbullet-ota deploy [options]

Description

The deploy command builds your JavaScript bundle, packages it with assets, and uploads it to the SilverOTA platform. The update will be distributed to devices matching the target version and channel criteria.

Options

--platform, -p <platform>

Required (unless using --interactive)

Specifies which platform to build for.

  • Choices: ios, android
  • Example: --platform ios

--target-app-version, -t <version>

Required (unless using --interactive)

Specifies which app version(s) should receive this update. Uses semver range format.

  • Format: Semantic versioning range (e.g., 1.0.0, 1.x.x, >=1.0.0 <2.0.0)
  • Example: --target-app-version 1.2.0

TIP

Use 1.x.x to target all minor versions of major version 1 (e.g., 1.0.0, 1.1.0, 1.2.5)

--channel, -c <channel>

The deployment channel to use.

  • Default: production
  • Example: --channel staging

--force-update, -f

Mark this update as mandatory. Users will be forced to update before using the app.

  • Default: false
  • Example: --force-update

WARNING

Use force updates sparingly. They can disrupt user experience if used for non-critical updates.

--bundle-output-path, -o <path>

Custom path where the bundle.zip will be generated.

  • Default: ./.silverbullet-ota/bundle
  • Example: --bundle-output-path ./build/ota

--message, -m <message>

Custom deployment message. If not provided, the latest git commit message is used.

  • Example: --message "Fixed critical crash on Android"

--interactive, -i

Run in interactive mode with prompts for all options.

  • Default: false
  • Example: --interactive

Examples

Basic Deployment

Deploy to iOS production for a specific version:

bash
silverbullet-ota deploy \
  --platform ios \
  --target-app-version 1.0.0 \
  --channel production

Deploy with Force Update

Deploy a critical security patch that users must install:

bash
silverbullet-ota deploy \
  --platform android \
  --target-app-version 1.x.x \
  --channel production \
  --force-update \
  --message "Critical security patch - please update immediately"

Deploy to Staging

Test updates on staging before production:

bash
silverbullet-ota deploy \
  --platform ios \
  --target-app-version 1.0.0 \
  --channel staging

Interactive Mode

Let the CLI prompt you for all options:

bash
silverbullet-ota deploy --interactive

Interactive prompts:

✔ Select platform › ios
✔ Target app version › 1.0.0
✔ Channel › production
✔ Force update? … no
✔ Custom message? … Bug fixes and improvements

Using npm Scripts

After project init, you can use the convenient npm scripts:

bash
# Deploy iOS to production
npm run silverbullet:deploy:ios

# Deploy Android to production
npm run silverbullet:deploy:android

These scripts automatically use --platform but you can add other options:

json
{
  "scripts": {
    "silverbullet:deploy:ios": "silverbullet-ota deploy --platform ios",
    "silverbullet:deploy:ios:staging": "silverbullet-ota deploy --platform ios --channel staging",
    "silverbullet:deploy:android": "silverbullet-ota deploy --platform android"
  }
}

Deployment Process

When you run deploy, the following steps occur:

1. Git Information Retrieval

Fetches the latest commit hash and message:

✓ Git commit: abc1234 - "Fix navigation bug"

This information is stored with the deployment for tracking.

2. Configuration Loading

Loads your ota.config.ts with the specified channel context:

✓ Loaded configuration
  Project ID: proj_abc123
  Channel: production

3. Version Detection

Auto-detects your native app version if --target-app-version not provided:

iOS: Reads CFBundleShortVersionString from Info.plist

✓ Detected iOS version: 1.0.0

Android: Reads versionName from build.gradle

✓ Detected Android version: 1.0.0

4. Bundle Building

Runs your configured build plugin (bare or expo):

Bare React Native:

✓ Building React Native bundle...
  Entry file: index.js
  Platform: ios
  Dev: false
  Minify: true

Expo:

✓ Building Expo bundle...
  Entry point: node_modules/expo/AppEntry.js
  Platform: ios

5. Bundle Packaging

Creates a ZIP archive with the bundle and assets:

✓ Created bundle.zip (2.4 MB)
  Location: .silverbullet-ota/bundle/bundle.zip

6. Hash Calculation

Computes SHA-256 hash for integrity verification:

✓ Bundle hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

7. Upload

Sends the bundle to SilverOTA servers:

⣾ Uploading bundle... (2.4 MB)
✓ Upload complete

8. Deployment Confirmation

Displays deployment details:

✅ Deployment successful!

Deployment ID: dep_xyz789
Platform: ios
Channel: production
Target Version: 1.0.0
Message: Fix navigation bug
Commit: abc1234

View deployment: https://silverota.com/console/projects/proj_abc123/deployments/dep_xyz789

Version Targeting

The --target-app-version option accepts semver ranges:

Exact Version

Target only apps with version 1.0.0:

bash
--target-app-version 1.0.0

Wildcard Pattern

Target all 1.x.x versions (1.0.0, 1.1.0, 1.2.5, etc.):

bash
--target-app-version 1.x.x

Target all versions in the 1.2.x range:

bash
--target-app-version 1.2.x

TIP

Always test version ranges carefully. Use staging deployments to verify targeting behavior.

Force Updates

Force updates (--force-update) make the update mandatory. Users cannot skip it.

When to Use Force Updates

  • Security vulnerabilities: Critical security patches
  • Breaking API changes: Server API changes that old app versions can't handle
  • Data corruption fixes: Bugs that could corrupt user data
  • Critical crashes: App-breaking bugs

When NOT to Use Force Updates

  • Minor bug fixes
  • New features
  • UI improvements
  • Performance optimizations

User Experience

With force update enabled:

  1. User opens the app
  2. SDK detects a mandatory update
  3. Download starts automatically (or with a non-dismissable prompt)
  4. App reloads after download
  5. User can now use the app

Without force update:

  1. User opens the app
  2. SDK detects an optional update
  3. User can choose to update now or later
  4. Update happens in background if user chooses "later"

Deployment Messages

The --message option lets you document what's in each deployment.

Auto-Generated Messages

If you don't provide --message, the CLI uses your latest git commit message:

bash
git commit -m "Fix navigation bug in settings screen"
silverbullet-ota deploy --platform ios

# Deployment message: "Fix navigation bug in settings screen"

Custom Messages

Provide context for your team and users:

bash
silverbullet-ota deploy \
  --platform ios \
  --message "Hotfix: Resolved crash when viewing profile page"

Troubleshooting

Version Detection Failed

Symptom: "Could not detect app version" error

Solution for iOS: Ensure CFBundleShortVersionString exists in Info.plist:

xml
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>

Solution for Android: Ensure versionName exists in android/app/build.gradle:

gradle
android {
    defaultConfig {
        versionName "1.0.0"
    }
}

Or explicitly provide version:

bash
silverbullet-ota deploy --platform ios --target-app-version 1.0.0

Best Practices

1. Test on Staging First

bash
# 1. Deploy to staging
silverbullet-ota deploy --platform ios --channel staging

# 2. Test thoroughly

# 3. Deploy to production
silverbullet-ota deploy --platform ios --channel production

Next Steps