CI/CD – All about AppCenter (1)

GitHub

react-native-codepush-as-over-the-air-ota-a-stroke-of-genius-7fbd0cf59ba0

What is CodePush?

What is CodePush limitation?

It does not support the following component properties:

  • SliderIOS component
    • maximumTrackImage, minimumTrackImage, thumbImage, trackImage props
  • Video component
    • source prop

When shouldn’t CodePush be used?

  • New features
    • because you can’t add something that has a native code change
  • UI changes, changing the functionality of your app, nything that may impact native code
    • These are related to app store terms and expectations of a user. They expect updates to happen when they download an update from the app store.

When should CodePush be used?

  • Beta features for a subset of trusted users
  • Bug fixes
  • Performance enhancements

Because:

  • Updates may happen when a user is on a cellular network, don’t eat up their data plan with huge updates
  • Updates can happen in the background and, even though the code is updating, the user shouldn’t really see any changes (though they may feel the performance improvements).

How to use CodePush to release JS bundle?

Enable codepush from AppCenter

Installation

Install AppCenter CLI

// Get the CLI
npm install -g appcenter-cli

// Login
appcenter login

// View your apps, we will use these names later
appcenter apps list
// output: baohung/XXXXX

// View the environments and corresponding deployment keys
// appcenter codepush deployment list -k --app <USERNAME>/<APPNAME>
appcenter codepush deployment list -k --app baohung/XXXXX

Install CodePush

yarn add react-native-code-push

Release

  • Make changes to JS files
  • Perform CodePush release
// View your apps, we will use these names later
appcenter apps list
// output: baohung/XXXXX

appcenter codepush release-react -a baohung/XXXXX -d Production
  • How to perform signing release
appcenter codepush release-react -a baohung/XXXXX -d Production --privateKeyPath 'xxxxxx'

https://medium.com/cybermonkey/mastering-over-the-air-updates-in-react-native-with-codepush-part-1-faf241a7f84b

How does CodePush work?

Version control

If you have two types of apk, one is 1.9.1 and one is 1.9.2. And Code Push release v10 is for 1.9.1 and v11 is for 1.9.2 . Then, 1.9.1 users can’t update v11 automatically and should download a new package from the store for using v11 

Update frequency

  • By default, CodePush will check for updates on every app start. If an update is available, it will be silently downloaded, and installed the next time the app is restarted
  • If an available update is mandatory, then it will be installed immediately
  • You can also choose to sync up with the CodePush server every time the app resumes from the background.
let codePushOptions = {
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
  installMode: codePush.InstallMode.ON_NEXT_RESUME,
  updateDialog: false,
}

class MyApp extends Component {
}

MyApp = codePush(codePushOptions)(MyApp);
let codePushOptions = {
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
  installMode: codePush.InstallMode.ON_NEXT_RESUME,
  updateDialog: false,
}

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

MyApp = codePush(codePushOptions)(MyApp);

Optional and mandatory update

ReleaseMandatory?
v1No
v2No
v3Yes
v4No
v5No
Example
  • If you are at v1 or v2, your app will download v5 then install it immediately
    • because v5 is considered of including v3’s changes which is mandatory
  • If you are at v3, your app will download v5 and install it after app is restarted
    • because v5 doesn’t include any mandatory update

Debug

  • Open console.log to see log CodePush message
  • You can create an Update button to trigger Update process like this
import codePush from 'react-native-code-push'

const YourComponent = () => {

  const [syncStatus, setSyncStatus] = useState('')

  const onButtonPress = async () => {
    await codePush.sync(
      {
        updateDialog: true,
        installMode: codePush.InstallMode.IMMEDIATE,
      },
      (state) => onStateChanged(state),
    )
  }

  const onStateChanged = async (state) => {
    if (state === codePush.SyncStatus.UP_TO_DATE) {
      setSyncStatus('Up to date')
    } else if (state === codePush.SyncStatus.UPDATE_INSTALLED) {
      setSyncStatus('Updated')
      codePush.restartApp(true)
    } else if (state === codePush.SyncStatus.UPDATE_IGNORED) {
      setSyncStatus('Ignored')
    } else if (state === codePush.SyncStatus.UNKNOWN_ERROR) {
      setSyncStatus('Error')
    } else if (state === codePush.SyncStatus.SYNC_IN_PROGRESS) {
      setSyncStatus('Waiting other Sync operation...')
    } else if (state === codePush.SyncStatus.CHECKING_FOR_UPDATE) {
      setSyncStatus('Checking...')
    } else if (state === codePush.SyncStatus.AWAITING_USER_ACTION) {
      setSyncStatus('Pending')
    } else if (state === codePush.SyncStatus.DOWNLOADING_PACKAGE) {
      setSyncStatus('Downloading...')
    } else if (state === codePush.SyncStatus.INSTALLING_UPDATE) {
      setSyncStatus('Installing...')
    } else {
      setSyncStatus('Unknown')
    }
  }

  return (
    <>
      <View>
        <TouchableOpacity onPress={onButtonPress}>
          <Text>Check for updates</Text>
        </TouchableOpacity>
        <Text>{syncStatus}</Text>
      </View>
    </>
  )
}
  • For Android, you can see update is done, bundle is installed but no change is applied until app is built as release mode

Issues

Error in getting binary resources modified time

Edit android/app/build.gradle

defaultConfig {
  ...
  // CodePush fix due to this issue
  // https://github.com/microsoft/react-native-code-push/issues/1961
  resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
  ...
}

What if you change app version and release a CodePush release?

App version is controlled by native code, no change will be applied

Be the first to comment

Leave a Reply

Your email address will not be published.


*