App Center Codepush avec React Native

Un des principaux problème dans le développement d’application est la dépendance aux stores officiels comme l’Apple Store ou le Play Store. Les tests, mises à jour et déploiements peuvent être laborieux. Et c’est ce à quoi essaye de répondre App Center de Microsoft et notamment CodePush.

Concept

CodePush est une des fonctionnalités de la solution App Center de Microsoft. Grace à celle-ci, il est possible de gérer la distribution de son application de la phase de test au déploiement en production.

Le principe est de disposer d’une console d’administration qui permet de gérer les versions d’applications qui seront disponibles au téléchargement et les versions associées.

Vous pouvez dès a present vous connecter avec votre compte Github / Microsoft / Google / Facebook sur App Center et utiliser la plateforme.

Mise en place

Pré-requis :

Pour la partie ligne de commande avec appcenter, vous devez être authentifié pour executer certaines commandes. Vous pouvez soit vous connecter directement via la commande appcenter login soit utiliser un token d’authentification déjà créé en ajoutant -t <token> à chaque commande.

Pour vérifier que vous êtes bien authentifié, utilisez la commande appcenter profile list.

Initialisation de l’application dans Appcenter

Commençons par la création de l’application dans l’environnement Appcenter. Vous pouvez nommer l’application comme vous le souhaitez. Ce nom n’est pas obligé de correspondre exactement au nom ou buildID de votre application.

Via l’interface Web

Sur la plateforme Appcenter, il faut ajouter une nouvelle application et renseigner a minima le nom, l’OS et la plateforme utilisée. Dans le cadre de React Native, créons les 2 applications avec un suffixe ‘-android’ ou ‘-ios’. Ici nous utiliserons React-Native-AppTest-android et React-Native-AppTest-ios.

NewAppIOS

Il faut ensuite générer les environements dans Distribute / CodePush et cliquer sur ‘Create standard deployments’.

standardDeployment

Via ligne de commande

De la même manière, en ligne de commande, il faut renseigner le nom, l’OS et la plateforme:

  • Android

appcenter apps create -d React-Native-AppTest-android -o Android -p React-Native
  • iOS

appcenter apps create -d React-Native-AppTest-ios -o iOS -p React-Native

Et ajouter les environements de déploiement Staging et Production:

  • Android

appcenter codepush deployment add -a <ownerName>/React-Native-AppTest-android Staging
appcenter codepush deployment add -a <ownerName>/React-Native-AppTest-android Production
  • iOS

appcenter codepush deployment add -a <ownerName>/React-Native-AppTest-ios Staging
appcenter codepush deployment add -a <ownerName>/React-Native-AppTest-ios Production

Initialisation de l’application

Si votre projet n’existe pas déjà, vous pouvez initialiser un projet React Native avec la commande react-native init <ProjectName>

Dans le dossier du projet:

Ajouter la dépendence react-native-codepush et l’intégrer dans iOS et Android.

  • Ajout de la dependence (v5.4.2)

yarn add react-native-code-push
  • Integration du code natif

react-native link react-native-code-push

linkCodePush

Lors de la commande react-native link, il sera demandé la clé de déploiement pour Android et iOS. Les clés peuvent être recupérées via les commandes suivantes:

  • Android

appcenter codepush deployment list -a <owner>/React-Native-AppTest-android -k
  • iOS

appcenter codepush deployment list -a <owner>/React-Native-AppTest-ios -k

listAppCenterKeys

Dans les commandes précédentes, -a permet de spécifier l’application ciblée et -k permet d’afficher les clés de déploiement. Pour recupérer le nom exact de l’application, on peut utiliser la commande: appcenter apps list.

Ces clés seront stockées dans votre projet dans les fichiers suivants:

  • Android: android/app/src/main/res/values/strings.xml
  • iOS: ios/<AppName>/Info.plist

Nous utiliserons l’environement Staging. L’application vérifira donc ses mises à jour sur cet environemement.

Enfin, dans le fichier App.js (ou le fichier ou vous déclarez le composant principal de votre application), nous allons ajouter le HOC de CodePush.

import React, { Component } from "react";
import {
  Platform,
  StyleSheet,
  Text,
  View,
  TouchableOpacity
} from "react-native";
import codePush from "react-native-code-push"; // Import du composant CodePush

const instructions = Platform.select({
  ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
  android:
    "Double tap R on your keyboard to reload,\n" +
    "Shake or press menu button for dev menu"
});

class App extends Component<Props> {
  onButtonPress() {
    // Ajout de la commande sync qui va nous permettre de recupérer les mises à jour
    codePush.sync({
      updateDialog: true, // Affichera une Alert à l'utilisateur
      installMode: codePush.InstallMode.IMMEDIATE // Installera la mise à jour immediatement
    });
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
        <View>
          <TouchableOpacity onPress={this.onButtonPress}>
            <Text>Check for updates</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF"
  },
  welcome: { fontSize: 20, textAlign: "center", margin: 10 },
  instructions: { textAlign: "center", color: "#333333", marginBottom: 5 }
});

// Definition des options de CodePush
const codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
// Ajout du HOC autour de l'application
export default codePush(codePushOptions)(App);

Ici, j’ai reutilisé le code généré par un nouveau projet React Native et y ai ajouté la configuration CodePush.

releaseApp

Voila, l’application est prête à recevoir des mises à jour “over-the-air”.

Déployer une Release

Avant de mettre en place le système de mise à jour, nous allons déployer une version ‘Release’. Cette version sera disponible en téléchargement pour les testeurs.

Cette étape n’est pas nécessaire pour déployer des mises à jour (Ex: Application deployée via le store officiel).

Afin que les applications puissent être installées sur les appareils des utilisateurs, il faut les signer. Les étapes sont différentes en fonction de la plateforme:

Une fois les applications signées, il faut générer les fichiers .apk et .ipa pour les mettre à disposition aux utilisateurs.

Pour Android, il suffit d’executer la commande suivante dans le dossier ‘android’ du projet: ./gradlew assembleRelease. Par défaut, le fichier apk se trouvera dans ./android/app/build/outputs/apk/release/app-release.apk.

Pour iOS, il faut:

  • Ouvrir le projet Xcode (Dans ./ios/<ProjectName>.xcodeproj)
  • Générer l’archive de l’application avec la fonction ‘Archive’ dans le menu ‘Product’
  • Une fois le build terminé, ouvrir l’Organizer depuis le menu ‘Windows’
  • Selectionner l’application, cliquer sur ‘Distribute App’ et suivre les instructions pour exporter l’application.

Une fois les applications signées et générées, on peut les mettre à disposition sur App Center via les commandes suivantes:

  • Android

appcenter distribute release -g Collaborators -f ./android/app/build/outputs/apk/release/app-release.apk -a <owner>/React-Native-AppTest-android
  • iOS

appcenter distribute release -g Collaborators -f <PathToIpaFile>.ipa -a <owner>/React-Native-AppTest-ios

Dans ces commandes nous avons utilisé:

  • -g pour assigner la release à un groupe de testeurs (Collaborators étant créé par défaut)
  • -f pour le chemin du fichier
  • -a pour le nom de l’application

Un email est envoyé aux testeurs avec le lien pour télécharger l’application.

Nous avons maintenant une application prête à être distribuée!

Note: N’oubliez pas de regénérer un package à chaque nouvelle release.

Déployer une Update

Nous avons vu plus haut comment utiliser App Center pour déployer une application prête à être installée sur un appareil. Malheureusement, notre bouton ‘Check for updates’ ne sert encore à rien.

Il nous faut donc déployer une mise à jour.

Pour cela, il suffit de faire une modification de notre application. J’ai modifié la couleur du texte du bouton comme ceci:

<Text style={{ color: "red" }}>Check for updates</Text>

La mise à jour peut maintenant être envoyée pour les 2 applications:

  • Android

appcenter codepush release-react -a <owner>/React-Native-AppTest-android -d Staging
  • iOS

appcenter codepush release-react -a <owner>/React-Native-AppTest-ios -d Staging

Une fois terminé, le clique sur le bouton ‘Check for updates’ devrait afficher un pop-up permettant de mettre à jour l’application.

updateApp

Et voila, le bouton est maintenant passé au rouge après un redémarrage soft de l’application.

Attention:

  • Les mises à jour CodePush ne pouront pas être testées en mode DEBUG. Dans ce mode, React Native utilise le Bundle JS généré par le packager. CodePush ne peut donc pas appliquer le nouveau bundle téléchargé.
  • Les changements dans le code natif (comme la modification des paramètres dans les fichiers gradle ou des changement dans AppDelegate.m) ne seront pas pris en compte dans les mises à jour. En effet, seul le Bundle JS est mis à jour.

Aller plus loin

Dans cet article, nous avons configuré CodePush pour mettre à jour notre application après un clique sur un bouton. La configuration par défaut ne necessite pas l’intervention de l’utilisateur. Je vous invite à regarder la documentation pour adapter ce scénario en fonction de vos besoin. Appcenter permet aussi beaucoup d’autre configuration tel que:

Sources