Handling Multi-Deployment Environments and AB Testing on react native

Aexomir
6 min readDec 5, 2023

--

Previously I’ve talked about how to configure React Native CodePush using a custom server. Also, I provided a step-by-step guide on how to set up the server and integrate it with your React Native app. Finally, I discussed on how to deploy updates to your app. In this part, We’re going to talk about how to manage multi deployment environments and AB Testing on React-Native.

Adding New Environment

In order to effectively test app releases, it is necessary to leverage multi deployments. This way, you never release an update to your end users that you haven't been able to validate yourself.

At first, We’re going to create a new environment named Dev using the following command:

code-push deployment add <appName> Dev

You can see that new environment has been added to your application. In order to see all the deployment environments along with their keys, you can use the following command:

code-push deployment ls MyApp -k

Previously, We just released to one Staging environment; but in order to release to a certain environment, we just have to provide the deployment name like:

Releasing App to a Specific Environment

code-push release MyApp ./code-push/index.android.bundle "*" --deploymentName Dev

After testing in the Dev environment and ensuring that everything works properly, We can then promote the app to an upper environment using the following command:

Rollout to Specific Percentage of Users

code-push promote MyApp Staging Production -r 20

The -r here provides the rollout functionality and selects the percentage of users which this update should be immediately available on their devices.

after waiting for a reasonable amount of time and ensuring that no crash reports or customer feedbacks are coming in, you can expand it to your entire users.

Patching to All Users

code-push patch MyApp Production -r 100

Configuring Multi Environments on Android and iOS

So far, We’ve seen how to setup Code-Push CLI to properly manage all deployment environments. Now, We’re going to explain on how to setup that on Android and ios.

You can read the full documentation along with more info from their official documents on the following links:
P.S: all step-by-step images are brought over from the original documentation.

android: https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-android.md

setup on iOS: https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-ios.md

iOS:

Step 1: Open your Xcode project and select your project in the Project navigator window

  1. Launch Xcode and open your existing React Native project.
  2. In the Project navigator window, locate your project and ensure it’s selected, not one of your targets.

Step 2: Create a duplicate of the “Release” configuration

  1. Switch to the Info tab.
  2. Click the “+” button in the Configurations section.
  3. Choose “Duplicate ‘Release’ Configuration” from the dropdown menu.
  1. Name the new configuration “Staging” or any preferred name.

Step 3: Add user-defined settings for Multi_Deployment_Config and CODEPUSH_KEY

  1. Select the Build Settings tab.
  2. Click the “+” button on the toolbar and select “Add User-Defined Setting.”
  1. Name the new setting “Multi_Deployment_Config.”
  2. Expand the Multi_Deployment_Config setting and add the following value:
$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

3. for Release. After that add value $(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME) for Staging

$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)
  • Add another user-defined setting named “CODEPUSH_KEY.”
  • Expand the CODEPUSH_KEY setting and specify your Staging deployment key for the Staging configuration and your Production deployment key for the Release configuration.

Retrieve these keys by running codepush deployment ls -a <ownerName>/<appName> -k from your terminal.

Step 4: Update the Info.plist file

  • Open your project’s Info.plist file.
  • Change the value of the CodePushDeploymentKey entry to $(CODEPUSH_KEY).

This will allow you to differentiate between staging and release builds when installed on the same device.

Android:

Step 1: Open the project’s app level build.gradle file

  1. Locate the project’s app level build.gradle file. This file is typically named android/app/build.gradle in standard React Native projects.

Step 2: Define resValue entries for deployment keys

  1. Within the android { buildTypes {} } section, add resValue entries for both your debug and release build types. These entries should reference your Staging and Production deployment keys, respectively.

For the debug build type, set the CodePushDeploymentKey value to an empty string (“”). This is because CodePush updates should not be tested in Debug mode, and the RN packager will override them. However, providing a key is necessary as CodePush checks for updates in all modes.

android {
...
buildTypes {
debug {
...
// Note: CodePush updates should not be tested in Debug mode as they are overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
resValue "string", "CodePushDeploymentKey", '""'
...
}

releaseStaging {
...
resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'

// Note: It is a good idea to provide matchingFallbacks for the new buildType you create to prevent build issues
// Add the following line if not already there
matchingFallbacks = ['release']
...
}

release {
...
resValue "string", "CodePushDeploymentKey", '"<INSERT_PRODUCTION_KEY>"'
...
}
}
...
}

Additionally, add the following line to the releaseStaging block. This ensures that if the releaseStaging build type is not recognized, it falls back to the release build type:

matchingFallbacks = ['release']

Step 3: Remove the key from strings.xml

  • If you configured the deployment key in the build process, remove the CodePushDeploymentKey key from the strings.xml file. This is because the key is now being defined in the build process.

NOTE: The naming convention for releaseStaging is significant due to this line.

Dynamic Deployment Assigning

The above section illustrated how you can leverage multiple CodePush deployments in order to effectively test your updates before broadly releasing them to your end users. However, if you want to be able to perform A/B tests, or provide early access of your app to certain users, it can prove very useful to be able to dynamically place specific users into specific deployments at runtime.

There are two ways to achieve this goal:

  1. Client Side:

This is useful when you want to implement Beta Testing that is user-visible and you’re not concerned with the privacy of your pre-production updates. In order to reach this goal, here’s a simple code to handle that:

type DeploymentKeys = {
ios: { [key: string]: string };
android: { [key: string]: string };
};

const CODEPUSH_DEPLOYMENT_KEYS: DeploymentKeys = {
android: {
production: 'PR-ANDROID-KEY',
staging: 'ST-ANDROID-KEY',
},
ios: {
production: 'PR-IOS-KEY',
staging: 'ST-IOS-KEY',
},
};

const handleChangeEnvironment = (env: string) => {
const { ios, android } = CODEPUSH_DEPLOYMENT_KEYS;
const selectedKeys = isIOS ? ios : android;
const deploymentKey = selectedKeys[env] || selectedKeys.production;

CodePush.sync({ deploymentKey });
};

2. Server Side:

This is useful when you want to implement AB Testing and assign experiments on users. In order to achieve this, here’s a simple code to handle key from server side:

api.addMonitor(async response => {
if (
response.ok &&
response.headers &&
Object.keys(response.headers).includes('ABTEST-KEY')
) {
const key = response.headers['ABTEST-kEY'];
return handleABTestEnvironment(key);
}
});

const handleABTestEnvironment = (deploymentKey: string) => {
CodePush.sync({ deploymentKey });
};

Conclusion

This was part two from the series of code-push configuration in react-native. To read the first part, check this.
Thanks for taking your time and I’d appreciate it if you give me your feedbacks. Happy Coding and see you in the next one! 🚀

--

--

Aexomir
Aexomir

Written by Aexomir

Mobile Application Developer for Life / Bug Hunter for Fun

No responses yet