DeployPulse

Build configurations

Many CodePush apps do not keep one deployment key in Info.plist and strings.xml. They pick the key per build: Staging for internal builds, Production for the store. This page shows where those keys usually live and what each one should hold after the move to DeployPulse.

The rule is the same everywhere: every place that holds an old deployment key gets a DeployPulse key, and every place that holds a server URL gets https://apps.deploypulse.io. Get your keys with:

dpctl deployment ls MyApp-iOS --displayKeys
dpctl deployment ls MyApp-Android --displayKeys

Which key goes where

BuildKey
The build you ship to the App Store and Google Play (usually Release on iOS, release on Android)The app's Production key
An internal or QA build (for example a Staging configuration or a releaseStaging build type)The app's Staging key
Debug / debugCan stay empty

Debug builds load the JavaScript from Metro, not from CodePush (see the #if DEBUG branch in iOS Setup), so their key is never used. Microsoft's setup guide leaves it empty, and that is fine.

Keys are per app as well as per deployment: the iOS build takes keys from your iOS app, the Android build from your Android app.

Xcode build settings

Microsoft's multi-deployment guide sets the key in Info.plist to a build setting instead of a literal:

<key>CodePushDeploymentKey</key>
<string>$(CODEPUSH_KEY)</string>

CODEPUSH_KEY is a user-defined build setting with one value per build configuration. Change the values, not the plist. They can be in several places, and Xcode takes the first one it finds, in this order:

  1. The app target's build settings.
  2. The .xcconfig file the target uses for that configuration.
  3. The project's build settings. Microsoft's guide adds CODEPUSH_KEY here, on the project node rather than the target, so look here first if you followed it.
  4. The .xcconfig file the project uses for that configuration.

In Xcode, select the project or the target, open Build Settings, choose All and Levels, and search for CODEPUSH_KEY. The Levels view shows every place that sets it. In project.pbxproj the values sit in the XCBuildConfiguration sections, one per configuration. In an .xcconfig file it is one line:

CODEPUSH_KEY = YOUR_PRODUCTION_KEY

The setting's name is whatever your project uses: search the plist for $( to find it. If an .xcconfig file #includes another file, the value can be in the included one. Files under ios/Pods/ are generated by CocoaPods and never hold it.

A value can also come from outside the project: xcodebuild CODEPUSH_KEY=... on the command line, or fastlane xcargs. Change it there, in your CI configuration or secrets.

Some apps use a separate plist per configuration instead (Info-Staging.plist, Info-Release.plist, selected by the INFOPLIST_FILE build setting). Put the key in each one.

Gradle build types

Microsoft's guide defines the key per build type with resValue in android/app/build.gradle:

android {
    buildTypes {
        debug {
            resValue "string", "CodePushDeploymentKey", '""'
        }
        releaseStaging {
            resValue "string", "CodePushDeploymentKey", '"YOUR_STAGING_KEY"'
            matchingFallbacks = ['release']
        }
        release {
            resValue "string", "CodePushDeploymentKey", '"YOUR_PRODUCTION_KEY"'
        }
    }
}

Replace each key between the inner quotes. Define the key in one place only: when build.gradle defines it with resValue, strings.xml must not have a CodePushDeploymentKey entry too.

Other places to check:

  • Resource files per build type or flavor. android/app/src/<buildType>/res/values/strings.xml (or src/<flavor>/...) overrides src/main for that build. Search every strings.xml under android/app/src/.

  • buildConfigField. Some apps put the key in BuildConfig and pass it to the SDK in MainApplication:

    buildConfigField "String", "CODEPUSH_KEY", '"YOUR_PRODUCTION_KEY"'
    
    CodePush.getInstance(BuildConfig.CODEPUSH_KEY, applicationContext, BuildConfig.DEBUG)
    

    Replace the key in each buildConfigField line. The key passed in MainApplication is the one the SDK uses, whatever strings.xml says.

  • gradle.properties or environment variables. A resValue or buildConfigField can read its value from a property (project.findProperty(...)) or from System.getenv(...). Change the value where it is set: gradle.properties, -P on the Gradle command line, or your CI secrets.

Server URL keys

The server URL has to point at DeployPulse in every configuration that sets one:

  • iOS: CodePushServerURL in Info.plist (in each plist, if there are several).
  • Android: CodePushServerUrl, lowercase "rl", in strings.xml or a resValue.
<!-- Info.plist -->
<key>CodePushServerURL</key>
<string>https://apps.deploypulse.io</string>
resValue "string", "CodePushServerUrl", '"https://apps.deploypulse.io"'

@deploypulseio/react-native-code-push already defaults to DeployPulse, but an old App Center URL left in any configuration overrides that default for that build. Microsoft's package and most other CodePush SDKs default to App Center, so with those the keys are required. Setting both keys in every configuration is the safe choice.

react-native-config and other env-based keys

With react-native-config, the key lives in .env files, one per environment:

# .env.production
CODEPUSH_KEY=YOUR_PRODUCTION_KEY

It reaches the SDK in one of three ways, and each needs the new key in the .env file it reads:

  • In JavaScript, passed as the deploymentKey option, for example codePush({ deploymentKey: Config.CODEPUSH_KEY }) or codePush.sync({ deploymentKey: ... }). A key passed in JavaScript overrides the native key for that call.
  • On iOS, through the build setting react-native-config generates ($(CODEPUSH_KEY) in Info.plist).
  • On Android, through resValue or buildConfigField lines that read project.env.get("CODEPUSH_KEY") in build.gradle.

Template files such as .env.example are not read at build time. Update the files your builds actually load, and any copies your CI writes from secrets.

Keys you have to check by hand

A value that is only known when the app is built cannot be checked by reading the project's files. That covers:

  • a build setting passed on the command line or by fastlane xcargs, or set in an #included .xcconfig;
  • gradle.properties, -P properties, System.getenv(...) and other environment variables;
  • react-native-config .env files, including its generated tmp.xcconfig;
  • buildConfigField values and Android product flavors;
  • a key passed to CodePush.getInstance(...) or set with CodePush.setDeploymentKey in native code, or a deploymentKey passed in JavaScript.

For each one, find where the value is set and make sure it is a DeployPulse key for the right app and deployment. The quickest end-to-end check is a real build: install it, release a small update to the deployment it should use, and confirm it arrives. dpctl debug ios (simulator) and dpctl debug android (emulator or device) show the SDK's logs while you test, see Debugging DeployPulse Integration.

White-label

A white-label project builds several branded apps from one codebase. Each brand is its own app in the stores, so give each brand its own DeployPulse app pair:

dpctl app add BrandA-iOS --platform ios
dpctl app add BrandA-Android --platform android
dpctl app add BrandB-iOS --platform ios
dpctl app add BrandB-Android --platform android

Each brand then has its own keys, its own release history and its own rollbacks, and a release for one brand never reaches another.

Android product flavors. Put each brand's key in its flavor:

android {
    flavorDimensions "brand"
    productFlavors {
        brandA {
            dimension "brand"
            resValue "string", "CodePushDeploymentKey", '"BRAND_A_ANDROID_PRODUCTION_KEY"'
        }
        brandB {
            dimension "brand"
            resValue "string", "CodePushDeploymentKey", '"BRAND_B_ANDROID_PRODUCTION_KEY"'
        }
    }
}

Or keep a strings.xml per flavor in android/app/src/brandA/res/values/ and android/app/src/brandB/res/values/. If you also use Staging keys per build type, the key depends on both the flavor and the build type: put it in the source set for that combination, such as android/app/src/brandARelease/res/values/strings.xml.

iOS. Brands are usually separate targets or schemes, each with its own Info.plist or its own build settings. Put each brand's key in its own plist, or set CODEPUSH_KEY per target and configuration as in Xcode build settings.

Releasing. Release each brand to its own app. dpctl reads the app version from the default Info.plist and build.gradle, so point it at the brand's files, or name the version yourself:

dpctl release-react BrandA-iOS ios -d Production --plistFile ios/BrandA/Info.plist
dpctl release-react BrandA-Android android -d Production --targetBinaryVersion 2.4.0

Next steps