Intégration et déploiement continu d’un projet IT avec Jira Software et Bitbucket Cloud

adminNon classifié(e)

Intégration et déploiement continu d’un projet IT avec Jira Software et Bitbucket Cloud

Suite à notre atelier en ligne, vous allez (re)découvrir un cas d’usage concret de Jira Software Cloud et Bitbucket Cloud pour la gestion et le développement d’un projet d’une application IT avec cet article. En reliant Jira Software Cloud et Bitbucket Cloud vous allez découvrir la puissance de la combinaison des deux outils dans l’Intégration Continue (build) et le Déploiement Continu (deploy) pour gérer, suivre, tester et optimiser vos projets et développements informatiques.

Avec cet article, vous allez apprendre comment simplement :

  1. configurer et utiliser Jira Software Cloud pour gérer et suivre le déroulement d’un projet IT par un exemple d’usage concret,
  2. lier vos tickets dans Jira Software Cloud et votre code source dans Bitbucket Cloud pour facilement suivre vos développements informatiques,
  3. exécuter un contrôle de la qualité du code produit au moment build de votre projet IT avec Bitbucket Pipelines,
  4. exécuter des tests unitaires au moment build de votre projet IT avec Bitbucket Pipelines.
  5. déployer vos binaires issues du build avec une configuration dans Bitbucket Pipelines.

_scroll_external/attachments/devops-loop-illustrations-161260fac3d4954935a26f9619bcffbc9dfad5e6e9aa91127adbb61158d87c0c.pngCI/CD : Définition et Concepts clés

CI = Continuous Integration / CD = Continuous Deployment

CI : Intégration continue

Définition de l’Intégration Continue (Continuous Integration) : ensemble de pratiques utilisées en génie logiciel consistant à vérifier à chaque modification de code source que le résultat des modifications ne produit pas de régression dans l’application développée. Elle repose souvent sur la mise en place d’une brique logicielle permettant l’automatisation de tâches : compilation, tests unitaires et fonctionnels, validation produit, tests de performances… À chaque changement du code, cette brique logicielle va exécuter un ensemble de tâches et produire un ensemble de résultats, que le développeur peut par la suite consulter

Les éléments clés de l’Intégration Continue :

  • Intégration continue = compiler le projet dès qu’une modification est apportée
  • Intégrer systématiquement les changements de code dans la branche principale d’un dépôt
  • Tester les changements le plus rapidement et le plus souvent possible
  • Intégrer le code produit quotidiennement, voire plusieurs fois par jour
  • Renforcer l’agilité
  • Créer de l’engagement fort de la part d’une équipe

Les avantages de l’Intégration Continue :

  • Accélérer le feedback sur les changements de code
  • Renforcer la qualité du code produit
  • Améliorer la productivité d’une équipe
  • Faciliter l’automatisation des tests
  • Obtenir des indicateurs de suivi fiables

_scroll_external/attachments/image2021-5-10_8-57-32-183075d3b1e63ee5cac3fd2562f439391758c647598d6536c977df1a235550d6.png

CD : Déploiement continu

Définition du Déploiement Continu (Continuous Deployment) : approche d’ingénierie logicielle dans laquelle les fonctionnalités logicielles sont livrées fréquemment par le biais de déploiements automatisés. Elle nécessite aucune évaluation ni vérification manuelle des changements de code dans l’environnement de test, puisque les tests automatisés sont intégrés très tôt dans le processus de développement et se poursuivent tout au long des phases du lancement. On parle de livraison continue lorsque les développeurs livrent souvent et de manière régulière du nouveau code à tester aux équipes de l’assurance qualité (QA) et de l’exploitation.

Les éléments clés du Déploiement Continu :

  • Automatiser les étapes de livraison, tout environnement confondus (dev, integration, production)
  • Déploiement automatisé robuste et fiable
  • Nécessite l’Intégration continue pour automatiser la production des livrables (build)
  • Pousse la pratique DevOps à son extrême logique
  • Offrir de nouvelles fonctionnalités à vos utilisateurs finaux et testeurs internes

Les avantages du Déploiement Continu :

  • Donner de la visibilité sur ce qui est développé
  • Permettre des tests d’interface sur les développements en cours
  • Accélérer les feedbacks et la remonter de bugs
  • Soulager l’équipe en charge des livraisons
  • Automatiser les livraisons (même en Production !)
  • Augmentation de la qualité des logiciels

 

_scroll_external/attachments/image2021-5-10_9-2-44-1c651196f6ed6914f0397c285afcc1948119a76872d48e9d0af06dbaadec9868.png

_scroll_external/attachments/image2021-5-10_9-4-1-2589970ea0433efe56a0a2d7b9c373ee1b218e41d4d48d0d3e274f5801be5e7d.png

Le contexte de cette démonstration

Le projet IT est un projet simple comprenant 2 classes JAVA : HelloWorld.java et Calculation.java. On se focalise ici sur la configuration des outils et pas le code projet en lui-même. Les deux produits Atlassian Cloud utilisés :

  • Jira Software Cloud : projet Jira Cloud = WORKSHOP-CI-CD
  • Bitbucket Cloud : répertoire de code Bitbucket Cloud = demo-workshop-ci-cd-java

Les implémentations Jira Software Cloud :

  • Un projet simple de gestion des tâches
  • Un tableau de suivi des tâches Kanban avec un statut personnalisé
  • Un changement de statut automatique au commit de code : De l’état TO DO vers IN PROGRESS
  • Lien avec Bitbucket Cloud pour suivre les builds et les deployments directement dans Jira Software Cloud

Les implémentations Bitbucket Cloud :

  • Répertoire de code source GIT
  • Bitbucket Pipelines pour construire le binaire JAVA avec MAVEN
  • Bitbucket Pipelines pour exécuter les tests unitaires avec JUNIT
  • Bitbucket Pipelines pour contrôler le code avec CHECKSTYLE
  • Bitbucket Pipelines pour déployer le binaire JAVA dans un gestionnaire de dépôt de binaires avec JFROG
  • Un déploiement automatique pour Test
  • Un déploiement manuel pour la Production (sans tag)
  • Lien avec Jira Software Cloud

_scroll_external/attachments/image2021-5-10_9-6-2-4f58d5b70b7b12f481544ee8b010b618c1f82291def5c871799b20ab50cdba82.png

Construire la partition…

Première étape : commençons par Jira Software Cloud

Le workflow du projet

Rien de spécial ici, on a simplement ajouté un état « In Review » au workflow de base fournit par Jira Software Cloud à la création d’un projet de type Kanban.

En savoir plus sur les workflows.

_scroll_external/attachments/image2021-5-10_9-17-41-3d5f9e3a0891c3fde56957bf3ef991ee0734e858ce47174076e5d655d7987d4b.png

Le trigger magique

On a ajouté un trigger sur la transition globale « In Progress » : au commit de code sur Bitbucket, la demande chargera d’état pour aller sur « In Progress », très pratique. À vous d’imaginer les possibilités sur votre workflow personnalisé !

En savoir plus sur les triggers.

_scroll_external/attachments/image2021-5-10_9-18-57-ac0d69b585b5bb518a76b72619c82a619efc7f95fa24e9d8d93727d51a11c889.png

Le lien Jira Cloud <> Bitbucket Cloud

En reliant les deux outils, la puissance est entre vos mains. Depuis Jira Software Cloud vous aller pouvoir constater des éléments dans Bitbucket Cloud et inversement. L’intégration est extrêmement forte et intuitive, vous allez être surpris !

En savoir plus sur le lien Jira Cloud <> Bitbucket Cloud.

_scroll_external/attachments/image2021-5-10_9-20-41-f8bc98759c777b61a9053e8a7d224a4cc781e0f8f6918d55a1a224c6dacdb0b7.png

Seconde étape : Bitbucket Cloud

La création d’un répertoire de code source sur Bitbucket Cloud est la première étape, il permettra de stocker notre code source Java.

Créer un répertoire de code (dépôt) vide

  1. Cliquez sur + dans la barre latérale globale sur la gauche, puis, sous Create new (Créer), sélectionnez Repository (Dépôt).
  2. Donnez un nom au dépôt. C’est important ! Le nom d’un dépôt sera inclus dans son URL.
  3. Définissez l’option Include a README? (Inclure un fichier README ?) sur Yes, with a template (Oui, avec un modèle).
  4. Vous pouvez conserver les autres valeurs par défaut et cliquer sur Create (Créer)

En savoir plus sur la création d’un répertoire de code source sur Bitbucket Cloud.

_scroll_external/attachments/image2021-5-10_9-43-43-484cf086a2a621636fc06e519cec5f930bad24704f78551836178a9f67c82e7d.png

La structure de notre projet Java dans Bitbucket Cloud et dans un terminal de commande

_scroll_external/attachments/image2021-5-10_9-45-16-bcbe7928516c954192eadfaa673ffefa9f21cbfd85ae41535f0ab09a54158f33.png

├── README.md
├── bitbucket-pipelines.yml
├── checkstyle.xml
├── pom.xml
├── settings.xml
├── src
│   ├── main
│   │   └── java
│   │       └── com
│   │           └── idalko
│   │               ├── calculation
│   │               │   ├── Calculation.java
│   │               │   └── package-info.java
│   │               ├── hello
│   │               │   ├── HelloWorld.java
│   │               │   └── package-info.java
│   │               └── tests
│   └── test
│       └── java
│           └── com
│               └── idalko
│                   └── calculation
│                       └── tests
│                           ├── TestCalculation.java
│                           └── package-info.java

La consigne impérative à chaque commit de code pour que Jira Software Cloud et Bitbucket Cloud fonctionne ensemble :

le message de votre commit doit impérativement contenir le numéro unique du ticket Jira concerné

Un exemple de commit git avec un message et un numéro unique de ticket Jira :

git commit -m "WCC-7 un exemple de commit git avec un message et 
un numéro unique de ticket Jira" ./README.md

Troisième étape : Bitbucket Pipelines

Après avoir activer Pipelines sur votre dépôt de sources, il est temps de le configurer pour nos besoins grâce au fichier bitbucket-pipelines.yml :

  1. une configuration principale pour la branche « master »
  2. une configuration secondaire pour les branches de fonctionnalités « feature/* »
  3. une configuration de déploiement pour un environnement de Test
  4. une configuration de déploiement pour un environnement de Production

On part d’une image docker nous permettant d’avoir un environnement ou construire notre binaire java, ici on utilise une image offerte par Maven mais vous pouvez utiliser votre propre image Docker avec tous vos outils pré-installés et publiée cette image sur le Hub Docker – https://hub.docker.com pour permettre à Bitbucket Pipelines d’y accéder en public ou en privé : (on reviendra plus tard à la configuration Maven de notre projet Java) :

image: maven:3.6.3

Puis on configure la branche « master » pour l’Intégration continue (build) et le Déploiement continu (deploy) :

branches:
  master:
    - parallel:
      - step:
          name: Build and Test
          caches:
            - maven
          script:
            - mvn verify --file pom.xml -s settings.xml
          after-script:
            # Collect checkstyle check results if any and convert to Bitbucket Code Insights.
            - pipe: atlassian/checkstyle-report:0.2.0
      - step:
          name: Security Scan
          script:
            # Run a security scan for sensitive data.
            # See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security
            - pipe: atlassian/git-secrets-scan:0.4.3
    - step:
        name: Deploy to Test
        deployment: Test
        script:
          - mvn clean deploy -s settings.xml
    - step:
        name: Deploy to Production
        deployment: Production
        trigger: manual
        script:
          - mvn --batch-mode release:update-versions -DreleaseVersion=1.0
          - mvn clean deploy

Quelques explications :

  • Sur l’étape (step) « Build and Test » , on met en cache maven (répertoire ~/.m2/repository),
  • Puis on lance la construction de notre binaire java avec nos fichiers de configuration en entrée (mvn verify),
  • Ensuite on exécute une Bitbucket Pipe pour contrôler notre code avec Checkstyle (pour Java) et obtenir un rapport,
  • L’étape (step) « Security Scan sera exécutée en parallèle de l’étape « Build and Test », c’est un test proposé par Atlassian pour vérifier que votre projet n’utilise pas de données sensibles « en clair » comme les mots de passe par exemple,
  • Sur l’étape (step) « Deploy to Test » on déploie notre binaire sur une plateforme de dépôt de binaire comme JFrog utilisé au sein d’iDalko par exemple,
  • Et enfin sur l’étape (step) « Deploy to Production », on incrémente la version de notre projet (rapide ici on devrait tagger notre projet), noté que le déclenchement sera manuel ici avec la commande trigger: manual

Pour en savoir plus sur les Bitbucket Pipes : Grâce aux Bitbucket Pipes vous allez pouvoir créez des workflows puissants et automatisés d’intégration continue et de déploiement continu de manière plug and play. Vous pouvez utiliser des Pipes pré-configurées ou créez et partagez vos propres Pipes.

Enfin, de la même manière, on configure la branche « feature/* » pour l’Intégration continue (build) et le Déploiement continu (deploy) :

feature/*:
   - parallel:
     - step:
         name: Build and Test
         caches:
           - maven
         script:
           - mvn versions:set --file pom.xml -DnewVersion=1.0-FEATURE-SNAPSHOT
           - mvn verify -s settings.xml
         after-script:
           # Collect checkstyle check results if any and convert to Bitbucket Code Insights.
           - pipe: atlassian/checkstyle-report:0.2.0
     - step:
         name: Security Scan
         script:
           # Run a security scan for sensitive data.
           # See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security
           - pipe: atlassian/git-secrets-scan:0.4.3
   - step:
       name: Deploy to Test
       deployment: Test
       script:
         - mvn versions:set --file pom.xml -DnewVersion=1.0-FEATURE-SNAPSHOT
         - mvn clean deploy -s settings.xml
   - step:
       name: Deploy to Production
       deployment: Production
       trigger: manual
       script:
         - mvn --batch-mode release:update-versions -DreleaseVersion=1.0
         - mvn clean deploy

Quelques explications :

  • Sur l’étape (step) « Build and Test » , on met en cache maven (répertoire ~/.m2/repository),
  • On force la version de notre configuration maven pour déposer nos binaires un dossier à part sur notre plateforme de dépôts de binaire (mvn versions:set)
  • Puis on lance la construction de notre binaire java avec nos fichiers de configuration en entrée (mvn verify),
  • Ensuite on exécute une Bitbucket Pipe pour contrôler notre code avec Checkstyle (pour Java) et obtenir un rapport,
  • L’étape (step) « Security Scan sera exécutée en parallèle de l’étape « Build and Test », c’est un test proposé par Atlassian pour vérifier que votre projet n’utilise pas de données sensibles « en clair » comme les mots de passe par exemple,
  • Sur l’étape (step) « Deploy to Test » on déploie notre binaire sur une plateforme de dépôt de binaire comme JFrog utilisé au sein d’iDalko par exemple,
  • Et enfin sur l’étape (step) « Deploy to Production », on incrémente la version de notre projet (rapide ici on devrait tagger notre projet), noté que le déclenchement sera manuel ici avec la commande trigger: manual

Quatrième étape : Maven dans le projet JAVA

Petit rappel sur Maven : Apache Maven (couramment appelé Maven) est un outil de gestion et d’automatisation de production des projets logiciels Java en général et Java EE en particulier. Il est utilisé pour automatiser l’intégration continue lors d’un développement de logiciel. Maven est géré par l’organisation Apache Software Foundation.

Pour décrire les dépendances de notre projet Java, on va donc construire un fichier nommé pom.xml :

  • le groupid : le package utilisé
  • l’artifactid : le nom de notre binaire Java (jar)
  • la version initiale de notre projet Java et de notre binaire
  • le packaging, ici en jar
  • et enfin les propriétés maven qui indique la version de Java a utilisé pour compiler notre projet ici Java 7
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <groupId>com.idalko.hello</groupId>
  <artifactId>my-hello-idalko</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <modelVersion>4.0.0</modelVersion>
  <name>iDalkoHello</name>
   
  <properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

Notre première dépendance : Junit pour l’exécution des tests unitaires sur notre projet Java, noté que le scope ici est important. On souhaite utiliser cette dépendance pour nos tests seulement le scope est très important ici car on ne souhaite pas embarquer le jar Junit dans notre binaire projet.

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.1</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Et les dépendances pour produire un rapport de test unitaire :

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-report-plugin</artifactId>
  <version>3.0.0-M5</version>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-failsafe-plugin</artifactId>
  <version>3.0.0-M5</version>
  <executions>
    <execution>
      <goals>
        <goal>integration-test</goal>
        <goal>verify</goal>
      </goals>
    </execution>
  </executions>
</plugin>

La configuration pour pouvoir utiliser Checkstyle et contrôler la qualité de notre code :

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-checkstyle-plugin</artifactId>
  <version>3.1.2</version>
  <dependencies>
    <dependency>
      <groupId>com.puppycrawl.tools</groupId>
      <artifactId>checkstyle</artifactId>
      <version>8.38</version>
    </dependency>
  </dependencies>
  <configuration>
    <configLocation>checkstyle.xml</configLocation>
    <includeTestSourceDirectory>true</includeTestSourceDirectory>
    <encoding>UTF-8</encoding>
    <consoleOutput>true</consoleOutput>
    <failsOnError>true</failsOnError>
    <linkXRef>false</linkXRef>
  </configuration>
  <executions>
    <execution>
      <id>validate</id>
      <phase>validate</phase>
      <goals>
        <goal>check</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Et enfin la plateforme de déploiement pour déployer nos binaires et les rendre disponible pour un déploiement par une autre équipe, on utilise ici Jfrog :

<distributionManagement>
    <repository>
      <uniqueVersion>false</uniqueVersion>
      <id>plugins-release-local</id>
      <name>Idalko Release Repository</name>
      <url>http://${USERBUILDER}:${PASSBUILDER}@artifactory.idalko.com/artifactory/plugins-release-local</url>
      <layout>default</layout>
    </repository>
    <snapshotRepository>
      <uniqueVersion>true</uniqueVersion>
      <id>plugins-snapshot-local</id>
      <name>Idalko Snapshot Repository</name>
      <url>http://${USERBUILDER}:${PASSBUILDER}@artifactory.idalko.com/artifactory/plugins-snapshot-local</url>
      <layout>default</layout>
    </snapshotRepository>
  </distributionManagement>
</project>

${USERBUILDER} et ${PASSBUILDER} sont des variables d’environnement Bitbucket pour ne pas utiliser ces informations en clair dans nos configurations. En savoir plus sur les variables d’environnement Bitbucket.

Un résumé de l’enchainement des différentes plateformes et de la partition qui va être jouée :

_scroll_external/attachments/summary-cicd-58c48ec89c67ff8d955143e095df552d14493492bc9b1020fa84e822aa946523.jpeg

En avant la musique…

Après avoir écrit la partition, on peut désormais jouer notre morceau de musique. Ce qui va se passer lors d’un commit de code avec un message contenant le numéro unique du ticket Jira concerné :

  1. le ticket Jira associé va transitionner sur l’état « In Progress »
  2. un build sera déclenché sur Bitbucket avec Pipelines
  3. les tests unitaires du projet seront exécuté et un rapport sera produit
  4. la qualité du code sera controlée et un rapport sera produit
  5. Si le binaire est construit et que le build est « vert »
    1. le déploiement du binaire se fera automatiquement sur notre dépôt de binaire en environnement (répertoire) de Test
    2. on pourra ensuite décider de pousser ce binaire dans notre dépôt sur l’environnement (répertoire) de Production manuellement

Un aperçu des différents résultats de build dans Bitbucket

_scroll_external/attachments/image2021-5-11_7-8-41-13cb6716c4de028bd09415d960152298c016b4111117e36b691f6f1d846fb3d3.png

Un build réussit

  • Il est possible de rejouer les différents déploiements manuellement
  • On retrouve des informations utiles : durée du build, branches associées, commit associé, etc.
  • La couleur parle à tout le monde, vert = succès

_scroll_external/attachments/image2021-5-11_7-9-46-c3eeaf46d6b94b46678634409a0afc288ebe609c0d3b817a6c75d28ca1b3f3f3.png

Un build échoué

  • Il est possible de relancer le build manuellement
  • On retrouve des informations utiles : durée du build, branches associées, commit associé, rapport, etc.
  • Le détail de l’erreur au build, mais pas très lisible ici
  • La couleur parle à tout le monde, rouge = échec

_scroll_external/attachments/image2021-5-11_7-14-41-1bfa9150b92ba6fb8eb864e95e8cad4198991f4c76b9f3f57cfc1f46798813b1.png

Le rapport Checkstyle sera beaucoup plus lisible :

_scroll_external/attachments/image2021-5-11_7-16-22-b0867531dc5cb20acdaf337e98ec77b8855dd071ebd294d964dcd6812b82a928.png

La vue des déploiements vers JFrog

Ce qui est très pratique ici : on peut directement promouvoir (promote) un build depuis l’environnement de test vers l’environnement de Production en 1 seul clic grâce au bouton Promote !

_scroll_external/attachments/image2021-5-11_7-27-52-18db97c649739aeab2146606620b41ebca336e2a76e04d17bd9cee67759b45e7.png

L’environnement de Test

_scroll_external/attachments/image2021-5-11_7-29-0-4a84f032bc8e839d6bd787b080b1a87c49fbb5cc24b81102df72dbe1b2128089.png

L’environnement de Production

_scroll_external/attachments/image2021-5-11_7-29-44-dc2836a56bb1f7c7fb20e7c845b6157f1b3c4651e91868d3c174127808d38791.png

La promotion d’un build

_scroll_external/attachments/image2021-5-11_7-31-54-203359b34b497797962e4e564a3b8086d44f124fb5a405bbc1f3832935dab2d7.png

Suite au clic sur « Deploy »

_scroll_external/attachments/image2021-5-11_7-33-27-b83a19b5d9ffe34693b01b64f93b7f46b8e6049c8006f8cdbf9d8394f9bf050b.png

La vue des binaires dans JFrog

_scroll_external/attachments/image2021-5-12_7-59-22-7d121b0c3c9e5ebc4bbc8031825b526896c7c4b928ee80105a2d7dddc49cd859.png

Les différentes vues dans Jira Software Cloud

La vue d’un ticket avec le panel « Development »

_scroll_external/attachments/image2021-5-11_7-38-49-d494c3d41734e57515276c39a6901b9ce8cd1a105863648395b6a9b49e6ded1a.png

L’historique détaillé des commits

_scroll_external/attachments/image2021-5-11_7-39-52-dd84389ad6e2cd28f78c3177cdb98d0b965f1c86d13b6b2db5a4b7a9da79a043.png

L’historique complet des pull requests

_scroll_external/attachments/image2021-5-11_7-40-45-1bb34120b3f6b01010b4b2cbe67a602b0b762348904fdf9e862388df1ba76415.png

Le dernier build effectué

_scroll_external/attachments/image2021-5-11_7-41-43-d2e48f092615e3180eeff627ecd8ca726291d14409161824587ff2d7072495e1.png

L’historique des déploiements

_scroll_external/attachments/image2021-5-11_7-42-33-58902257adc5f039954f83a85254214d38d9a8cf0d8b8ce1281b6d7de57cb469.png

Cet article a été écrit par Damien Lauberton, un ingénieur Atlassian à iDalko.

Ressources

Remerciements

Merci à iDalko qui sait toujours me dégager du temps pour l’implémentation et la rédaction de ces articles, et un remerciement tout spécial à Atlassian et à leur support tellement rapide et efficace pour m’avoir offert de nombreuses minutes de build sur Bitbucket Pipelines gratuitement.