Skip to content

Instantly share code, notes, and snippets.

@hemanth-manoharan
Last active June 25, 2022 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hemanth-manoharan/5460456f019faae2678776427f879bac to your computer and use it in GitHub Desktop.
Save hemanth-manoharan/5460456f019faae2678776427f879bac to your computer and use it in GitHub Desktop.
Tutorial #3: How to perform OTA (Over-The-Air) updates using CodePush

Tutorial #3: How to perform OTA (Over-The-Air) updates using CodePush

This post is the 3rd one in a series of posts on Electrode Native.

It assumes that one has already completed the steps in Tutorial #2 here - https://gist.github.com/hemanth-manoharan/8c0f5bda0469335ce9410ea61dbc4e54

Ref: https://native.electrode.io/cli-commands/code-push#prerequisites

npm install -g appcenter-cli
appcenter login
appcenter apps create -p "React-Native" -o "Android" -d ErnOuterAppAndroid
  • From the AppCenter portal, create the default deployments for that app (Staging and Production).

  • Then, retrieve the CodePush deployment keys for the app using the following command. Keep a note of the key against Staging deployment.

appcenter codepush deployment list -a hemanth-aero-pmdp/ErnOuterAppAndroid -k

  • Now, run the following to locally setup the CodePush API Access token with Electrode Native Note: Here, we need to set the Code Push API Access Token and not Deployment Key

ern platform config set codePushAccessKey YOUR_CODE_PUSH_API_ACCESS_TOKEN

  • Now, let's move to app1-miniapp folder (the app for which we want to push OTA update) and perform the following steps

  • Run the command

ern add react-native-code-push

  • Then, in the app1-miniapp code, decorate the App Component class in App.js with codePush as shown below. To decorate the same with codePush, the component needs to be defined as a Class Component. Not a Function Component.
import codePush from 'react-native-code-push';

...

// const App: () => React$Node = () => {
class App extends React.Component {
  render() {
    ...
  }
}

...

App = codePush({
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
  installMode: codePush.InstallMode.ON_NEXT_RESUME,
  minimumBackgroundDuration: 60 * 2,
})(App)

export default App;

Section - Publish an updated version of app1 simply and embed the aar within ErnOuterApp to get access to CodePushPlugin class in tbe native Android code

  • Now, update the version in package.json of app1-miniapp to 0.0.2 and re-publish the same to npm

  • Now, update the cauldron with the new version of app1. Note: We are choosing not to update the native app version in this case but we are bumping up the container version.

ern cauldron update miniapps app1-miniapp@0.0.3 -d ErnOuterApp:android:0.0.1 -v 1.0.2

  • Now, create the container locally again using the cauldron metadata.

ern create-container -d ErnOuterApp:android:0.0.1 -p android

  • Now, run the gradle build to create the updated .aar file.

  • Then, copy over the updated lib-debug.aar to the libs folder of the ErnOuterApp android project

  • Change the initialization code in the ErnOuterApp as follows

ElectrodeReactContainer.initialize(
    getApplication() /* Application instance */,
    new ElectrodeReactContainer.Config(),
    new CodePushPlugin.Config("DEPLOYMENT_KEY")
    /* Additional plugins configuration here */);
  • Then, test out the app with both the buttons and check if things are fine.

  • At this point - we are all set for pushing OTA updates for non-native changes to app1. Let's do that in the next section.

Section - Finally, pushing an OTA update for app1

  • First, make some change in app1-miniapp, update the version in package.json to 0.0.3 and re-publish the same to npm

  • Run the commands

ern cauldron update miniapps app1-miniapp@0.0.3 -d ErnOuterApp:android:0.0.1 -v 1.0.3

  • Important: Ensure that the versionName in the app's build.gradle for ErnOuterApp has the right version "0.0.1"

  • Now, let's use CodePush to dynamically push the OTA update

ERN_LOG_LEVEL=debug ern code-push release --miniapps app1-miniapp@0.0.3 -d ErnOuterApp:android:0.0.1 --deploymentName Staging

  • To apply the update immediately, make it a mandatory update via AppCenter portal.

  • Now, finally run the app and check if the update happens.

  • If the code-push command fails due to an internal server error as below, then follow the steps indicated.

[ Releasing bundle through CodePush (Started) ]
[ Releasing bundle through CodePush (Failed) ]
✖ performCodePushOtaUpdate Error: {"message":"Internal Server Error","statusCode":500}
✖ An error occurred: {"message":"Internal Server Error","statusCode":500}
Error: {"message":"Internal Server Error","statusCode":500}
    at CodePushSdk.releaseReact (/Users/hemanth/.ern/versions/0.45.5/node_modules/ern-core/src/CodePushSdk.ts:73:15)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
  • Note down the temporary folder path like the one below in the output of the above command

/private/var/folders/*

We are interested in the bundleOut folder under the same.

  • Then, run the following command directly

appcenter codepush release -a hemanth-aero-pmdp/ErnOuterAppAndroid -c TEMP_FOLDER_PATH/bundleOut -t 0.0.1 -d Staging

@hemanth-manoharan
Copy link
Author

These instructions are needed for ReactNative v0.60 and above.

Install react-native-code-push in ernouterappwrapper folder.

End of build.gradle in app needs to look like the below:

apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

End of settings.gradle needs to look like the below:

apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)

include ':app', ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

Use following instructions for decorating App with CodePush
Reference: https://github.com/microsoft/react-native-code-push

For functional component

import codePush from "react-native-code-push";

let MyApp: () => React$Node = () => {
}

MyApp = codePush(MyApp);

Reference: https://docs.microsoft.com/en-us/appcenter/distribution/codepush/rn-get-started#android-setup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment