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
| Build | Key |
|---|---|
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 / debug | Can 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:
- The app target's build settings.
- The
.xcconfigfile the target uses for that configuration. - The project's build settings. Microsoft's guide adds
CODEPUSH_KEYhere, on the project node rather than the target, so look here first if you followed it. - The
.xcconfigfile 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(orsrc/<flavor>/...) overridessrc/mainfor that build. Search everystrings.xmlunderandroid/app/src/. -
buildConfigField. Some apps put the key inBuildConfigand pass it to the SDK inMainApplication:buildConfigField "String", "CODEPUSH_KEY", '"YOUR_PRODUCTION_KEY"'CodePush.getInstance(BuildConfig.CODEPUSH_KEY, applicationContext, BuildConfig.DEBUG)Replace the key in each
buildConfigFieldline. The key passed inMainApplicationis the one the SDK uses, whateverstrings.xmlsays. -
gradle.propertiesor environment variables. AresValueorbuildConfigFieldcan read its value from a property (project.findProperty(...)) or fromSystem.getenv(...). Change the value where it is set:gradle.properties,-Pon 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:
CodePushServerURLinInfo.plist(in each plist, if there are several). - Android:
CodePushServerUrl, lowercase "rl", instrings.xmlor aresValue.
<!-- 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
deploymentKeyoption, for examplecodePush({ deploymentKey: Config.CODEPUSH_KEY })orcodePush.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)inInfo.plist). - On Android, through
resValueorbuildConfigFieldlines that readproject.env.get("CODEPUSH_KEY")inbuild.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,-Pproperties,System.getenv(...)and other environment variables;- react-native-config
.envfiles, including its generatedtmp.xcconfig; buildConfigFieldvalues and Android product flavors;- a key passed to
CodePush.getInstance(...)or set withCodePush.setDeploymentKeyin native code, or adeploymentKeypassed 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
- App Center Migration covers the rest of the move: the SDK package, the plain
Info.plistandstrings.xmlkeys, and CI. - Apps and deployments is the full dpctl reference.
