Relâchez le train. Rapport Yandex

Les processus de publication dans différentes équipes Yandex (et dans toutes les grandes sociétés informatiques) sont organisés de manière similaire, mais diffèrent dans de nombreux détails. Les développeurs mobiles ont leurs propres spécificités: leurs versions sont affectées par l'ordre de mise en page dans l'App Store et Google Play. Développeur Android Dmitry PolyakovDmpolyakov Il a parlé des processus autour de lui - comment son équipe envoie un train de versions selon un calendrier, comment lancer des versions non planifiées, ajouter des voitures à une version déjà sortie et que faire pour rester sur la bonne voie.


- Bonjour à tous, je suis Dmitry Polyakov, développeur Android de l'application mobile que je prends.



Maintenant, en deux équipes - développement Android et iOS, je prends - 13 personnes chacune. Cela nous permet d'effectuer de nombreuses tâches intéressantes en parallèle et de les transférer rapidement aux utilisateurs. Dans le rapport, je dirai comment nous avons appris à travailler avec git et à vivre dans un référentiel.

Ensuite, je vais vous expliquer comment fonctionne notre cycle de publication. Les gestionnaires viennent nous voir et disent que nous voulons déployer cette fonctionnalité dès que possible. Donc, probablement, tout gestionnaire le souhaite, nous avons donc mis en place le processus de publication afin de nous rendre sur l'App Store et Google Play chaque semaine. Je vais également parler des outils dont nous disposons et que je vous recommande d'essayer, ils sont sympas.

Git flow


Commençons par Git Flow. Comme base, nous avons pris le Git Flow classique, cependant, il a beaucoup changé dans nos conditions, sous notre équipe. Vous regardez aussi, et peut-être que quelque chose de cela vous conviendra, mais pas quelque chose. Chaque équipe a sa propre approche pour travailler avec git.

Comment ça marche avec nous? Epic est la branche racine de votre fonctionnalité, pour de grandes fonctionnalités. Pour le rendre plus clair, regardons immédiatement l'exemple de produit.



Le gestionnaire vient et dit - le développeur, faites-nous la fonctionnalité de la liste de souhaits avec les produits sélectionnés dans l'application. Le développeur démarre une nouvelle épopée de branche et l'appelle wishlist.



De plus, il le décompose en tâches plus petites, qui commencent dans le tracker. Peut-être que cela fonctionne avec le réseau, le rendu de l'interface utilisateur, l'écriture de tests. Pour chacune de ces fonctionnalités, il démarre une tâche dans le tracker. Et dès qu'il commence à terminer la tâche, il démarre la branche de fonctionnalité correspondante. La fait sortir de la même épopée.

Dès qu'il a fini de travailler sur une de ces fonctionnalités, il la verse dans l'épopée à travers la demande de pool. La demande de pool est un tel mécanisme lorsque d'autres développeurs de votre équipe vérifient votre code. S'ils n'aiment pas quelque chose, alors votre code risque de ne pas atteindre votre épopée, ce qui signifie que vous ne serez pas libéré avant d'avoir trouvé un accord avec eux.

Il y a deux de ces examinateurs dans notre équipe. Ils sont attribués au hasard. Il s'agit d'un processus automatisé, il sélectionne parmi les développeurs qui ont récemment travaillé avec les mêmes fichiers que vous avez modifiés dans votre demande de pool.



Ainsi, il s'avère que plusieurs épopées avec leur propre ensemble de fonctionnalités vivent en parallèle dans le projet. Une épopée ne peut avoir qu'une seule fonctionnalité. Cela peut se produire si nous voulons télécharger cette fonctionnalité via la demande de pool vers epic.



Dès que le travail sur toutes les fonctionnalités d'une épopée est terminé, la tâche quitte d'abord l'équipe de test, l'équipe QA, et ils testent fonctionnellement la branche. Une fois qu'ils ont trouvé des bugs, vous les éditez dans le cadre de cette épopée. Une fois tous les bugs corrigés, vous remplissez cette épopée en développement. Ici, aucune révision de code supplémentaire n'est déjà effectuée par votre équipe, car tout le code a déjà été examiné lors de l'étape des fonctionnalités dans Epic.

Notre développement est une telle branche dans laquelle le code déjà testé visite, car au stade épique, il est testé et le code est passé par la demande de pool.



Cela nous permet de créer en toute sécurité une nouvelle branche de publication au début du cycle de publication. Sans crainte qu'il y aura de nombreux bugs qui n'ont pas encore été testés. Par conséquent, nous créons une nouvelle branche de publication à partir de develop, elle est en cours de test. Dès que la version est testée et que nous sommes prêts à partir plus loin vers la porte, cette branche fusionne en master.

Parfois, nous avons un correctif et il existe un type de branche distinct pour celui-ci. Il s'agit d'une version très courte qui doit être déployée rapidement. Nous n'avons pas le temps d'attendre trois ou quatre jours avant le début du prochain cycle de publication. C'est généralement quelque chose de petit.

Par exemple, si une sorte de bogue est entré en production et est très critique, nous devons le corriger de toute urgence. Par conséquent, nous arrêtons la version actuelle, exécutons le correctif sur ce bogue et mettons à jour notre version. Mais le correctif n'est pas toujours une histoire de bugs. Parfois, nous avons besoin d'un produit.



Par exemple, dès que le mode d'auto-isolation a été introduit à Moscou, nous avons eu un besoin en produits pour que les utilisateurs puissent commander des produits sans contact. Désormais, lors de la passation d'une commande dans notre application, l'utilisateur peut sélectionner la fonction «Laisser à la porte». Le courrier arrive, laisse le colis sous la porte et vous le remet sans contact.

Avec cette tâche dans le correctif, nous avons également inclus des widgets différents qui vous invitent à rester à la maison et à commander des marchandises par courrier. N'allez pas aux points de ramassage maintenant. Nous avons déployé ces tâches via le correctif afin de pouvoir les transmettre à l'utilisateur dès que possible, car nous les considérons comme importantes.

Lorsque nous avons un correctif, nous le brunchons de master. De développer, il ne peut pas être brunch, car à ce moment, de nouveaux pourraient se développer épique, qui n'avait pas encore été publié. Mais nous ne voulons pas emporter ces épopées avec nous dans le correctif, afin qu'elles ne nous affectent pas au hasard et ne bloquent pas notre correctif. Une fois le correctif terminé, nous l'injectons dans master et l'ajoutons également à develop, car ce code n'existait pas encore dans develop.



Master est une base de code correspondant à la dernière version de l'application, qui est maintenant dans la boutique de l'utilisateur. C'est propre, sans bugs, car les tests fonctionnels et de régression y sont déjà passés, c'est une branche de sauvegarde.

Lorsque notre version est terminée, nous la réinjectons également dans develop. Parce que dans le cadre de la version, des bogues qui n'ont pas été trouvés dans les tests fonctionnels peuvent être trouvés et différentes épopées peuvent entrer en conflit les unes avec les autres. Par conséquent, nous injectons également la version dans develop afin que nous ayons également ces correctifs dans develop.



Beaucoup de travail peut être fait sur l'épopée, et afin de suivre le code en développement, le développeur l'ajoute parfois à son épopée, afin qu'il y ait moins de blocages.



Puisque nous avons ajouté develop à epic, epic pour les mêmes raisons doit être ajouté à votre fonctionnalité.



Au nom des branches épiques et des fonctionnalités, nous avons un numéro de ticket dans le traqueur de tâches. C'est cool, car c'est précisément par le numéro de ticket que nous pouvons découvrir complètement à partir de n'importe quelle partie de notre application, dans quels tickets il a changé, qui a écrit ce code et dans quel but il a été écrit.



La branche de version et de correctif a dans son nom le numéro de version de version actuelle de l'application. Certaines équipes combinent le numéro de correctif avec le numéro de version, le justifiant en disant que le correctif est quelque chose de petit et peut-être pas très important pour l'utilisateur. Par conséquent, ils n'augmentent pas la version de l'application. Nous n'utilisons pas cette approche, car divers rapports de plantage des fabricants nous parviennent, et nous voulons savoir exactement si ce rapport était en correctif ou dans la version, afin de savoir où chercher le problème.



Maîtriser et développer sont des branches qui vivent en permanence dans notre référentiel. Une fois créé et vivant. Par conséquent, ils sont nommés si succinctement.

C'est ainsi que nous vivons. Maintenant, nous sommes confortables, pratiques.

Train de sortie


Nous passons à nos processus de publication. Mais avant de parler des versions et de la façon dont nous les construisons, je vais parler des rôles que nous avons pour soutenir la version.

Nous avons un développeur en service qui, dans le cadre d'une semaine de travail, cesse de traiter les tâches du produit et corrige les bogues de la version actuelle. S'il n'a aucune tâche pour la version actuelle, il corrigera certaines dettes techniques que nous avons accumulées, prendra des tâches dans l'arriéré et les corrigera.

Il y a aussi un testeur en service. Il arrête également de tester les tâches du produit dans une semaine de travail et vérifie la version actuelle. S'il n'a pas de tâches pour la version actuelle, il teste ce qui a été corrigé dans le cadre de la dette technique.



La sortie commence vendredi. C'est ce jour-là que nous avons une date butoir. À 18 heures du soir, le testeur en service clique sur le bouton «Start Release». Après ce moment, tout ce qui sera versé dans develop ne tombera plus dans la version actuelle, car après avoir cliqué sur le bouton, une branche de release a été créée, develop a fusionné et plus n'y sera versé.

Un autre processus important a lieu vendredi, un autre élément de la version actuelle, dont je parlerai plus tard.



Nous nous reposons le week-end, donc le deuxième jour de sortie est lundi. Le développeur en service commence la journée par une analyse. Il examine ce qui a été changé dans la version actuelle en termes de code. Prend git diff entre la branche de publication actuelle et le master. Et par ce diff il regarde quels composants ont été affectés. Cela peut affecter le processus de paiement ou le panier, et le travail avec les piédestaux n'est pas affecté.

Ainsi, il forme une liste de différents cas qui seront testés lors des tests. Cela nous aide à accélérer notre régression, ne vérifiez pas la totalité de l'application. Lorsque la liste est compilée, l'équipe de test vérifie l'application et le développeur de service corrige les bogues. S'il a beaucoup de bogues, il peut déléguer une partie à d'autres développeurs qui ont récemment travaillé avec ces morceaux de code.



Mardi, nous continuons de tester notre version et de corriger les bogues de version. Vers l'après-midi, nos tests de régression se terminent et nous sommes prêts à partir pour la porte. Nous lançons notre train de versions - en fait, même plusieurs trains de versions, parce que nous avons récemment pénétré un nouveau marché pour nous. Je vous recommande également d'essayer de publier non seulement sur Google Play, mais aussi dans d'autres. Le plus n'est pas seulement que vous obtenez un nouveau public fidèle.

D'une manière ou d'une autre, nous avons publié notre version et après quelques heures, nous avons constaté que le nombre de bogues parmi les utilisateurs avait considérablement augmenté. Nous avons examiné ces bogues, les avons analysés et avons constaté qu'ils ne se produisent que sur les appareils Huawei. Nous n'avons pas immédiatement compris ce qui se passait, mais nous avions Huawei, nous les avons testés, trouvé un bug, corrigé et sommes allés mettre à jour.

Dès que nous sommes arrivés avec la mise à jour sur Google Play, nous avons vu une grande bannière qui disait qu'en raison de la situation actuelle dans le monde, Google Play a une très grande charge et ils n'ont pas le temps de vérifier les applications aussi rapidement que d'habitude. Il s'est avéré que nous n'avions pas encore le temps de vérifier notre application, nous n'avons pas atteint les utilisateurs de Google Play, mais avons été publiés uniquement dans la Huawei AppGallery. Et c'était la raison pour laquelle nous n'avions des bugs que sur Huawei. Ainsi, il était possible de détecter et de corriger un bogue critique avant même de publier sur Google Play.

Ensuite, je vais vous expliquer comment les publications sont organisées via Google Play, car nous avons une très grande proportion d'utilisateurs. Et chez Huawei AppGallery, nous sommes récemment partis et essayons toujours de comprendre comment tout y est organisé.

Nous ne publions pas immédiatement à tous les utilisateurs sur Google Play, de sorte qu'une sorte de bogue aléatoire n'affecte pas l'ensemble de notre public. Nous publions uniquement à tous les testeurs qui souscrivent au fait qu'ils peuvent avoir un bogue, mais ils seront les premiers à recevoir nos modifications et versions. De plus, nous ne publions que 5% de l'audience.



Mercredi, le développeur en service regarde une nouvelle version sans plantage. Il est important pour nous qu'il n'y ait pas de nouveau crash et qu'il n'y en ait pas beaucoup d'anciens. Si tout est normal, il vérifie toujours les métriques du produit. Par exemple, pour que le nombre de commandes ne baisse pas par rapport à la même période. Si nos mesures de produits et sans crash sont bonnes, nous déployons encore 5%, un total de 10%.



Jeudi, le développeur de garde vérifie les avis dans le magasin. En fait, il les regarde mercredi. Certes, mercredi, nous avons encore un petit public, une ou deux critiques. Mais jeudi, il y a plus de critiques pour juger de la sortie. Il peut y avoir 10 à 15 pièces.

Pourquoi regarde-t-il même les critiques si nous avons beaucoup de métriques et de graphiques? L'application peut ne pas se bloquer, même les mesures peuvent être correctes. Mais il est possible que l'utilisateur ait des polices ou qu'un filtre ne fonctionne pas pour lui. Nous essayons de rendre l'utilisation de l'application aussi pratique que possible pour l'utilisateur et analysons les critiques, les bugs ou les problèmes rencontrés par l'utilisateur.

Si les critiques sont en ordre, sans crash est également normal et les mesures de produit ne se sont pas affaissées, nous déployons déjà de 20%.



Et cela commence donc vendredi, le jour du lancement de notre version. Le troisième point dont je voulais parler est que vendredi nous terminerons la version actuelle. Nous passons immédiatement de 20% à 100%. Cela semble être un très grand saut et très risqué. Mais cela dépend de l'équipe et de votre public.

20% de notre audience nous permet avec une forte probabilité de juger de la stabilité de la sortie. Et si tout va bien de 20%, et vendredi nous n'avons pas vu de problème, alors nous irons directement au centième.

Je connais les équipes qui utilisent le piratage de la vie sur Google Play - peut-être qu'il vous aidera aussi. Vous pouvez déployer non pas à 100%, mais à 99,9%. Cela vous laissera un bouton sur Google Play pour arrêter de toute urgence la sortie. Et si vous déployez à 100%, ce bouton disparaît. Mais, comme je l'ai dit, par vingt pour cent de notre public, nous pouvons juger avec précision de la stabilité de la sortie. Par conséquent, nous déployons calmement à 100%, cela nous évite des étapes supplémentaires. Et puis vous devez rouler un autre 0,01%.

C'est notre processus, donc nous roulons chaque semaine et essayons de ne pas nous perdre.


Quels autres outils avons-nous pour soutenir la bonne vie de l'utilisateur de son côté? Il s'agit de Force Update, Soft Update et Feature Toggle.



Forcer la mise à jour - un mécanisme qui bloque l'utilisation de l'application si sa version est très obsolète. La version considérée comme obsolète est définie dans le panneau d'administration du serveur. Et dès que le numéro y aura changé, certaines applications auront une telle boîte qui ne vous laissera pas partir. Il n'y aura qu'un bouton Actualiser, l'utilisateur sera obligé de mettre à niveau.

Nous essayons d'utiliser ce mécanisme le moins possible, mais parfois c'est très important. Par exemple, si nous avons rompu la compatibilité descendante, déployé une nouvelle fonctionnalité qui n'est pas prise en charge dans l'ancien code. Ensuite, l'utilisateur de la version obsolète de l'application peut se retrouver dans un état incohérent. Il ira au panier, et par exemple, il n'aura pas de commande. Il ne comprendra pas pourquoi, bien que dans la nouvelle version toutes les erreurs soient enregistrées et il sera clair pourquoi il n'est pas possible de passer une commande.



Pour aider à forcer la mise à jour, il existe une mise à jour logicielle. Il s'agit d'une chose native de Google, qui est simplement intégrée à votre application et ne bloque pas l'utilisation. Mais elle dit - il y a une mise à jour sur Google Play, installez-la et vous aurez de nouveaux trucs sympas.

Initialement, il est mis en œuvre par un tel dialogue. Il s'agit d'un design natif d'Android. Et puis, il peut être intégré à votre application. Par exemple, nous l'avons implémenté dans notre widget «Mettre à jour l'application» dans notre jeu de couleurs.

La mise à jour logicielle nous a permis de réduire considérablement la queue des versions, et elle est implémentée simplement selon la documentation. Essayez-le si vous avez plusieurs versions.



Un autre outil important est la fonction Toggle. Il vous permet d'ajuster une partie des fonctionnalités côté utilisateur, en la modifiant dans le panneau d'administration. Il existe un ensemble de fonctionnalités que nous pouvons activer et désactiver à partir de notre serveur sans mises à jour d'application supplémentaires.

Parlons de la façon dont Feature Toggle fonctionne sur l'exemple d'une application tierce - un véhicule. Au départ, les développeurs ont juste un tel vélo, qui a déjà deux fonctionnalités: un moteur et une grande taille. Les clients utilisent le vélo, puis l'équipe de test dit: nous avons testé le moteur, il fonctionne, roule, refroidit, allumons-le pour l'utilisateur.



Nous allons dans le panneau d'administration, allumons la fonction Toggle et le vélo sans mettre à jour l'utilisateur, sur le pouce il se transforme en cyclomoteur. L'utilisateur est à l'aise, cela lui permet de se déplacer plus rapidement et plus confortablement.

Le produit se développe, le public grandit, il ne tient plus sur un cyclomoteur. Les utilisateurs veulent emporter une famille avec eux, rouler ensemble. Les développeurs et les gestionnaires ont fourni un basculement de fonctionnalité supplémentaire - une grande taille. Nous l'activons dans le panneau d'administration et le véhicule de l'utilisateur s'agrandit en déplacement.



Cela semble cool: la fonction Toggle nous aide. C'est vrai, mais vous pouvez rencontrer des problèmes. Par exemple, vous devez surveiller la compatibilité descendante et la compatibilité de basculement des fonctionnalités. Supposons qu'à un moment donné, l'application casse le moteur, qu'un crash ou un bug se produise. Ou ce moteur consommera beaucoup de nos ressources, et nous ne pourrons pas supporter trop d'utilisateurs avec le moteur. Ensuite, nous devons le désactiver.

Mais nous ne voulons pas que l'application de l'utilisateur disparaisse. Nous voulons lui donner la possibilité d'utiliser l'application, malgré le fait qu'il dispose toujours d'un Toggle de grande taille. Par conséquent, lorsque nous éteignons le moteur, nous devons avoir un mécanisme de secours pour contrôler le véhicule. Dans ce cas, c'est un tel hybride.



Peut-être valait-il la peine de considérer que le toit s'incline. Le conducteur sera peut-être mal à l'aise de s'asseoir sur un tel siège. Mais il pourra toujours conduire un véhicule, utiliser l'application et ne pas marcher.

Sinon, comment utiliser la fonction bascule de fonction Supposons que les backends sont toujours en cours de développement et ne sont pas prêts à être publiés. Ensuite, nous pouvons développer une partie de la fonctionnalité, prendre en charge le contrat API pour toutes les communications avec le backend, prendre en charge l'interface utilisateur et déployer avec le basculement de fonctionnalité désactivé. Dès que les backends seront prêts, nous testerons que tout fonctionne bien, et si c'est le cas, activez la fonction Toggle. Ensuite, l'utilisateur n'aura pas besoin d'être mis à jour pour obtenir de nouvelles fonctionnalités. Autrement dit, nous aurons déjà un public, nous apparaîtrons immédiatement dans ce public. Tellement génial aussi.



Maintenant, comme je l'ai déjà dit, nous avons 13 personnes dans chacune des équipes de développement Android et iOS. Nous travaillons sur un Git Flow, dans un référentiel, configurons notre processus de sortie prévu, réduisons le temps de mise sur le marché et roulons chaque semaine. Nous avons récemment publié Huawei AppGallery et regardons d'autres magasins. Nous avons appris à modifier les applications utilisateur sans mises à jour en raison du basculement des fonctionnalités. Merci pour l'attention.

All Articles