Situations typiques dans l'intégration continue

Vous avez étudié les commandes Git mais vous souhaitez comprendre comment s'effectue l'intégration continue (Continuous Integration, CI) dans la réalité ? Ou peut-être voulez-vous optimiser vos actions quotidiennes ? Ce cours vous donnera des compétences pratiques en intégration continue en utilisant un dépôt sur GitHub. Ce cours n'est pas conçu comme un wizard que l'on peut simplement cliquer ; au contraire, vous effectuerez les mêmes actions que les gens font réellement au travail, de la même manière qu'ils le font. J'expliquerai la théorie au fur et à mesure que vous progresserez à travers les étapes pertinentes.

Que allons-nous faire ?

Au fur et à mesure, nous allons progressivement créer une liste d'étapes type CI, ce qui est un excellent moyen de mémoriser cette liste. En d'autres termes, nous allons établir une liste des actions que les développeurs accomplissent lorsqu'ils mettent en œuvre l'intégration continue. Nous utiliserons également un ensemble simple de tests pour rapprocher notre processus CI de la réalité.

Ce GIF illustre schématiquement les commits dans votre dépôt au fur et à mesure que vous avancez dans le cours. Comme vous pouvez le voir, il n'y a rien de compliqué et seulement l'essentiel.

Situations typiques dans l'intégration continue

Vous aborderez des scénarios standards de CI :

  • Travailler sur une fonctionnalité ;
  • Appliquer des tests automatisés pour garantir la qualité ;
  • Réaliser une tâche prioritaire ;
  • Résoudre un conflit lors de la fusion de branches (merge conflict) ;
  • Survenir d'une erreur en production.

Que découvrirez-vous ?

Vous serez capable de répondre à des questions telles que :

  • Qu'est-ce que l'intégration continue (CI) ?
  • Quels types de tests automatisés sont utilisés lors de la CI, et en réponse à quelles actions sont-ils déclenchés ?
  • Qu'est-ce qu'une pull request et quand en a-t-on besoin ?
  • Qu'est-ce que le développement piloté par les tests (Test Driven Development, TDD) et comment cela se rapporte-t-il à la CI ?
  • Faut-il effectuer un merge ou appliquer les modifications par-dessus (rebase) ?
  • Doit-on annuler ou corriger dans la version suivante ?

Au début, j'ai traduit partout des choses comme 'pull request', mais j'ai finalement décidé de revenir à l'anglais dans certains cas pour réduire la folie du texte. Parfois, j'utiliserai un 'surgique de programmation' comme le charmant verbe 'committer' là où les gens l'utilisent réellement au travail.

Qu'est-ce que l'intégration continue ?

Intégration continue, ou CI, est une pratique technique consistant à ce que chaque membre de l'équipe intègre son code dans un référentiel commun au moins une fois par jour, le code résultant devant pouvoir être compilé sans erreurs.

Il existe des divergences d'interprétation concernant ce terme.

Le sujet de débat est la fréquence d'intégration. Certains affirment que ne fusionner le code qu'une fois par jour n'est pas suffisant et que l'intégration doit être continue. Un exemple est donné d'une équipe où chacun prend le code frais le matin et s'intègre une fois le soir. Bien que ce soit un argument raisonnable, il est généralement considéré que la définition "une fois par jour" est suffisamment pratique, précise, et adaptée aux équipes de différentes tailles.

Un autre argument est que C++ n'est plus le seul langage utilisé dans le développement, et que la simple exigence de compilation sans erreurs, comme moyen de validation, est faible. Un certain ensemble de tests (par exemple, des tests unitaires exécutés localement) doit également réussir. Actuellement, la communauté tend à ce que cette exigence soit obligatoire et, à l'avenir, "compilation + tests unitaires" deviendra probablement la norme, si cela n'est pas déjà le cas.

Intégration continue diffère de la livraison continue (Continuous Delivery, CD) en ce sens qu'elle ne nécessite pas de candidat à la version après chaque cycle d'intégration.

Voici la liste des étapes que nous allons utiliser tout au long du cours.

  1. Récupérer le dernier code. Créer une branche à partir de master. Commencer à travailler.
  2. Créer des commits sur votre nouvelle branche. Compiler et tester localement. Succès ? Passer à l'étape suivante. Échec ? Corriger les erreurs ou les tests et essayer à nouveau.
  3. Pousser vers votre référentiel distant ou branche distante.
  4. Créer une demande de fusion. Discuter des changements, ajouter d'autres commits au fur et à mesure de la discussion. Faire passer les tests sur la branche fonctionnalité.
  5. Fusionner/réébaser les commits depuis la branche principale. Faire passer les tests sur le résultat de la fusion.
  6. Déployer depuis la branche fonctionnalité en production.
  7. Si tout va bien en production pendant une certaine période, fusionner les changements dans la branche principale.

Situations typiques dans l'intégration continue

️ Préparation

Assurez-vous d'avoir le logiciel nécessaire.

Pour suivre ce cours, vous aurez besoin de Node.js et d'un client Git..

Vous pouvez utiliser n'importe quel client Git, mais je vais donner des commandes uniquement pour la ligne de commande.

Assurez-vous que vous avez un client Git installé qui prend en charge la ligne de commande.

Si vous n'avez pas encore installé de client Git qui supporte la ligne de commande, vous pouvez trouver des instructions d'installation. ici.

Préparer le référentiel.

Vous devrez créer une copie personnelle (fork) du référentiel modèle avec le code pour le cours sur GitHub. Convenons d'appeler cette copie personnelle le référentiel du cours..

Avez-vous terminé ? Si vous n'avez pas modifié les paramètres par défaut, votre dépôt de cours est probablement appelé continuous-integration-team-scenarios-students, il se trouve dans votre compte GitHub et l'URL ressemble à ceci

https://github.com//continuous-integration-team-scenarios-students

J'appellerai cette adresse simplement <URL репозитория>.

Les chevrons comme <тут> signifient que vous devez remplacer cette expression par la valeur correspondante.

Assurez-vous que GitHub actions sont activées pour ce dépôt de cours. Si elles ne sont pas activées, veuillez les activer en cliquant sur le gros bouton au milieu de la page, que vous pouvez atteindre en cliquant sur Actions dans l'interface GitHub.

Vous ne pourrez pas suivre le cours en suivant mes instructions si GitHub Actions n'est pas activé.

Situations typiques dans l'intégration continue

Vous pouvez toujours utiliser la capacité de GitHub à afficher le Markdown pour voir l'état actuel de la liste que nous écrivons ici

https://github.com//continuous-integration-team-scenarios-students/blob/master/ci.md

Concernant les réponses

Bien que la meilleure façon de terminer ce cours soit de tout faire vous-même, vous pourriez rencontrer des difficultés.

Si vous sentez que vous ne comprenez pas quoi faire et que vous ne pouvez pas continuer, vous pouvez jeter un coup d'œil à la branche solution, qui est dans votre dépôt de démarrage.
Veuillez ne pas fusionner solution dans master pendant le cours. Vous pouvez utiliser cette branche pour comprendre quoi faire, ou pour comparer votre code avec celui de l'auteur, en utilisant toutes les fonctionnalités que Git nous offre. Si vous êtes complètement perdu, vous pouvez complètement remplacer votre branche master par la branche solution et ensuite réinitialiser votre répertoire de travail à l'étape du cours dont vous avez besoin.

Utilisez cela uniquement si vous en avez vraiment besoin

Commitez votre code

git add .
git commit -m "Sauvegarde de mon travail"

Ces commandes

  • renomment master dans master-backup;
  • renomment solution dans master;
  • passent à la nouvelle branche master et réécrivent le contenu du répertoire de travail;
  • créent une branche "solution" à partir de "master" (qui était auparavant "solution") au cas où vous auriez besoin de la branche "solution" à l'avenir.

git branch -m master master-backup
git branch -m solution master
git checkout master -f
git branch solution

Après ces actions, vous pouvez utiliser git log master pour déterminer quel commit vous avez besoin.
Vous pouvez réinitialiser votre répertoire de travail à ce commit de cette manière :

git reset --hard

Si vous êtes satisfait du résultat, à un moment donné, vous aurez besoin de publier vos versions du dépôt dans un dépôt distant. N'oubliez pas de spécifier explicitement la branche distante lorsque vous le ferez.

git push --force origin master

Veuillez noter que nous utilisons git push --force. Vous ne voudrez probablement pas le faire souvent, mais nous avons ici un scénario très spécifique avec un utilisateur du dépôt qui comprend ce qu'il fait.

Commencer à travailler

Situations typiques dans l'intégration continue

Commençons à établir notre liste d'étapes CI. Normalement, vous commencez cette étape par l'extraction de la dernière version du code depuis le dépôt distant, mais nous n'avons pas encore de dépôt local, donc nous le clonons à partir du dépôt distant à la place.

️ Tâche : mettez à jour le dépôt local, créez une branche à partir de master, commencez à travailler

  1. Clonez le dépôt du cours de <URL репозитория>.
  2. Lancez npm install dans le répertoire du dépôt du cours ; nous en avons besoin pour l'installation de Jest, que nous utilisons pour exécuter des tests.
  3. Créez une branche et appelez-la feature. Changez de branche.
  4. Ajoutez le code de test dans ci.test.js entre les commentaires demandant de le faire.

    it('1. extraire le dernier code', () => {
      expect(/.*pull.*/ig.test(fileContents)).toBe(true);
    });
    
    it('2. ajouter des commits', () => {
      expect(/.*commit.*/ig.test(fileContents)).toBe(true);
    });
    
    it('3. pousser vers la branche distante avec le même nom', () => {
      expect(/.*push.*/ig.test(fileContents)).toBe(true);
    });
    
    it('4. créer une demande de tirage et continuer à travailler', () => {
      expect(/.*pulls+request.*/ig.test(fileContents)).toBe(true);
    });

  5. Ajoutez le texte avec les 4 premières étapes dans le fichier ci.md.
    1. Récupérer le dernier code. Créez une branche à partir de `master`. Commencez à travailler.    
    2. Créez des commits sur votre nouvelle branche. Construisez et testez localement.  
    Passé ? Passer à l'étape suivante. Échoué ? Corrigez les erreurs ou les tests et réessayez.  
    3. Poussez vers votre dépôt distant ou votre branche distante.  
    4. Créez une demande de tirage. Discutez des changements, ajoutez plus de commits  
    alors que la discussion continue. Faites passer les tests sur la branche de fonctionnalité.  

    Commandes

# Клонируйте репозиторий курса
git clone <repository URL>
cd <repository name>

# Выполните npm install в каталоге репозитория курса; он установит Jest, который мы используем для запуска тестов.
npm install

# Создайте ветку и назовите ее feature. Переключитесь на эту в ветку.
git checkout -b feature

# Отредактируйте ci.test.js как описано выше.
# Отредактируйте ci.md как описано выше

Créez des commits sur la nouvelle branche, construisez et testez localement.

Nous allons configurer les tests pour qu'ils s'exécutent avant chaque commit, puis commettre le code.

Scénarios typiques où les tests s'exécutent automatiquement

  • Localement :
    • Constamment ou en réponse à des modifications pertinentes du code ;
    • À la sauvegarde (pour les langages interprétés ou JIT-compilés) ;
    • Lors de la construction (lorsque la compilation est nécessaire) ;
    • Lors du commit ;
    • Lors de la publication dans un dépôt public.

  • Sur le serveur de construction ou dans l'environnement de construction :
    • Lorsque le code est publié dans une branche / dépôt personnel.
    • Le code est testé dans cette branche.
    • Le résultat potentiel de la fusion est testé (généralement avec master).
    • En tant qu'étape d'intégration continue / de pipeline de déploiement continu

En général, plus un ensemble de tests s'exécute rapidement, plus vous pouvez vous permettre de le lancer fréquemment. Une distribution typique des étapes pourrait ressembler à cela.

  • Tests unitaires rapides - lors de la compilation, dans le pipeline CI
  • Tests unitaires lents, tests de composants et tests d'intégration rapides - lors de la validation, dans le pipeline CI
  • Tests de composants et tests d'intégration lents - dans le pipeline CI
  • Tests de sécurité, tests de charge et autres tests longs ou coûteux - dans les pipelines CI/CD, mais seulement dans certains modes/étapes/pipelines de construction, par exemple, lors de la préparation d'un candidat de version ou lors d'un lancement manuel.

️ Tâche

Je propose de commencer par exécuter les tests manuellement en utilisant la commande npm test. Ensuite, ajoutons un hook git pour exécuter nos tests lors de la validation. Il y a un petit problème : les hooks Git ne font pas partie du dépôt et ne peuvent donc pas être clonés depuis GitHub avec les autres matériaux du cours. Pour installer le hook, vous devez exécuter install_hook.sh ou copier le fichier repo/hooks/pre-commit dans le répertoire local .git/hooks/.
Lors de la validation, vous verrez que les tests sont exécutés et qu'ils vérifient la présence de certains mots-clés dans la liste.

  1. Exécutez les tests manuellement en exécutant la commande npm test dans le répertoire de votre cours. Assurez-vous que les tests ont été exécutés.
  2. Installez le hook de validation (hook pre-commit) en exécutant install_hook.sh.
  3. Validez les changements dans le dépôt local.
  4. Assurez-vous que les tests s'exécutent avant la validation.

Votre dépôt doit ressembler à cela après avoir effectué ces actions.
Situations typiques dans l'intégration continue

Commandes

# Установите pre-commit hook выполнив install_hook.sh.  

# Закоммитьте изменения в локальный репозиторий. Используйте "Add first CI steps" в качестве сообщения при коммите.
git add ci.md ci.test.js
git commit -m "Add first CI steps"

# Убедитесь, что тесты запускаются перед коммитом.  

Publiez le code dans un dépôt distant ou une branche distante

Après avoir terminé le travail en local, les développeurs rendent généralement leur code public afin qu'il puisse finalement être intégré au commun. Avec GitHub, cela se fait généralement par la publication du travail dans une copie personnelle du dépôt (fork personnel) ou dans une branche personnelle.

  • Lors de l'utilisation de forks, le développeur clone un dépôt distant public, créant ainsi sa propre copie éloignée, également connue sous le nom de fork. Ensuite, il clone ce dépôt personnel pour travailler avec localement. Une fois le travail terminé et les commits effectués, il les place dans son fork, où ils sont accessibles aux autres et peuvent être intégrés dans le dépôt principal. Cette approche est généralement utilisée dans des projets open source sur GitHub. Elle est également utilisée dans mon cours avancé [Team Work and CI with Git]http://devops.redpill.solutions/).
  • Une autre approche consiste à utiliser un seul dépôt distant et à considérer uniquement la branche master du dépôt partagé comme "protéger". Dans ce scénario, les développeurs individuels publient leur code dans les branches du dépôt distant afin que les autres puissent consulter ce code, et si tout est en ordre, l'incorporer dans master le dépôt principal.

Dans ce cours spécifique, nous allons utiliser un flux de travail basé sur des branches.

Publions notre code.

️ Tâche

  • Publiez les modifications dans une branche distante portant le même nom que votre branche de travail

Commandes

git push --set-upstream origin feature

Créez une demande de tirage

Créez une demande de tirage avec le titre Étapes de révision. Définissez feature comme "branche source" et master comme "branche de destination".

Assurez-vous que vous avez défini master dans son le fork du dépôt comme "branche de destination", je ne vais pas accepter de demandes de modifications dans le dépôt contenant les matériaux du cours.

Dans le jargon de GitHub, "branche de destination" est la branche sur laquelle vous basez votre travail, et "branche source" est la branche contenant les modifications proposées.

Discutez des modifications, ajoutez de nouveaux commits au fur et à mesure que la discussion se poursuit

La demande de tirage (PR)

La demande de tirage (PR) est un moyen de discuter et de documenter le code, ainsi que d'effectuer une révision de code. Les demandes de tirage sont nommées d'après la manière générale d'intégrer des modifications individuelles dans le code principal. En général, une personne clone le dépôt officiel distant du projet et travaille sur le code localement. Ensuite, elle place le code dans son propre dépôt distant personnel et demande aux responsables du dépôt officiel de récupérerpull) son code dans leurs dépôts locaux, où ils l'examinent et, éventuellement, l'intègrentfusionner) cela. Ce concept est également connu sous d'autres noms, par exemple, demande de fusion.

En réalité, vous n'êtes pas obligé d'utiliser la fonction pull request de GitHub ou d'autres plateformes similaires. Les équipes de développement peuvent utiliser d'autres moyens de communication, y compris des discussions en personne, des appels vocaux ou des courriels, mais il y a néanmoins plusieurs raisons d'utiliser ces pull requests dans un style de discussion de forum. Voici quelques-unes d'entre elles :

  • discussions organisées concernant des modifications spécifiques du code ;
  • comme un lieu pour examiner les retours sur le travail inachevé, tant des tests automatisés que des collègues ;
  • formalisation des vérifications de code ;
  • pour pouvoir plus tard clarifier les raisons et les considérations derrière un morceau de code particulier.

En général, vous créez une pull request lorsque vous avez besoin de discuter quelque chose ou d'obtenir des retours. Par exemple, si vous travaillez sur une fonctionnalité qui peut être mise en œuvre de plusieurs manières, vous pourriez créer une demande de modification même avant d'avoir écrit la première ligne de code, afin de partager vos idées et de discuter de vos plans avec vos co-auteurs. Si le travail est plus simple, la pull request est ouverte quand quelque chose est déjà terminé, enregistré et peut être discuté. Dans certains scénarios, vous pouvez ouvrir un PR uniquement pour des raisons de contrôle qualité : pour exécuter des tests automatisés ou initier une vérification de code. Quoi que vous décidiez, n'oubliez pas de @mentionner les personnes dont l'approbation est requise dans votre pull request.

Habituellement, lors de la création d'un PR, vous faites ce qui suit.

  • Indiquez ce que vous proposez de modifier et où.
  • Rédigez une description expliquant l'objectif des modifications. Vous pouvez vouloir :
    • ajouter des éléments importants qui ne sont pas évidents dans le code, ou quelque chose d'utile pour comprendre le contexte, comme des #bugs pertinents et des numéros de commits ;
    • @mentionner toutes les personnes avec qui vous souhaitez travailler ensemble, ou vous pouvez les @mentionner dans les commentaires plus tard ;
    • demander à des collègues de vous aider avec quelque chose ou de vérifier un point spécifique.

Après que vous ayez ouvert le PR, des tests configurés pour s'exécuter dans de tels cas sont effectués. Dans notre cas, ce sera le même ensemble de tests que nous avons exécutés localement, mais dans un projet réel, il peut y avoir des tests et des vérifications supplémentaires.

Veuillez patienter jusqu'à ce que les tests soient terminés. Vous pouvez voir l'état des tests en bas de la discussion PR dans l'interface GitHub. Continuez une fois que les tests sont finis.

️ Ajoutez une remarque sur l'arbitraire de la liste des étapes CI

La liste utilisée dans ce cours est arbitraire et subjective, nous devons ajouter une note à ce sujet.

️ Tâche : créer une pull request pour cette annotation

  1. Changez de branche master.
  2. Créez une branche nommée bugfix.
  3. Ajoutez le texte de l'annotation à la fin du fichier ci.md.
    > **GitHub flow** est parfois utilisé comme un surnom pour désigner une variante de développement basé sur le tronc  
    quand le code est déployé directement à partir des branches de fonctionnalités. Cette liste n'est qu'une interprétation  
    que j'utilise dans mes [cours DevOps](http://redpill.solutions).  
    Le tutoriel officiel est [ici](https://guides.github.com/introduction/flow/).
  4. Commitez les modifications.
  5. Publiez la branche bugfix dans le dépôt distant.
  6. Créez une pull request nommée Ajout d'une remarque avec la branche principale bugfix et la branche de basemaster.

Assurez-vous que vous avez défini master dans son le fork du dépôt comme "branche de destination", je ne vais pas accepter de demandes de modifications dans le dépôt contenant les matériaux du cours.

Voici à quoi doit ressembler votre dépôt.
Situations typiques dans l'intégration continue

Commandes

# Переключитесь на ветку master. Создайте ветку bugfix.
git checkout master

# Создайте ветку bugfix-remark.
git checkout -b bugfix

# Добавьте текст примечания внизу ci.md.

# Закоммитьте изменения
git add ci.md
git commit -m "Add a remark about the list being opinionated"

# Опубликуйте ветку bugfix в удалённый репозиторий.
git push --set-upstream origin bugfix

# Создайте pull request при помощи интерфейса GitHub как описано выше

Approuvez la pull request "Ajout d'une remarque"

️ Tâche

  1. Créez une pull request.
  2. Cliquez sur "Fusionner la pull request".
  3. Cliquez sur "Confirmer la fusion".
  4. Cliquez sur "Supprimer la branche", elle n'est plus nécessaire.

Voici le diagramme des commits après la fusion.
Situations typiques dans l'intégration continue

️ Continuez à travailler et ajoutez des tests

La collaboration sur une pull request entraîne souvent la nécessité de travaux supplémentaires. Cela résulte généralement de la révision de code ou des discussions, mais dans notre cours, nous allons simuler cela en ajoutant de nouveaux éléments à notre liste d'étapes CI.

En intégration continue, un certain niveau de couverture de tests est généralement appliqué. Les exigences de couverture de tests varient et se trouvent généralement dans un document intitulé "guides pour les auteurs" (contribution guidelines). Nous allons faire simple et ajouter un test pour chaque ligne de notre liste de contrôle.

Lors de l'exécution des tâches, essayez d'abord de commettre les tests. Si vous avez correctement configuré le pre-commit hook auparavant, le test nouvellement ajouté sera exécuté, ne passera pas, et rien ne sera commis. Notez que c'est ainsi que nous savons que nos tests vérifient réellement quelque chose. Curieusement, si nous avions commencé avec le code avant les tests, le passage des tests aurait pu signifier soit que le code fonctionne comme prévu, soit que les tests ne vérifient en fait rien. De plus, si nous n'avions pas écrit de tests en premier lieu, nous pourrions même les oublier, car rien ne nous en rappellerait.

Développement par test (TDD)

Le TDD recommande d'écrire des tests avant le code. Le processus de travail typique utilisant le TDD se déroule comme suit.

  1. Ajoutez un test.
  2. Exécutez tous les tests et assurez-vous que le nouveau test échoue.
  3. Écrivez le code.
  4. Exécutez les tests, assurez-vous que tous les tests passent.
  5. Effectuez une refactorisation du code.
  6. Répétez.

Étant donné que les résultats des tests qui échouent s'affichent généralement en rouge, et ceux qui réussissent en vert, ce cycle est également connu sous le nom de 'rouge-vert-refactorisation'.

️ Tâche

Essayez d'abord de valider les tests et laissez-les échouer, puis ajoutez et validez le texte de la liste des étapes CI. Vous verrez que les tests passent ('verts').
Ensuite, publiez le nouveau code dans le dépôt distant et regardez comment les tests s'exécutent dans l'interface GitHub en bas de la discussion de la demande de tirage, et le statut PR se met à jour.

  1. Changez de branche feature.
  2. Ajoutez ces tests dans ci.test.js après le dernier appel it (...);.

    it('5. Fusionner/rébaser les commits à partir de master. Faire passer les tests sur le résultat de la fusion.', () => {
      expect(/.*merge.*commits.*testss+pass.*/ig.test(fileContents)).toBe(true);
    });
    
    it('6. Déployer de la branche fonctionnelle en production.', () => {
      expect(/.*Deploy.*tos+production.*/ig.test(fileContents)).toBe(true);
    });
    
    it('7. Si tout va bien en production pendant un certain temps, fusionner les changements avec master.', () => {
      expect(/.*merge.*tos+master.*/ig.test(fileContents)).toBe(true);
    });

  3. Essayez de valider les tests. Si pre-commit hook est installé, la tentative de validation échouera.
  4. Ajoutez ensuite ce texte dans ci.md.
    5. Fusionner/rébaser les commits à partir de master. Faire passer les tests sur le résultat de la fusion.  
    6. Déployer de la branche fonctionnelle avec un bug furtif en production.
    7. Si tout va bien en production pendant un certain temps, fusionner les changements avec master. 
  5. Apportez et validez les modifications localement.
  6. Publiez les modifications sur la branche feature.

Vous devriez maintenant avoir quelque chose comme ça
Situations typiques dans l'intégration continue

Commandes


# Переключительна ветку feature
git checkout feature

# Добавить тесты в ci.test.js как описано выше

# Добавьте в индекс ci.test.js чтобы позже закоммитить
git add ci.test.js

# Попытайтесь закоммитить тесты. Если pre-commit hook установлены, коммит не произойдёт.
git commit

# Теперь добавьте текст в ci.md как описано выше

# Внесите изменения и закоммитьте их
git add ci.md
git commit -m "Add the remaining CI steps"

# Опубликуйте изменения в ветку feature
git push

Conflit de fusion

Accédez à la demande de tirage Étapes de révision.

Bien que nous n'ayons rien fait de mal et que les tests de notre code aient réussi, nous ne pouvons toujours pas fusionner la branche. feature et masterC'est parce qu'une autre branche bugfix a été fusionnée avec master pendant que nous travaillions sur cette PR.
Cela crée une situation où la branche distante master a une version plus récente que celle sur laquelle nous avons basé la branche. featureEn raison de cela, nous ne pouvons pas simplement faire reculer HEAD master jusqu'à la fin de la branche. featureDans cette situation, nous devons soit fusionner, soit appliquer les commits feature par-dessus. masterGitHub peut en fait effectuer des fusions automatiques s'il n'y a pas de conflits. Malheureusement, dans notre situation, les deux branches ont des modifications concurrentes dans le fichier. ci.mdCette situation est connue sous le nom de conflit de fusion, et nous devons la résoudre manuellement.

Fusion ou rebase

Fusion

  • Crée un commit de fusion supplémentaire et préserve l'historique des modifications.
    • Préserve les commits d'origine des branches avec leurs horodatages et auteurs d'origine.
    • Conserve les SHA des commits et les références dans les discussions sur les demandes de tirage.
  • Nécessite une résolution unique des conflits.
  • Rend l'historique non linéaire.
    • L'historique peut être difficile à lire en raison du grand nombre de branches (rappelant un câble IDE).
    • Complique le débogage automatique, par exemple, rend git bisect moins utile — il ne trouvera qu'un commit de fusion.

Rebase

  • Reproduit les commits de la branche actuelle au-dessus de la base un par un.
    • De nouveaux commits avec de nouveaux SHA sont créés, ce qui entraîne que les commits dans GitHub correspondent aux demandes de tirage d'origine, mais pas aux commentaires associés.
    • Les commits peuvent être recombinés et modifiés au cours du processus ou même fusionnés en un seul.
  • Il peut être nécessaire de résoudre plusieurs conflits.
  • Permet de maintenir un historique linéaire.
    • L'historique peut être plus facile à lire, à condition qu'il ne soit pas trop long sans raison valable.
    • Le débogage automatique et la résolution des problèmes sont un peu plus simples : cela rend possibles git bisect, peut rendre les retours automatiques plus clairs et prévisibles.
  • Exige la publication de la branche avec les commits transférés en utilisant le drapeau --force lors de l'utilisation avec des demandes de modification.

En général, les équipes s'accordent à utiliser toujours la même stratégie lorsqu'elles doivent fusionner des modifications. Cela peut être une fusion "propre" ou une application "propre" des commits par dessus, ou quelque chose d'intermédiaire, comme effectuer l'application des commits en mode interactif (git rebase -i) localement pour des branches non publiées dans le dépôt partagé, mais fusionne pour les branches "publiques".

Ici nous allons utiliser la fusion.

️ Tâche

  1. Assurez-vous que le code dans la branche locale master est à jour depuis le dépôt distant.
  2. Changez de branche feature.
  3. Initiez la fusion avec la branche master. Un conflit de fusion lié à des modifications concurrentes sera signalé. ci.md.
  4. Résolvez le conflit de manière à ce que notre liste d'étapes CI et sa remarque soient toutes deux présentes dans le texte.
  5. Publiez le commit de fusion dans la branche distante. feature.
  6. Vérifiez l'état de la demande de tirage dans l'interface utilisateur de GitHub, attendez que la fusion soit résolue.

Commandes

# Убедитесь, что код в локальное ветке `master` обновлён из удалённого репозитория.
git checkout master
git pull

# Переключитесь на ветку feature
git checkout feature

# Инициируйте слияние с веткой master 
git merge master

# A merge conflict related to concurrent changes to ci.md will be reported
# => Auto-merging ci.md
#    CONFLICT (content): Merge conflict in ci.md
#    Automatic merge failed; fix conflicts and then commit the result.

# Разрешите конфликт так, чтобы и наш список шагов CI, и замечание о нем остались в тексте.
# отредактируйте ci.md чтоб он не содержал маркеров конфликта слияния
git add ci.md
git merge --continue
# при коммите можете оставить сообщение по умолчанию

# Опубликуйте коммит слияния в удаленную ветку feature.
git push

# Проверьте статус запроса на изменения в пользовательском интерфейсе GitHub, дождитесь пока слияние не будет разрешено.

Excellent travail !

Vous avez terminé de travailler sur la liste, et maintenant vous devez approuver la demande de tirage dans master.

️ Tâche : Approuvez la demande de tirage "Revue des étapes".

  1. Ouvrez la demande de tirage.
  2. Cliquez sur "Fusionner la pull request".
  3. Cliquez sur "Confirmer la fusion".
  4. Cliquez sur "Supprimer la branche", car elle n'est plus nécessaire.

Voici votre dépôt en ce moment.
Situations typiques dans l'intégration continue

Erreur en production.

On dit que « les tests peuvent être utilisés pour montrer la présence d'erreurs, mais jamais pour montrer leur absence ». Bien que nous ayons eu des tests, et qu'ils ne nous aient pas signalé d'erreurs, une erreur sournoise s'est glissée en production.

Dans un tel scénario, nous devons nous occuper de :

  • ce qui est déployé en production ;
  • le code dans la branche master avec l'erreur à partir de laquelle les développeurs peuvent commencer de nouveaux travaux.

Rollback ou correction dans la prochaine version ?

"Rollback" (retour en arrière) est le déploiement d'une version antérieure supposément saine dans l'environnement de production et l'annulation (revert) des commits contenant l'erreur. "Correction dans la prochaine version" (fixing forward) est l'ajout d'un correctif dans master et le déploiement d'une nouvelle version dès que possible. Étant donné que les APIs et les schémas de bases de données changent au fur et à mesure que le code est déployé dans l'environnement de production, dans la livraison continue et avec une bonne couverture de tests, le rollback est généralement beaucoup plus complexe et risqué que la correction dans la prochaine version.

Étant donné que le rollback ne représente dans notre cas aucun risque, nous allons procéder par cette voie, car cela nous permet

  • de corriger l'erreur en production aussi rapidement que possible ;
  • de rendre le code dans master immédiatement prêt à commencer de nouveaux travaux.

️ Tâche

  1. Changez de branche master localement.
  2. Mettez à jour le dépôt local à partir du dépôt distant.
  3. Annulez le commit de fusion de PR. Étapes de révision dans master.
  4. Publiez les modifications dans le dépôt distant.

Voici l'historique du dépôt avec le commit de fusion annulé.
Situations typiques dans l'intégration continue

Commandes

# Переключитесь на ветку master.
git checkout master

# Обновите локальный репозиторий из удалённого репозитория.
git pull

# Отмените коммит слияния PR Steps review в master.
# Мы отменяем коммит слияния, поэтому нам нужно выбрать ветку истории, которую мы захотим оставить
git show HEAD

# предположим, что коммит, который был последним в ветке master до слияния, был отображён предыдущей командой первым
git revert HEAD -m 1
# можете не менять сообщения коммитов

# Опубликуйте изменения в удалённый репозиторий
git push

️ Auto-vérification.

Assurez-vous que ci.md ne contient plus le texte "sneaky bug" après l'annulation du commit de fusion.

Corrigez la liste d'étapes CI et renvoyez-la dans master.

Nous avons complètement annulé le commit de fusion de la branche feature. La bonne nouvelle est qu'il n'y a maintenant plus d'erreur dans masterLa mauvaise nouvelle est que notre précieuse liste des étapes d'intégration continue a disparu. Idéalement, nous devons appliquer la correction aux commits de feature et les ramener dans master avec la correction.

Nous pouvons aborder la tâche de différentes manières :

  • annuler (revert) un commit qui annule la fusion feature avec master;
  • déplacer les commits de l'ancienne feature.

Différentes équipes de développeurs utilisent des approches variées dans ce cas, nous allons déplacer les commits utiles dans une nouvelle branche et créer une demande de tirage séparée pour cette nouvelle branche.

️ Tâche

  1. Créez une branche nommée feature-fix et commutez dessus.
  2. Déplacez tous les commits de l'ancienne branche feature vers la nouvelle branche. Résolvez les conflits de fusion qui sont survenus lors du déplacement.

    Situations typiques dans l'intégration continue

  3. Ajoutez un test de régression dans ci.test.js:

    it('does not contain the sneaky bug', () => {
    expect(/.*sneakys+bug.*/gi.test(fileContents)).toBe(false);
    });

  4. Exécutez les tests localement pour vous assurer qu'ils ne réussissent pas.
  5. Supprimez le texte " with a sneaky bug" dans ci.md.
  6. Ajoutez les modifications des tests et les modifications de la liste des étapes à l'index et validez-les.
  7. Publiez la branche dans le dépôt distant.

Vous devriez obtenir quelque chose qui ressemble à ceci
Situations typiques dans l'intégration continue

Commandes

# Создайте ветку под названием feature-fix и переключитесь на нее.
git checkout -b feature-fix

# Перенесите все коммиты из бывшей ветки feature в новую ветку. Разрешите конфликты слияния, которые возникли при переносе.
# используйте историю чтобы узнать хэши коммитов:
# - предшествующего коммиту с первой частью списка: C0
# - добавляющего последние элементы списка: C2
git log --oneline --graph
git cherry-pick C0..C2
# разрешите конфликты слияния
# - отредактируйте ci.md и/или ci.test.js
# - добавьте файлы в индекс
# - выполните "git cherry-pick --continue", можете не менять сообщение коммита

# Добавьте регрессионный тест в ci.test.js
# Запустите тесты локально, чтобы убедиться, что они не завершаются успешно.

# Удалите текст " with a sneaky bug" в ci.md.

# Добавьте в индекс изменения тестов и в списке шагов и закоммитьте их.
git add ci.md ci.test.js
git commit -m "Fix the bug in steps list"

# Опубликуйте ветку в удалённый репозиторий.
git push --set-upstream origin feature-fix

Créez une pull request.

Créez une demande de tirage avec le titre Fixing the feature. Définissez feature-fix comme "head branch", et master comme "branche de destination".
Veuillez attendre la fin des tests. Vous pouvez voir l'état des tests en bas de la discussion PR.

Assurez-vous que vous avez défini master dans son le fork du dépôt comme "branche de destination", je ne vais pas accepter de demandes de modifications dans le dépôt contenant les matériaux du cours.

Approuvez la demande de tirage "Fixing the feature"

Merci pour la correction ! Veuillez approuver les modifications dans master de la demande de tirage.

️ Tâche

  1. Cliquez sur "Fusionner la pull request".
  2. Cliquez sur "Confirmer la fusion".
  3. Cliquez sur "Supprimer la branche", car elle n'est plus nécessaire.

C'est ce que vous devriez avoir à ce moment-là
Situations typiques dans l'intégration continue

Félicitations !

Vous avez exécuté toutes les actions que les gens effectuent généralement dans le processus d'intégration continue.

Si vous rencontrez des problèmes avec le cours ou avez des suggestions d'amélioration, créez un problème dans le dépôt du matériel du cours. Ce cours a également une version interactive utilisant GitHub Learning Lab comme plateforme.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster