Skip to main content

Releasing Updates

This guide covers the recommended release flow for bare React Native apps using SrcPush.

What OTA updates can include

Source Push updates can include:

  • JavaScript changes
  • bundled assets such as images and fonts
  • runtime behavior changes that do not require native code updates

They cannot include:

  • native Android or iOS code changes
  • native dependency changes
  • anything that requires shipping a new binary

When the native layer changes, publish a new store build first and then target the new binary line with subsequent OTA releases.

Prefer explicit package scripts

Define separate scripts per platform and environment:

{
"scripts": {
"srcpush:android:staging": "srcpush release-react YOUR_APP_NAME_ANDROID android -d Staging --privateKeyPath ./keys/private.pem --useHermes",
"srcpush:android:prod": "srcpush release-react YOUR_APP_NAME_ANDROID android -d Production --privateKeyPath ./keys/private.pem --useHermes",
"srcpush:ios:staging": "srcpush release-react YOUR_APP_NAME_IOS ios -d Staging --privateKeyPath ./keys/private.pem --plistFile ./ios/YOUR_APP/Info.plist --useHermes",
"srcpush:ios:prod": "srcpush release-react YOUR_APP_NAME_IOS ios -d Production --privateKeyPath ./keys/private.pem --plistFile ./ios/YOUR_APP/Info.plist --useHermes"
}
}

This keeps releases predictable and makes CI easier to wire correctly.

Basic release flow

Release to staging first:

yarn srcpush:ios:staging
yarn srcpush:android:staging

Release to production after validation:

yarn srcpush:ios:prod
yarn srcpush:android:prod

If the release must be pinned to a specific native app line, append --targetBinaryVersion when invoking the script:

yarn srcpush:ios:prod --targetBinaryVersion "1.2.3"
yarn srcpush:android:prod --targetBinaryVersion "1.2.3"

Signing and secret handling

Keep these out of git:

  • Source Push access keys
  • private signing keys
  • real deployment keys
  • public keys when your organization treats them as managed config

Tracked files should keep placeholders such as:

  • YOUR_ANDROID_STAGING_KEY
  • YOUR_ANDROID_PRODUCTION_KEY
  • YOUR_IOS_DEPLOYMENT_KEY
  • YOUR_PUBLIC_KEY

Injecting tracked config before release

If your repository stores placeholders in strings.xml and Info.plist, write the real values just before publishing.

Example:

node scripts/inject-srcpush-config.js \
--android-strings android/app/src/main/res/values/strings.xml \
--ios-plist ios/MyApp/Info.plist \
--deployment-key-android "$SRCPUSH_DEPLOYMENT_KEY_ANDROID" \
--deployment-key-ios "$SRCPUSH_DEPLOYMENT_KEY_IOS" \
--server-url "https://api.srcpush.com" \
--public-key-file ./keys/public.pem

Required arguments:

  • --android-strings
  • --ios-plist
  • --deployment-key-android
  • --deployment-key-ios

Optional arguments:

  • --server-url
  • --public-key
  • --public-key-file

Rollout and promotion strategy

A practical workflow is:

  1. Release to Staging
  2. Validate on real devices
  3. Release or promote to Production
  4. Monitor installation and rollback metrics

Use mandatory updates sparingly and only for critical fixes.

Common release mistakes

  • Publishing an OTA update for a binary line that has native changes
  • Duplicating deployment key values across build.gradle and strings.xml
  • Committing real keys into tracked native files
  • Releasing without the correct Info.plist path on iOS

Next steps