Objectif : développer un projet logiciel BTS SNIR avec Jira
1. Les outils
1.1. Git
Git est un logiciel de gestion de versions décentralisé (DVCS). C’est un logiciel libre créé par Linus Torvalds en 2005. Il s’agit maintenant du logiciel de gestion de versions le plus populaire devant Subversion (svn
) qu’il a remplacé avantageusement.
Site officiel : https://git-scm.com/
Ressources Git :
1.2. Atlassian : Jira, Bitbucket, …
À l’origine, Jira est un système de suivi de bugs et de gestion des incidents (tickets). Il est maintenant un système de gestion de projets développé par Atlassian.
Atlassian est un éditeur de logiciels, basé en Australie, qui développe des produits pour la gestion de développement et de projets. Ses logiciels les plus connus sont Jira, Confluence, Bitbucket et Trello :
-
Jira Software constitue la plate-forme centrale pour les phases de programmation, de collaboration et de livraison. Jira Software est gratuit jusqu’à 10 utilisateurs, avec 2 Go de stockage.
-
Confluence est un logiciel de wiki, utilisé comme logiciel de travail collaboratif.
-
Bitbucket est un service web d’hébergement et de gestion de développement logiciel utilisant le logiciel de gestion de versions Git. Bitbucket est gratuit pour les particuliers et les petites équipes comptant jusqu’à 5 utilisateurs, avec des référentiels publics et privés illimités.
-
Trello est un outil de gestion de projet en ligne, inspiré par la méthode Kanban de Toyota.
Ressources Atlassian :
1.3. GitHub
GitHub est un service web d’hébergement et de gestion de développement de logiciels, utilisant le logiciel de gestion de versions Git.
Site officiel : https://github.com/
Ressources GitHub :
2. Le projet BTS SNIR à LaSalle Avignon
Un projet (ou mini-projet) BTS SNIR sera mené avec :
2.1. Processus de développement logiciel
Un processus de développement décrit une méthode qui permet de construire, déployer et éventuellement maintenir un logiciel.
Un processus de développement définit une séquence d’étapes, partiellement ordonnées, qui permettent d’obtenir un système logiciel ou faire évoluer un système existant.
Exemples d’étapes :
-
Exigences, Analyse, Conception, Mise en œuvre (implémentation), Test
-
Besoin/Faisabilité, Élaboration, Fabrication, Transition/Test
On utilisera un développement itératif et incrémental.
Liens :
2.2. Le développement itératif
Le développement itératif s’organise en une série de développement très courts de durée fixe nommée itérations.
Dans une itération, on répète les mêmes activités (de la spécification jusqu’au test).
Le résultat de chaque itération est un système partiel exécutable, testé et intégré mais incomplet.
Une nouvelle itération écrase la précédente.
Le résultat d’une itération n’est pas un prototype expérimental ou « jetable ».
Le projet ou mini-projet sera mené à son terme en plusieurs itérations successives (2 ou 3 maximum).
2.3. Le développement incrémental
Le développement incrémental consiste à réaliser successivement des éléments fonctionnels utilisables.
Un incrément est une avancée dans le développement en terme de fonctionnalités.
Dans un développement incrémental, on planifie donc par fonctionnalités.
Chaque développement s’ajoute et enrichit l’existant.
Chaque incrément produira une version.
2.4. Versions
Une version d’un logiciel correspond à un état donné de l’évolution d’un projet logiciel. Une version de logiciel est le plus souvent associée à une numérotation.
Il faut différencier les évolutions dans un logiciel :
-
Les évolutions majeures apportent de nouvelles fonctionnalités, voire restructurent complètement l’application.
-
Les évolutions mineures apportent principalement des corrections de bugs ou des ajouts de fonctionnalités secondaires.
Convention utilisée pour les numéros de versions (tags) X.Y
:
-
X
le numéro de version majeur de l’application (1
pour la première version/itération) -
Y
le numéro de version mineur de l’application (0
par défaut, ensuite incrémenté pour chaque correction)
2.5. Planification
La planification est essentielle dans le projet.
La plupart des méthodes encourage une planification itérative pilotée à la fois par les risques et par le client.
Cela signifie que les objectifs des premières itérations sont choisis afin de d’identifier les risques les plus importants et de construire les fonctionnalités visibles qui comptent le plus pour le client.
Pour chaque itération, on choisira des cas d’utilisation présentant ces trois qualités :
-
significatifs du point de vue de l’architecture
-
de grande valeur pour le client (les fonctionnalités qui comptent vraiment pour lui)
-
à haut risque (technique)
On classera en distinguant trois niveaux de priorité (Haut, Moyen et Bas).
2.6. Kanban
Issue d’un mot japonais signifiant tableau, la méthode Kanban a vu le jour dans les usines Toyota au milieu du XXème siècle. Cette image de tableau vient de l’utilisation des porte-étiquettes permettant d’organiser le travail dans les usines.
Sa reprise pour la gestion de projet date de l’apparition des méthodes dites agile.
La méthode Kanban tire sa force de sa simplicité. En effet, toujours dans un esprit agile, cette méthode simplifie au maximum le concept d’organisation des tâches.
Elle repose sur quatre étapes principales aboutissant à un tableau de quatre colonnes :
-
à faire (backlog ou todo) : la liste des tâches à effectuer pour l’itération ;
-
prêt (ready ou selected) : la liste des tâches que vous souhaitez effectuer dans l’itération ;
-
en cours (in progress) : les tâches en cours de réalisation (en général par développeur une à la fois, voire deux) ;
-
terminé (done) : Les tâches terminées.
On peut ajouter, supprimer et/ou renommer les colonnes (Par exemple : à faire, en cours et terminé). |
Dans Jira, un tableau Kanban permet à l’équipe de visualiser le flux de travail (workflow) :
- Backlog
-
Un backlog contient des tickets en suspens sur lesquels une équipe devra travailler. Au démarrage d’une itération, on sélectionne les tickets dans le backlog pour les basculer dans "Sélectionné pour le développement" ou dans "En cours".
Le flux de travail (workflow) par défaut :
Il est possible d’ajouter des règles pour gérer automatiquement le flux de travail (workflow) :
Par exemple, pour faire le lien avec Git :
Kanban vs Scrum
Kanban et Scrum sont des frameworks Agile populaires auprès des développeurs de logiciels. Il y a cependant des différences clés :
|
Les tâches (un ticket dans Jira) sont représentées visuellement sur le tableau Kanban, ce qui permet à l’équipe de suivre l’état du travail à tout moment. Les colonnes du tableau représentent chaque étape du workflow, des tâches à faire à celles qui sont terminées.
Les tickets Jira, également appelés « tâches », suivent chaque travail qui doit passer par les différentes étapes du workflow jusqu’à son achèvement. Les tickets sont des éléments de travail individuel qui sont assignés aux membres de l’équipe.
Les différents types de ticket dans Jira :
- Epics
-
Une « epic » (épopée) est un vaste ensemble de tâches qui peuvent être subdivisées en plus petites unités. Ces unités, appelées « stories » (histoire) ou « user stories », représentent les exigences ou besoins du point de vue de l’utilisateur.
Il est possible de créer des epics de trois manières dans Jira : la feuille de route, le backlog et le bouton global "Créer un ticket". Après avoir créé une epic, on peut y ajouter des stories ou des tickets enfant.
Les stories, les bugs et les tâches décrivent un bloc de travail, alors que les epics sont utilisées pour décrire un groupe de tickets. |
- Feuilles de route
-
Les feuilles de route créent une représentation visuelle de toutes les epics sur lesquelles une équipe travaille. Une feuille de route est une source de référence partagée qui décrit la vision, l’orientation, les priorités et l’avancement d’un produit ou d’une équipe au fil du temps.
- Versions
-
Dans Jira, les versions représentent des points dans le temps pour un projet. Elles aident à organiser les tâches grâce à des étapes importantes à suivre. Il est possible d’assigner les tickets à une version spécifique et organiser les itérations en fonction des tâches réalisées dans cette version. Les noms de version correspondent généralement à des chiffres, par exemple,
1.0
ou2.1.1
.
2.7. Le développement collaboratif
2.7.1. Pull Request et Révision de code
Les Pull Requests sont une fonctionnalité facilitant la collaboration des développeurs sur un projet. Cela permet à un développeur d’informer les membres de l’équipe qu’il a terminé un « travail » (une fonctionnalité, une version livrable, un correctif, …) et de proposer sa contribution au dépôt central.
Pull Request peut être traduit par « Proposition de révision » (PR) : c’est-à-dire une demande de modification ou de contribution. |
Le principe est le suivant :
-
Une fois que sa branche de suivi est prête, le développeur crée ou ouvre (Open) une Pull Request.
-
Tous les développeurs du projet seront informées du fait qu’ils doivent réviser le code puis le fusionner (merge) dans la branche principale (
main
oumaster
) ou dans une autre branche.
Pendant cette révision de code, les développeurs peuvent discuter de la fonctionnalité (commenter le code, poser des questions, …) et proposer des adaptations de la fonctionnalité en publiant des commits de suivi.
Les Pull Requests offrent cette fonctionnalité dans une interface Web à côté des dépôts GitHub ou Bitbucket. Cette interface affiche une comparaison des changements, permet l’échange entre développeurs et fournit une méthode simple pour réaliser la fusion (merge) du code quand il est prêt.
2.7.2. Gitflow
Un workflow git est une méthode, un processus de travail, une recette ou une recommandation sur la façon d’utiliser Lien : Comparaison des workflow git |
Le workflow Gitflow définit un modèle de branchement strict conçu autour de la version du projet. Ce workflow n’ajoute pas de nouveaux concepts ou commandes. Gitflow permet de gérer les bugs (issues), les nouvelles fonctionnalités (features) et les versions (releases) en attribuant des rôles très spécifiques à différentes branches et définit comment et quand elles doivent interagir.
Les rôles des branches sont les suivants :
-
pour les branches permanentes :
-
La branche
master
stocke l’historique des versions officielles. Tous les commits de cette branche sont étiquetés avec un numéro de version (tags). -
La branche
develop
est créée à partir de la branchemaster
. Elle sert de branche d’intégration pour les fonctionnalités. Cette branche contiendra l’historique complet du projet.
-
-
pour les branches temporaires :
-
Les branches
features-xxxx
permettent de travailler sur des nouvelles fonctionnalités. Elles sont créées directement à partir de la branchedevelop
et une fois le travail fini, fusionnées vers la branchedevelop
. -
Les branches
release-xxxx
permettent de travailler sur une livraison (généralement des tâches dédiées à la documentation). On les crée à partir dedevelop
puis on les fusionne dansmaster
en leur attribuant un numéro de version (tag). -
Les branches
hotfix-xxxx
permettent de publier rapidement (hot) une correction (fix) depuis la branchemaster
. Ces branches seront ensuite fusionnées vers la branchemaster
etdevelop
.
-
En projet BTS SN, les branches (feature, release et hotfix) seront créées dans Jira à partir d’un ticket. Les fusions seront réalisées lors d’une revue de code en utilisant les Pull Requests dans GitHub ou Bitbucket. |
Réalisation d’une fonctionnalité :
Réalisation d’une release :
Correction d’un bug :
Une branche représente une ligne de développement indépendante. Lorsqu’elle désigne un travail bien identifié du projet (une fonctionnalité, une release ou un correctif), il est préférable (obligatoire) que cela reste visible dans le graphe d’historique, même lorsque la branche est supprimée. Pour éviter que Git utilise par défaut une avance rapide (Fast Forward) si c’est possible, il faudra réaliser un commit de fusion avec l’option |
2.7.3. Branche de suivi
Une branche de suivi (tracking branch) est une branche locale qui est en relation directe avec une branche distante (upstream branch).
1 . Nettoyer son historique local avant de publier
Avant de faire un git push
sur une branche de suivi, il faut eut être nettoyer son historique local (une série de commits dans la branche) afin de pouvoir proposer quelque chose de propre et d’utilisable. Avant de publier la branche, il est conseillé d’effectuer une rebasage interactif avec git rebase -i
. On a alors une totale liberté pour nettoyer, réécrire, annuler, regrouper les commits locaux avant de les partager (git push
) sur le dépôt distant.
Sur la branche actuelle depuis la dernière synchronisation : git rebase -i @{upstream}
(ou git rebase -i origin/feature
ou git rebase -i HEAD~n
).
Lorsque l’on développe seul, une branche de suivi peut servir de sauvegarde sur un dépôt distant. Dans le cadre d’un travail collaboratif, cela devient une branche de partage. |
2 . Travailler à plusieurs sur une branche de fonctionnalité
Il est possible que le git push
soit refusé en raison d’une branche de suivi obsolète (un travail a été poussé entre-temps) : entre la dernière synchronisation entrante (git pull
) et le moment où on souhaite effectuer un git push
, un autre développeur a publié des changements (des commits). La branche distante (par exemple origin/feature
) est donc maintenant plus avancée que sa copie locale.
Un git pull
provoquerait une fusion avec une divergence mais on souhaite conserver un historique linéaire au sein d’une branche : car ce n’est réalité qu’un problème de séquencement dans le travail sur la branche.
On va demander à git pull
de faire un rebase au lieu d’une fusion (merge) en utilisant git pull --rebase
.
La commande |
2.8. Cycle de travail
2.9. Jira et GitHub
Cette partie décrit un exemple de développement de projet avec Jira connecté à un dépôt GitHub. Il reprend le cycle de travail défini précédemment.
Au démarrage, il faut cloner le dépôt GitHub :
$ git clone git@github.com:btssn-lasalle84/mp1-teamX.git $ cd mp1-teamX/
À chaque itération (produisant une nouvelle version) :
-
Création d’une version dans Jira
-
Mise à jour de la Feuille de route
-
Création d’une Epic (l’itération) : Réalisation de la version
x.x
-
Il faut l’associer à la version créée :
-
Création des tâches (tickets enfants) pour chaque fonctionnalité associée à la version
Par exemple :
-
Sélection d’une tâche puis création de la branche (Type
feature
à partir dedevelop
)
On récupère (copier) la commande Git :
-
Implémentation de la fonctionnalité sur la branche
$ git fetch && git checkout feature/MP1T0-2-initialisation-du-projet Depuis github.com:btssn-lasalle84/mp1-team0 * [nouvelle branche] feature/MP1T0-2-initialisation-du-projet -> origin/feature/MP1T0-2-initialisation-du-projet La branche 'feature/MP1T0-2-initialisation-du-projet' est paramétrée pour suivre la branche distante 'feature/MP1T0-2-initialisation-du-projet' depuis 'origin'. Basculement sur la nouvelle branche 'feature/MP1T0-2-initialisation-du-projet' $ vim projet.txt fonc 1 : vide fonc 2 : vide fonc 3 : vide fonc 4 : vide fonc 5 : vide $ git add projet.txt
Au minimum, il faut inclure la clé du ticket au début du message de commit pour faire lien avec Jira :
$ git commit -m "MP1T0-2 Ajout du fichier projet.txt"
Avant de faire le |
Dans le cadre d’un travail collaboratif, on "publie" la branche sur le dépôt distant :
$ git push Décompte des objets: 3, fait. Delta compression using up to 12 threads. Compression des objets: 100% (3/3), fait. Écriture des objets: 100% (3/3), 322 bytes | 322.00 KiB/s, fait. Total 3 (delta 0), reused 0 (delta 0) To github.com:btssn-lasalle84/mp1-team0.git 5401f1a..9be3d62 feature/MP1T0-2-initialisation-du-projet -> feature/MP1T0-2-initialisation-du-projet
-
Création d’une Pull Request lorsque la fonctionnalité est prête pour validation
Il est possible de continuer à travailler sur la branche. Dans le cadre d’un travail collaboratif, il sera peut-être nécessaire de mettre à jour la branche avec un |
Lorsque la Pull Request sera approuvée, on pourra faire la fusion (avec l’option --no-ff
) :
On obtient :
Une fois la fusion réalisée, on peut faire la mise à jour de la branche develop
:
$ git checkout develop $ git pull
Avec Gitflow, seules les branches main
et develop
sont permanentes. Les branches feature
peuvent être supprimées :
$ git branch -d feature/MP1T0-2-initialisation-du-projet $ git push origin --delete feature/MP1T0-2-initialisation-du-projet
Dans Jira, le ticket est passé automatiquement à l’état "Terminé" (sinon le faire manuellement) :
Avec des informations sur le développement :
-
Finalisation d’une release puis création de la branche (Type
release
à partir dedevelop
)
Lorsque toutes les tâches de l’itération sont terminées :
On sélectionne le ticket Epic (représentant l’itération réalisée) et on crée une branche release
à partir de la branche develop
:
-
Implémentation de la release sur la branche
On récupère la branche :
$ git fetch && git checkout release/MP1T0-1-version-1-0 Depuis github.com:btssn-lasalle84/mp1-team0 * [nouvelle branche] release/MP1T0-1-version-1-0 -> origin/release/MP1T0-1-version-1-0 La branche 'release/MP1T0-1-version-1-0' est paramétrée pour suivre la branche distante 'release/MP1T0-1-version-1-0' depuis 'origin'. Basculement sur la nouvelle branche 'release/MP1T0-1-version-1-0'
On prépare une version livrable, par exemple la mise à jour du README.md
:
$ vim README.md $ git add README.md $ git commit -m "MP1T0-1 Finalisation de la version 1.0" [release/MP1T0-1-version-1-0 136f392] MP1T0-1 Finalisation de la version 1.0 1 file changed, 3 insertions(+) $ git push Décompte des objets: 3, fait. Delta compression using up to 12 threads. Compression des objets: 100% (2/2), fait. Écriture des objets: 100% (3/3), 331 bytes | 331.00 KiB/s, fait. Total 3 (delta 0), reused 0 (delta 0) To github.com:btssn-lasalle84/mp1-team0.git 92ea1cc..136f392 release/MP1T0-1-version-1-0 -> release/MP1T0-1-version-1-0
-
Création d’une Pull Request lorsque la release est prête pour validation dans la branche
main
Une fois la fusion réalisée, il faut créer un tag dans main
pour cette release et le publier sur le dépôt distant :
$ git checkout main $ git pull $ git tag -a -m "Version 1.0" 1.0 $ git push --tags
Maintenant, il faut intégrer les changements éventuels à la branche develop
pour qu’elle soit à jour pour continuer le développement. On crée une autre Pull Request :
On valide la fusion et on met à jour le dépôt local :
$ git checkout develop $ git pull
Pour finir, on supprime la branche release
:
$ git branch -d release/MP1T0-1-version-1-0 $ git push origin --delete release/MP1T0-1-version-1-0
Dans Jira, la version est automatiquement "Terminé" :
On peut donc livrer la version :
La version est maintenant à l’état "LIVRÈE" :
-
Correction d’un bug (Type
hotfix
à partir demain
)
Malheureusement, il est fort possible que le client remonte des dysfonctionnalités. Dans ce cas, il faudra réaliser un correctif qui aboutira à une nouvelle version (1.1
par exemple).
Il faut créer un ticket bug dans (l'Epic de) la version 1.0
:
Il faut maintenant créer et associer une nouvelle version (ici 1.1
) :
Le ticket apparaît dans le tableau Kanban :
On le sélectionne pour créer une branche de type hotfix
à partir de main
:
Le ticket bug apparaît à l’état en cours :
On récupère la branche :
$ git fetch && git checkout hotfix/MP1T0-5-defaut-dans-fonc-2
On travaille sur le correctif :
$ vim projet.txt $ git add projet.txt $ git commit -m "MP1T0-5 Correction fonc 2" $ git push
Création d’une Pull Request lorsque le correctif est prêt pour validation dans la branche main
:
Une fois la fusion réalisée, il faut créer un tag dans main
pour cette release et le publier :
$ git checkout main $ git pull $ git tag -a -m "Version 1.1" 1.1 $ git push --tags
Pour finir, il faut intégrer le correctif à la branche develop
en créant une Pull Request :
On valide la fusion et on met à jour le dépôt local :
$ git checkout develop $ git pull
Pour finir, on supprime la branche hotfix
:
$ git branch -d hotfix/MP1T0-5-defaut-dans-fonc-2 $ git push origin --delete hotfix/MP1T0-5-defaut-dans-fonc-2
Le dépôt distant :
Dans Jira, on peut livrer la version 1.1
:
L’historique du projet en mode graphique :
2.10. Jira et Bitbucket
On sélectionne un ticket (ici une fonctionnalité) :
On crée la branche (Gitflow) :
On récupère la branche (copier/coller) :
$ git fetch && git checkout feature/MP1T1-2-initialisation-du-projet Password for 'https://btssn-avignon-admin@bitbucket.org': Depuis https://bitbucket.org/btssn-avignon/miniprojet1-team1 * [nouvelle branche] feature/MP1T1-2-initialisation-du-projet -> origin/feature/MP1T1-2-initialisation-du-projet La branche 'feature/MP1T1-2-initialisation-du-projet' est paramétrée pour suivre la branche distante 'feature/MP1T1-2-initialisation-du-projet' depuis 'origin'. Basculement sur la nouvelle branche 'feature/MP1T1-2-initialisation-du-projet' $ vim projet.txt $ git add projet.txt
Au minimum, il faut inclure la clé du ticket au début du message de commit pour faire lien avec Jira :
$ git commit -m "MP1T1-2 Ajout du fichier projet.txt" $ git push Décompte des objets: 3, fait. Delta compression using up to 12 threads. Compression des objets: 100% (2/2), fait. Écriture des objets: 100% (3/3), 292 bytes | 292.00 KiB/s, fait. Total 3 (delta 0), reused 0 (delta 0) remote: remote: Create pull request for feature/MP1T1-2-initialisation-du-projet: remote: https://bitbucket.org/btssn-avignon/miniprojet1-team1/pull-requests/new?source=feature/MP1T1-2-initialisation-du-projet&t=1 remote: To https://bitbucket.org/btssn-avignon/miniprojet1-team1.git ddc49ad..40cb4b1 feature/MP1T1-2-initialisation-du-projet -> feature/MP1T1-2-initialisation-du-projet
Deux situations possibles :
-
fusion locale dans la branche
develop
puis on publie sur le dépôt central
$ git checkout develop $ git pull $ git merge --no-ff feature/MP1T1-2-initialisation-du-projet Merge made by the 'recursive' strategy. projet.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 projet.txt $ git push
-
création d’une Pull Request dans Bitbucket (avec le lien fourni après le
push
)
La Pull Request dans Bitbucket :
On fusionne :
L’historique :
À la fin, mise à jour :
$ git checkout develop $ git pull $ cat projet.txt
Avec Gitflow, seules les branches main
et develop
sont permanentes. Les autres branches peuvent être supprimées :
$ git branch -d feature/MP1T1-2-initialisation-du-projet $ git push origin --delete feature/MP1T1-2-initialisation-du-projet
Dans Jira, le ticket est passé automatiquement à l’état "Terminé" :
Avec des informations sur le développement :
Site : btssn-lasalle84.github.io