Module M2 — Gestion de projet (Jour 2 matin — 3h30)¶
Prérequis : instance configurée par M1 — rôles, trackers, workflow et activités en place
Objectif : créer et piloter un projet Redmine, gérer ses membres et produire des rapports de temps
Exercice 01 - Création et structuration du projet¶
Solution to Exercise 1 #
Menu : Projets → Nouveau projet
Renseigner les champs Nom et Identifiant — l’identifiant est généré automatiquement à partir du nom, vérifier qu’il correspond à
gestion-sinistresDans la section Modules, cocher : Suivi des demandes, Wiki, Documents, Suivi du temps, Fichiers
Sauvegarder
Pour le sous-projet : répéter l’opération, puis dans le champ Projet parent sélectionner Gestion des sinistres.
Vérifier dans la liste des projets que gestion-sinistres-batch apparaît en retrait sous gestion-sinistres.
Exercice 02 - Affectation des membres et des rôles¶
Solution to Exercise 2 #
Menu : Projet gestion-sinistres → Paramètres → onglet Membres → Nouveau membre
Sélectionner l’utilisateur dans la liste déroulante
Sélectionner le rôle correspondant
Cliquer Ajouter — répéter pour les 3 comptes
Vérification par compte :
| Compte | Ce qui doit être visible | Ce qui ne doit pas l’être |
|---|---|---|
cda.dupont | Paramètres projet, tous les tickets, tous les temps | Administration |
dev.martin | Ses tickets, saisie de temps | Paramètres projet, gestion membres |
client.durand | Liste des tickets, création de demande | Temps des autres, paramètres |
Exercice 03 - Création des versions (jalons)¶
Solution to Exercise 3 #
Menu : Projet → Paramètres → onglet Versions → Nouvelle version
Pour chaque version :
Saisir le nom (
Sprint 1,Sprint 2)Définir la date d’échéance
Statut : Ouvert
Sauvegarder
Vérifier via Menu : Projet → Roadmap — les 2 versions doivent apparaître avec leur date et le compteur de demandes (0 pour l’instant).
Exercice 04 - Création d’un lot de demandes fil rouge¶
Solution to Exercise 4 #
Voie A — interface web
Menu : Projet → Nouveau ticket
Pour chaque demande, renseigner dans l’ordre : Tracker, Sujet, Priorité, Assigné à, Version cible.
Voie B — import CSV
Menu : Projet → Suivi des demandes → Importer → téléverser demandes-import.csv
Mapper les colonnes :
| Colonne CSV | Champ Redmine |
|---|---|
| tracker | Tracker |
| subject | Sujet |
| priority | Priorité |
| assigned_to | Assigné à |
| fixed_version | Version cible |
| description | Description |
Lancer l’import — Redmine affiche un récapitulatif : 6 demandes importées, 0 erreur.
Si une valeur de colonne (tracker, priorité, version) ne correspond pas exactement à un libellé existant dans l’instance, la ligne est rejetée. Vérifier la casse et l’orthographe avant l’import.
Voie C — API REST
Correspondance des identifiants (vérifier dans votre instance) :
| Élément | id probable |
|---|---|
| Tracker Anomalie | 1 |
| Tracker Évolution | 2 |
| Tracker Demande de service | 3 |
| Tracker Tâche interne | 4 |
| Priorité Basse | 1 |
| Priorité Normale | 2 |
| Priorité Haute | 3 |
| Priorité Urgente | 4 |
Récupérer ID_DEV_MARTIN et les ID_SPRINT1 / ID_SPRINT2 depuis les appels de contrôle indiqués dans l’exercice, puis créer les 6 demandes en adaptant les paramètres.
Vérification commune : Menu Projet → Suivi des demandes → appliquer les filtres suivants :
Filtre
Version = Sprint 1→ doit retourner 4 demandesFiltre
Tracker = Anomalie→ doit retourner 3 demandesFiltre
Priorité = Urgente→ doit retourner 2 demandes
Si les champs personnalisés de l’exercice 11 (M1) ont été créés, renseigner aussi Environnement et Criticité métier sur les anomalies.
Exercice 05 - Mise en place de la documentation projet (Wiki)¶
Durée : 20 min
Menu : Projet → Wiki
Éléments de syntaxe Markdown (CommonMark, formatage par défaut configuré en M1)
| Syntaxe | Rendu |
|---|---|
# Titre niveau 1 | Titre principal |
## Titre niveau 2 | Sous-titre |
**texte** | gras |
*texte* | italique |
- élément | liste à puces |
1. élément | liste numérotée |
[[Nom-de-page]] | lien vers une page wiki |
[[Nom-de-page|Libellé]] | lien avec libellé personnalisé |
| col1 | col2 | | ligne de tableau |
```code``` | bloc de code |
Les liens internes wiki [[Nom-de-page]] fonctionnent quel que soit le moteur de formatage. Si l’instance est restée en Textile (formatage par défaut Redmine hors configuration M1), remplacer # par h1., ** par * et les blocs de code par <pre>...</pre>.
Créer les pages suivantes :
| Page | Contenu attendu |
|---|---|
| Accueil | Présentation du projet, contacts, liens utiles |
| Procedure-Incident | Procédure de qualification d’une anomalie (3 étapes minimum) |
| Contacts | Tableau fictif des interlocuteurs (nom, rôle, email) |
Depuis la page Accueil, créer un lien vers la procédure :
[[Procedure-Incident]]Critère de réussite : wiki navigable, lien fonctionnel entre les pages
Solution to Exercise 5 #
Menu : Projet → Wiki → Modifier (page Accueil générée automatiquement)
Contenu de la page Accueil (exemple) :
# Formation Redmine
Bienvenue sur le wiki du projet.
- [[Procedure-Incident|Procédure de gestion des incidents]]
- [[Contacts|Annuaire des interlocuteurs]]Contenu de la page Procedure-Incident :
# Procédure de qualification d'une anomalie
## Étape 1 — Réception
Vérifier la complétude du signalement : environnement, reproductibilité, impact.
## Étape 2 — Qualification
Affecter un tracker, une priorité et une version cible.
## Étape 3 — Assignation
Affecter à un développeur et passer le statut en "En cours".Contenu de la page Contacts :
| Nom | Rôle | Email |
|---|---|---|
| Dupont | Chef de projet | cda.dupont@example.com |
| Martin | Développeur | dev.martin@example.com |
| Durand | Client | client.durand@example.com |Vérifier que le lien [[Procedure-Incident]] depuis la page Accueil est cliquable et navigue vers la bonne page.
Exercice 06 - Consultation et analyse des temps (simulation)¶
Durée : 20 min
Saisie des temps — chaque stagiaire saisit 3 entrées :
| Demande | Durée | Activité |
|---|---|---|
| Erreur 500 sur le module facturation | 2h | Développement |
| Réinitialisation mot de passe | 0,5h | Support / Assistance |
| Mise à jour documentation API | 1h | Documentation |
Voie A — saisie via l’interface : Menu Projet → Suivi du temps → Nouvelle entrée de temps
Voie B — saisie via API REST (prérequis : clé API M1 EX-09, récupérer activity_id au préalable)
# Lister les activités disponibles
curl -H "X-Redmine-API-Key: VOTRE_CLE_API" `
http://localhost:3000/enumerations/time_entry_activities.json
# Saisir une entrée de temps sur une demande
curl -X POST `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"time_entry\": {\"issue_id\": ID_DEMANDE, \"hours\": 2, \"activity_id\": ID_ACTIVITE, \"comments\": \"Correction du module facturation\"}}" `
http://localhost:3000/time_entries.jsonAnalyse — Menu : Projet → Suivi du temps
Filtrer par activité
Filtrer par utilisateur
Filtrer par version
Identifier le total d’heures sur Sprint 1
Consultation via API REST
# Temps du projet
curl -H "X-Redmine-API-Key: VOTRE_CLE_API" `
"http://localhost:3000/time_entries.json?project_id=gestion-sinistres"
# Temps sur une demande précise
curl -H "X-Redmine-API-Key: VOTRE_CLE_API" `
"http://localhost:3000/time_entries.json?issue_id=ID_DEMANDE"
# Temps d'un utilisateur sur le projet
curl -H "X-Redmine-API-Key: VOTRE_CLE_API" `
"http://localhost:3000/time_entries.json?project_id=gestion-sinistres&user_id=ID_UTILISATEUR"Critère de réussite : rapport affiche les temps saisis, tous les filtres fonctionnels, total Sprint 1 = 2,5h
Solution to Exercise 6 #
Voie A — interface
Menu Projet → Suivi du temps → Nouvelle entrée de temps
Pour chaque entrée : sélectionner la demande, saisir la durée (format 2 ou 2.5), choisir l’activité, ajouter un commentaire optionnel.
Voie B — API REST
Réponse attendue de enumerations/time_entry_activities.json (ids probables selon configuration M1 EX-07) :
| activity_id | Activité |
|---|---|
| 1 | Développement |
| 2 | Recette / Tests |
| 3 | Réunion |
| 4 | Documentation |
| 5 | Support / Assistance |
Les 3 entrées à créer :
# 2h Développement sur "Erreur 500"
curl -X POST `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"time_entry\": {\"issue_id\": ID_ERREUR500, \"hours\": 2, \"activity_id\": 1, \"comments\": \"Correction du module facturation\"}}" `
http://localhost:3000/time_entries.json
# 0.5h Support sur "Réinitialisation MDP"
curl -X POST `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"time_entry\": {\"issue_id\": ID_MDP, \"hours\": 0.5, \"activity_id\": 5, \"comments\": \"Réinitialisation effectuée\"}}" `
http://localhost:3000/time_entries.json
# 1h Documentation sur "MAJ documentation API"
curl -X POST `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"time_entry\": {\"issue_id\": ID_DOC, \"hours\": 1, \"activity_id\": 4, \"comments\": \"Mise à jour endpoints REST\"}}" `
http://localhost:3000/time_entries.jsonRésultats attendus après filtrage :
| Filtre | Résultat attendu |
|---|---|
| Activité = Développement | 2h sur “Erreur 500” |
| Activité = Support / Assistance | 0,5h sur “Réinitialisation MDP” |
| Version = Sprint 1 | 2,5h (Erreur 500 + Réinitialisation MDP) |
| Utilisateur = dev.martin | Total des 3 entrées = 3,5h |
Résultat attendu de la consultation API (time_entries.json?project_id=gestion-sinistres) :
{
"time_entries": [
{"id": 1, "hours": 2.0, "activity": {"name": "Développement"}, "issue": {"id": ID_ERREUR500}},
{"id": 2, "hours": 0.5, "activity": {"name": "Support / Assistance"}, "issue": {"id": ID_MDP}},
{"id": 3, "hours": 1.0, "activity": {"name": "Documentation"}, "issue": {"id": ID_DOC}}
],
"total_count": 3
}L’API ne retourne pas de total calculé — sommer le champ hours côté client. Le paramètre spent_on permet de filtrer par date : ?spent_on=2026-06-18.
Exercices avancés¶
Exercice 07 - Requêtes et filtres personnalisés¶
Durée : 20 min
Menu : Projet → Suivi des demandes
Créer et sauvegarder 3 filtres réutilisables :
| Nom du filtre | Critères |
|---|---|
| Anomalies urgentes Sprint 1 | Tracker = Anomalie ET Priorité = Urgente ET Version = Sprint 1 ET Statut ≠ Fermé |
| Mes demandes en cours | Assigné à = moi ET Statut = En cours |
| Backlog Sprint 2 | Version = Sprint 2 ET Statut = Nouveau |
Pour chaque filtre :
Appliquer les critères via Ajouter un filtre
Choisir les colonnes à afficher (Tracker, Sujet, Priorité, Assigné à, Mis à jour)
Cliquer Sauvegarder — nommer le filtre
Cocher Public pour le partager à tous les membres du projet
Critère de réussite : 3 filtres sauvegardés, accessibles depuis le menu déroulant, le filtre public visible par dev.martin et client.durand
Solution to Exercise 7 #
Menu : Projet → Suivi des demandes → section Filtres → Ajouter un filtre
Anomalies urgentes Sprint 1 :
Tracker → est → Anomalie
Priorité → est → Urgente
Version → est → Sprint 1
Statut → n’est pas → Fermé
Cliquer Appliquer, puis Sauvegarder → saisir le nom → cocher Public → Sauvegarder.
Vérification : se connecter avec dev.martin → Projet → Suivi des demandes → le filtre public doit apparaître dans la liste déroulante des requêtes sauvegardées.
Les filtres privés ne sont visibles que par leur créateur. Utiles pour les vues personnalisées de chaque développeur.
Exercice 08 - Roadmap et suivi d’avancement¶
Durée : 20 min
Menu : Projet → Roadmap
L’objectif est de simuler l’avancement d’un sprint et d’en lire les indicateurs.
Étapes :
Passer 2 demandes du Sprint 1 en statut “Résolu” (
dev.martin)Passer 1 demande en statut “Fermé” (
cda.dupontouclient.durand)Consulter la Roadmap : observer la barre de progression du Sprint 1
Consulter le Gantt : Menu Projet → Gantt
Répondre aux questions suivantes :
Quel pourcentage d’avancement affiche le Sprint 1 ?
Combien de demandes restent ouvertes ?
Le Sprint 2 apparaît-il dans le Gantt ?
Critère de réussite : roadmap affiche un avancement > 0%, Gantt affiche les 2 versions avec leurs demandes
Solution to Exercise 8 #
Passage en Résolu : se connecter avec dev.martin → ouvrir la demande → modifier le statut → Sauvegarder.
Passage en Fermé : se connecter avec cda.dupont → ouvrir la demande résolue → modifier le statut → Sauvegarder.
Lecture de la Roadmap :
La barre de progression = (demandes fermées / total demandes de la version) × 100
Avec 1 demande fermée sur 4 du Sprint 1 → 25%
Les demandes encore ouvertes sont listées sous la barre
Lecture du Gantt :
Chaque demande apparaît comme une barre horizontale positionnée entre sa date de création et son échéance de version
Le Sprint 2 apparaît si ses demandes ont une date d’échéance définie
Redmine calcule la progression de la roadmap uniquement sur les demandes à statut “fermé” — les demandes “Résolues” ne comptent pas encore.
Exercice 09 - API REST : gestion de projet¶
Durée : 30 min
Utiliser l’API REST pour piloter le projet sans passer par l’interface web.
Remplacer VOTRE_CLE_API par la clé obtenue à l’exercice 9 (M1).
1. Lister les membres du projet
curl -H "X-Redmine-API-Key: VOTRE_CLE_API" `
http://localhost:3000/projects/gestion-sinistres/memberships.json2. Créer une nouvelle version via API
curl -X POST `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"version\": {\"name\": \"Sprint 3\", \"status\": \"open\", \"due_date\": \"2026-07-31\"}}" `
http://localhost:3000/projects/gestion-sinistres/versions.json3. Lister les versions du projet
curl -H "X-Redmine-API-Key: VOTRE_CLE_API" `
http://localhost:3000/projects/gestion-sinistres/versions.json4. Affecter une demande existante à la nouvelle version
Récupérer l’id du Sprint 3 dans la réponse de l’étape 3, puis :
curl -X PUT `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"issue\": {\"fixed_version_id\": ID_SPRINT3}}" `
http://localhost:3000/issues/ID_DEMANDE.json5. Fermer une version (fin de sprint)
curl -X PUT `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"version\": {\"status\": \"closed\"}}" `
http://localhost:3000/versions/ID_SPRINT1.jsonCritère de réussite : Sprint 3 créé et visible dans la roadmap, demande réaffectée, Sprint 1 fermé via API et non modifiable dans l’interface
Solution to Exercise 9 #
Réponse attendue à l’étape 2 (création version) :
{
"version": {
"id": 3,
"project": {"id": 1, "name": "Gestion des sinistres"},
"name": "Sprint 3",
"status": "open",
"due_date": "2026-07-31"
}
}L’id retourné (ici 3) est à utiliser aux étapes 4 et 5.
Étape 4 — remplacer ID_SPRINT3 par 3 et ID_DEMANDE par l’id d’une demande existante :
curl -X PUT `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"issue\": {\"fixed_version_id\": 3}}" `
http://localhost:3000/issues/5.jsonÉtape 5 — récupérer l’id du Sprint 1 via l’étape 3, puis fermer :
curl -X PUT `
-H "X-Redmine-API-Key: VOTRE_CLE_API" `
-H "Content-Type: application/json" `
-d "{\"version\": {\"status\": \"closed\"}}" `
http://localhost:3000/versions/1.jsonVérification : Menu Projet → Paramètres → Versions — le Sprint 1 apparaît en statut “Fermé” et n’accepte plus de nouvelles demandes.
Erreurs fréquentes :
422sur la fermeture de version → des demandes ouvertes sont encore affectées à cette version404sur/versions/ID→ l’id est incorrect, vérifier viaversions.json