Workflow git + PR de développement de features OpenIMIS (develop, Comores & CSU)
Objectif
Reporting : si ce travail vient d'un ticket Redmine, après implémentation/PR suivre le skill ticket-driver pour le reporting (statut recette, assignataire, capture) et l'envoi en recette — ne pas laisser le ticket sans mise à jour.
Créer les branches et ouvrir les PR d'une feature dans un ou plusieurs modules OpenIMIS (repo principal, Comores, CSU) en suivant la procédure validée, sans redemander la marche à suivre à l'utilisateur.
Espaces de travail et prérequis
- OpenIMIS principal :
/home/y-note/openimis
- Frontend :
/home/y-note/openimis/frontend-packages/<Module> (ex. ClaimModule, PaymentModule, LedgerModule)
- Backend :
/home/y-note/openimis/openimis-be-<module>_py (ex. openimis-be-core_py, openimis-be-contract_py)
- Assemblies exclues sauf mention explicite :
openimis-fe_js, openimis-be_py, openimis-dist_dkr
- Comores :
/home/y-note/openimis-comores/<module>_js (ex. openimis-fe-contribution_js, openimis-fe-payment_js)
- CSU :
/home/y-note/openimis-csu/<module>_js (ex. openimis-fe-claim_js)
- Remotes :
origin = openimis (repo de base des PR) ; ynote = Y-Note-SAS (fork de push, créé automatiquement par les scripts si absent)
- Scripts :
/home/y-note/mes_scripts/open-pr.sh (alias pr) et /home/y-note/mes_scripts/git-feature-fanout.sh (alias gff). En shell non interactif, appeler les scripts directement (les alias viennent de ~/.bashrc).
gh doit être authentifié avec le scope repo.
Validation avant fanout (obligatoire)
Avant de fanouter un changement vers les autres branches, le changement doit d'abord être testé et validé par l'utilisateur sur une seule branche :
- Le changement doit être implémenté, committé et testé sur une branche unique (la branche principale de la feature, ex.
feature-<n>).
- Faire valider le résultat par l'utilisateur (revue du diff, tests, rendu, etc.) avant toute diffusion vers d'autres branches.
- Ne lancer le fanout (
gff / cherry-pick vers les autres cibles) qu'après validation explicite de l'utilisateur.
- Ce principe s'applique à tous les cas de fanout : Comores (
test-comores/main-comores), CSU (hotfix-csu/release-csu) et toute autre cible.
Workflow OpenIMIS principal (develop) — 2 PRs par module
Chaque module modifié reçoit deux PRs successives (gitflow interne Y-Note) :
- PR de review :
feature-<n> (poussée sur ynote) → branche develop de Y-Note-SAS/<repo>. C'est la PR que le bot/la revue examine ; les corrections se font sur la branche de feature, dans cette même PR, jusqu'à validation.
- PR de publication : branche
develop de Y-Note-SAS/<repo> → branche develop de openimis/<repo>, une fois la PR de review mergée dans la develop du fork.
⚠️ On ne PR jamais directement feature-<n> vers openimis:develop (ancien flow) : la develop de ynote est le passage obligé, c'est elle qu'on merge dans openimis.
Étapes
Partir de origin/develop à jour : git fetch origin --prune puis git checkout -b feature-<n> origin/develop (n = numéro de feature transmis par l'utilisateur, ex. feature-37855).
Working tree propre obligatoire : vérifier git status --porcelain. S'il y a des changements non commités, ne pas les écraser : résumer ce qu'ils contiennent (git status, git diff --stat) et demander à l'utilisateur quoi en faire (stash, commit séparé, abandon, conserver).
Implémenter la feature puis committer en un seul commit (message descriptif, ex. add unit tests for claim pickers).
Pousser vers ynote : git push -u ynote feature-<n>. Si le remote ynote est absent : git remote add ynote https://github.com/Y-Note-SAS/<repo>.git.
PR 1 — vers la develop du fork (review) : vérifier d'abord que la branche existe sur le fork (git ls-remote --heads ynote refs/heads/develop) ; si elle est absente, la créer depuis origin/develop (git push ynote refs/remotes/origin/develop:refs/heads/develop). Puis, description remplie depuis le template officiel openIMIS (jamais --fill) :
gh pr create --repo Y-Note-SAS/<repo> --base develop --head feature-<n> --title "feature <n> — <description courte>" --body-file <fichier>
Revue / corrections dans la PR 1, puis merge de feature-<n> dans la develop du fork (revue humaine ou bot ; ne pas merger soi-même sauf demande explicite).
PR 2 — vers openimis (publication), seulement après le merge de la PR 1 :
- resynchroniser le fork si sa develop est en retard sur openimis (
git fetch origin --prune puis merger origin/develop dans ynote/develop) afin que la PR ne contienne que le travail Y-Note ;
gh pr create --repo openimis/<repo> --base develop --head Y-Note-SAS:develop --title "feature <n> — <description courte>" --body-file <fichier>
Vérifier les PRs ouvertes et les diffs ; rendre la main avec les liens, présentés séparément :
PRs vers Ynote
---
- <repo> : <lien PR 1 (feature-<n> → ynote develop)>
PRs vers openimis
---
- <repo> : <lien PR 2 (ynote develop → openimis develop)>
Template de description de PR openIMIS (obligatoire)
Les deux PRs (vers la develop du fork et vers openimis) utilisent ce template, rempli honnêtement.
Remplir chaque section du template officiel (source : openimis/.github/PULL_REQUEST_TEMPLATE.md) :
#Thank you for your contribution to openIMIS!
#Please complete the sections below. Anything in comments is guidance and can be deleted.
# Description
Description claire et concise du changement : pourquoi est-il nécessaire, quel problème résout-il ?
# Type of Change
- [x] Feature
- [ ] Bug fix
- [ ] Chore (Refactor, Docs, CI/CD)
- [ ] Other, please specify
## Related Issue(s) / Task(s)
- [ ] Requires [link to github PR], [link to github PR] needs to be merged first before this one
- [ ] Relates to [link to github PR], this needs to be merged before [link to github PR]
- [x] External reference (e.g., Jira): feature <n>
## Demo
Captures d'écran / gifs / lien de démo, ou « N/A » si non applicable.
## Checklist
- [x] Unit tests added/modified
- [x] I18n / translation handled
Cocher les cases réellement applicables (Type of Change, Checklist) et compléter les sections honnêtement.
Section « Related Issue(s) / Task(s) » — PR liées entre modules
Quand une feature touche plusieurs modules (plusieurs PR liées à la même feature), relier explicitement les PR entre elles, en plus de la référence externe feature <n> :
- PR dépendante (elle consomme un mécanisme/API ajouté par une autre PR, ex. un module qui utilise une nouvelle capacité de
fe-core, ou un frontend qui consomme de nouvelles requêtes GraphQL du backend) : cocher Requires et lister la PR prérequise, ex. :
- [x] Requires [openimis/openimis-fe-core_js#348](https://github.com/openimis/openimis-fe-core_js/pull/348), needs to be merged first before this one
- PR prérequise / de base (elle est consommée par d'autres PR de la même feature) : cocher
Relates to et lister les PR qui en dépendent, ex. :
- [x] Relates to [openimis/openimis-fe-contribution_js#64](https://github.com/openimis/openimis-fe-contribution_js/pull/64) and [openimis/openimis-fe-payment_js#39](https://github.com/openimis/openimis-fe-payment_js/pull/39), this needs to be merged before them
- Frontend ↔ backend : la PR frontend coche
Requires avec la PR backend dont elle consomme les requêtes ; la PR backend coche Relates to avec la PR frontend.
- Laisser les lignes non utilisées telles quelles (placeholders d'origine) ; ne cocher que les lignes réellement remplies.
Workflow Comores
git fetch origin --prune dans le module concerné.
- Créer
feature-<n> depuis origin/develop-comores à jour : git checkout -b feature-<n> origin/develop-comores.
- Committer la modification en un seul commit (message descriptif, ex.
disable manual payments in family overview page).
- PR principale :
pr -b develop-comores -r origin (pousse feature-<n> vers ynote et ouvre/actualise la PR vers mngoe develop-comores).
- Validation utilisateur obligatoire : avant tout fanout, faire tester et valider le changement par l'utilisateur sur cette branche/PR principale (voir « Validation avant fanout (obligatoire) »). Ne pas continuer sans validation explicite.
- Fanout :
gff -n 1 -r origin test-comores main-comores → crée feature-<n>-test-comores et feature-<n>-main-comores (cherry-pick du commit), les pousse vers ynote et ouvre les PR vers test-comores et main-comores.
- Même numéro de feature pour tous les modules touchés (ex.
feature-37791 dans contribution ET payment).
Workflow CSU
git fetch origin --prune.
- Créer
feature-<n> depuis test-csu : git checkout -b feature-<n> origin/test-csu.
- Committer la modification en un seul commit.
- PR principale :
pr -b test-csu -r origin.
- Validation utilisateur obligatoire : avant tout fanout, faire tester et valider le changement par l'utilisateur sur cette branche/PR principale (voir « Validation avant fanout (obligatoire) »). Ne pas continuer sans validation explicite.
- Fanout :
gff -n 1 -r origin <cible> où <cible> dépend de la typologie de déploiement :
hotfix-csu pour un correctif urgent ;
release-csu pour une fonctionnalité normale.
Si la typologie n'est pas claire, demander à l'utilisateur.
- Nommage des branches fanout :
feature-<n>-hotfix-csu / feature-<n>-release-csu.
Pièges connus
- GitHub refuse une PR sans commit : la PR 2 (
ynote develop → openimis develop) n'est possible qu'après le merge de la PR 1, sinon la branche de tête n'a rien de plus que la base.
- Un fork
ynote peut ne pas avoir de branche develop (cas constaté sur openimis-fe-policy_js, qui n'avait que main et des branches de feature) : la créer depuis origin/develop avant d'ouvrir la PR 1.
- Une develop de fork peut être en retard sur
openimis/develop (cas de openimis-fe-contribution_plan_js et openimis-be-policy_py) : la resynchroniser avant la PR 2 pour que le diff ne contienne que le travail Y-Note.
gff exige un working tree propre et revient sur la branche source à la fin (trap).
- Ne pas relancer
gff inutilement sur une branche déjà fanoutée : le script reset + re-cherry-pick (nouveaux SHAs) + force-push.
- Le script
pr crée la PR avec --fill (description = liste des commits) : dans le workflow OpenIMIS principal, ne pas l'utiliser pour la description — créer la PR avec gh pr create --body-file rempli depuis le template openIMIS.
- L'API GitHub renvoie parfois des 503 intermittents (pas un problème d'auth : 401/403 = auth/permissions, 503 = indisponibilité serveur). Réessayer avec backoff. Si
gff échoue seulement à l'étape création de PR (les branches sont déjà poussées sur ynote), créer les PR manuellement via REST :
gh api --method POST repos/mngoe/<repo>/pulls -f title="<titre>" -f head="Y-Note-SAS:<branche>" -f base="<base>" (avec retry + sleep).
- Après exécution : vérifier les PR ouvertes (
gh pr list --repo mngoe/<repo> --state open) et le diff avant de rendre la main ; résumer avec les liens des PR.
1---2name: openimis3description: Apply the standard git + PR workflow for a feature in OpenIMIS repos: main openIMIS (/home/y-note/openimis — frontend-packages modules and openimis-be-*_py backends: create feature-<n> from develop, commit once, push to ynote, open a PR to openimis develop with the description filled from the official openIMIS PR template) and OpenIMIS front-end modules under /home/y-note/openimis-comores and /home/y-note/openimis-csu (create feature-<n> from the correct base (develop-comores for Comores, test-csu for CSU), commit once, open the PR with the pr script, then fan out the same commit with the gff script to test-comores/main-comores for Comores or hotfix-csu/release-csu for CSU). Use when the user asks to develop an openimis feature (main repo, Comores or CSU), do 'le même travail'/'same work' in another module, or port a patch between modules.4---56# Workflow git + PR de développement de features OpenIMIS (develop, Comores & CSU)78## Objectif910> **Reporting** : si ce travail vient d'un ticket Redmine, après implémentation/PR suivre le skill **ticket-driver** pour le reporting (statut recette, assignataire, capture) et l'envoi en recette — ne pas laisser le ticket sans mise à jour.1112Créer les branches et ouvrir les PR d'une feature dans un ou plusieurs modules OpenIMIS (repo principal, Comores, CSU) en suivant la procédure validée, sans redemander la marche à suivre à l'utilisateur.1314## Espaces de travail et prérequis15- OpenIMIS principal : `/home/y-note/openimis`16 - Frontend : `/home/y-note/openimis/frontend-packages/<Module>` (ex. `ClaimModule`, `PaymentModule`, `LedgerModule`)17 - Backend : `/home/y-note/openimis/openimis-be-<module>_py` (ex. `openimis-be-core_py`, `openimis-be-contract_py`)18 - Assemblies exclues sauf mention explicite : `openimis-fe_js`, `openimis-be_py`, `openimis-dist_dkr`19- Comores : `/home/y-note/openimis-comores/<module>_js` (ex. `openimis-fe-contribution_js`, `openimis-fe-payment_js`)20- CSU : `/home/y-note/openimis-csu/<module>_js` (ex. `openimis-fe-claim_js`)21- Remotes : `origin` = openimis (repo de base des PR) ; `ynote` = Y-Note-SAS (fork de push, créé automatiquement par les scripts si absent)22- Scripts : `/home/y-note/mes_scripts/open-pr.sh` (alias `pr`) et `/home/y-note/mes_scripts/git-feature-fanout.sh` (alias `gff`). En shell non interactif, appeler les scripts directement (les alias viennent de `~/.bashrc`).23- `gh` doit être authentifié avec le scope `repo`.2425## Validation avant fanout (obligatoire)26Avant de fanouter un changement vers les autres branches, le changement doit d'abord être **testé et validé par l'utilisateur sur une seule branche** :27- Le changement doit être implémenté, committé et testé sur une branche unique (la branche principale de la feature, ex. `feature-<n>`).28- Faire valider le résultat par l'utilisateur (revue du diff, tests, rendu, etc.) avant toute diffusion vers d'autres branches.29- Ne lancer le fanout (`gff` / cherry-pick vers les autres cibles) qu'après validation explicite de l'utilisateur.30- Ce principe s'applique à **tous** les cas de fanout : Comores (`test-comores`/`main-comores`), CSU (`hotfix-csu`/`release-csu`) et toute autre cible.3132## Workflow OpenIMIS principal (develop) — 2 PRs par module3334Chaque module modifié reçoit **deux PRs successives** (gitflow interne Y-Note) :35361. **PR de review** : `feature-<n>` (poussée sur `ynote`) → branche `develop` de `Y-Note-SAS/<repo>`. C'est la PR que le bot/la revue examine ; les corrections se font sur la branche de feature, dans cette même PR, jusqu'à validation.372. **PR de publication** : branche `develop` de `Y-Note-SAS/<repo>` → branche `develop` de `openimis/<repo>`, **une fois la PR de review mergée** dans la develop du fork.3839⚠️ On ne PR **jamais** directement `feature-<n>` vers `openimis:develop` (ancien flow) : la develop de ynote est le passage obligé, c'est elle qu'on merge dans openimis.4041### Étapes421. Partir de `origin/develop` à jour : `git fetch origin --prune` puis `git checkout -b feature-<n> origin/develop` (`n` = numéro de feature transmis par l'utilisateur, ex. `feature-37855`).432. **Working tree propre obligatoire** : vérifier `git status --porcelain`. S'il y a des changements non commités, ne pas les écraser : résumer ce qu'ils contiennent (`git status`, `git diff --stat`) et demander à l'utilisateur quoi en faire (stash, commit séparé, abandon, conserver).443. Implémenter la feature puis committer en **un seul commit** (message descriptif, ex. `add unit tests for claim pickers`).454. Pousser vers `ynote` : `git push -u ynote feature-<n>`. Si le remote `ynote` est absent : `git remote add ynote https://github.com/Y-Note-SAS/<repo>.git`.465. **PR 1 — vers la develop du fork (review)** : vérifier d'abord que la branche existe sur le fork (`git ls-remote --heads ynote refs/heads/develop`) ; si elle est absente, la créer depuis `origin/develop` (`git push ynote refs/remotes/origin/develop:refs/heads/develop`). Puis, description remplie depuis le template officiel openIMIS (**jamais `--fill`**) :47 - `gh pr create --repo Y-Note-SAS/<repo> --base develop --head feature-<n> --title "feature <n> — <description courte>" --body-file <fichier>`486. Revue / corrections dans la PR 1, puis merge de `feature-<n>` dans la develop du fork (revue humaine ou bot ; ne pas merger soi-même sauf demande explicite).497. **PR 2 — vers openimis (publication)**, seulement après le merge de la PR 1 :50 - resynchroniser le fork si sa develop est en retard sur openimis (`git fetch origin --prune` puis merger `origin/develop` dans `ynote/develop`) afin que la PR ne contienne que le travail Y-Note ;51 - `gh pr create --repo openimis/<repo> --base develop --head Y-Note-SAS:develop --title "feature <n> — <description courte>" --body-file <fichier>`528. Vérifier les PRs ouvertes et les diffs ; rendre la main avec les liens, **présentés séparément** :5354 ```55 PRs vers Ynote56 ---57 - <repo> : <lien PR 1 (feature-<n> → ynote develop)>5859 PRs vers openimis60 ---61 - <repo> : <lien PR 2 (ynote develop → openimis develop)>62 ```6364### Template de description de PR openIMIS (obligatoire)65Les **deux** PRs (vers la develop du fork et vers openimis) utilisent ce template, rempli honnêtement.66Remplir chaque section du template officiel (source : `openimis/.github/PULL_REQUEST_TEMPLATE.md`) :6768```69#Thank you for your contribution to openIMIS!70#Please complete the sections below. Anything in comments is guidance and can be deleted.7172# Description7374Description claire et concise du changement : pourquoi est-il nécessaire, quel problème résout-il ?7576# Type of Change7778- [x] Feature79- [ ] Bug fix80- [ ] Chore (Refactor, Docs, CI/CD)81- [ ] Other, please specify8283## Related Issue(s) / Task(s)84- [ ] Requires [link to github PR], [link to github PR] needs to be merged first before this one85- [ ] Relates to [link to github PR], this needs to be merged before [link to github PR]86- [x] External reference (e.g., Jira): feature <n>8788## Demo8990Captures d'écran / gifs / lien de démo, ou « N/A » si non applicable.9192## Checklist93- [x] Unit tests added/modified94- [x] I18n / translation handled95```9697Cocher les cases réellement applicables (Type of Change, Checklist) et compléter les sections honnêtement.9899### Section « Related Issue(s) / Task(s) » — PR liées entre modules100101Quand une feature touche plusieurs modules (plusieurs PR liées à la même feature), relier explicitement les PR entre elles, en plus de la référence externe `feature <n>` :102103- **PR dépendante** (elle consomme un mécanisme/API ajouté par une autre PR, ex. un module qui utilise une nouvelle capacité de `fe-core`, ou un frontend qui consomme de nouvelles requêtes GraphQL du backend) : cocher `Requires` et lister la PR prérequise, ex. :104 `- [x] Requires [openimis/openimis-fe-core_js#348](https://github.com/openimis/openimis-fe-core_js/pull/348), needs to be merged first before this one`105- **PR prérequise / de base** (elle est consommée par d'autres PR de la même feature) : cocher `Relates to` et lister les PR qui en dépendent, ex. :106 `- [x] Relates to [openimis/openimis-fe-contribution_js#64](https://github.com/openimis/openimis-fe-contribution_js/pull/64) and [openimis/openimis-fe-payment_js#39](https://github.com/openimis/openimis-fe-payment_js/pull/39), this needs to be merged before them`107- **Frontend ↔ backend** : la PR frontend coche `Requires` avec la PR backend dont elle consomme les requêtes ; la PR backend coche `Relates to` avec la PR frontend.108- Laisser les lignes non utilisées telles quelles (placeholders d'origine) ; ne cocher que les lignes réellement remplies.109110## Workflow Comores1111. `git fetch origin --prune` dans le module concerné.1122. Créer `feature-<n>` depuis `origin/develop-comores` à jour : `git checkout -b feature-<n> origin/develop-comores`.1133. Committer la modification en **un seul commit** (message descriptif, ex. `disable manual payments in family overview page`).1144. PR principale : `pr -b develop-comores -r origin` (pousse `feature-<n>` vers `ynote` et ouvre/actualise la PR vers mngoe `develop-comores`).1155. **Validation utilisateur obligatoire** : avant tout fanout, faire tester et valider le changement par l'utilisateur sur cette branche/PR principale (voir « Validation avant fanout (obligatoire) »). Ne pas continuer sans validation explicite.1166. Fanout : `gff -n 1 -r origin test-comores main-comores` → crée `feature-<n>-test-comores` et `feature-<n>-main-comores` (cherry-pick du commit), les pousse vers `ynote` et ouvre les PR vers `test-comores` et `main-comores`.117- Même numéro de feature pour tous les modules touchés (ex. `feature-37791` dans contribution ET payment).118119## Workflow CSU1201. `git fetch origin --prune`.1212. Créer `feature-<n>` depuis `test-csu` : `git checkout -b feature-<n> origin/test-csu`.1223. Committer la modification en un seul commit.1234. PR principale : `pr -b test-csu -r origin`.1245. **Validation utilisateur obligatoire** : avant tout fanout, faire tester et valider le changement par l'utilisateur sur cette branche/PR principale (voir « Validation avant fanout (obligatoire) »). Ne pas continuer sans validation explicite.1256. Fanout : `gff -n 1 -r origin <cible>` où `<cible>` dépend de la typologie de déploiement :126 - `hotfix-csu` pour un correctif urgent ;127 - `release-csu` pour une fonctionnalité normale.128 Si la typologie n'est pas claire, demander à l'utilisateur.129- Nommage des branches fanout : `feature-<n>-hotfix-csu` / `feature-<n>-release-csu`.130131## Pièges connus132- GitHub **refuse une PR sans commit** : la PR 2 (`ynote develop` → `openimis develop`) n'est possible qu'après le merge de la PR 1, sinon la branche de tête n'a rien de plus que la base.133- Un fork `ynote` **peut ne pas avoir de branche `develop`** (cas constaté sur `openimis-fe-policy_js`, qui n'avait que `main` et des branches de feature) : la créer depuis `origin/develop` avant d'ouvrir la PR 1.134- Une develop de fork peut être **en retard** sur `openimis/develop` (cas de `openimis-fe-contribution_plan_js` et `openimis-be-policy_py`) : la resynchroniser avant la PR 2 pour que le diff ne contienne que le travail Y-Note.135- `gff` exige un working tree propre et revient sur la branche source à la fin (trap).136- Ne pas relancer `gff` inutilement sur une branche déjà fanoutée : le script reset + re-cherry-pick (nouveaux SHAs) + force-push.137- Le script `pr` crée la PR avec `--fill` (description = liste des commits) : dans le workflow OpenIMIS principal, ne pas l'utiliser pour la description — créer la PR avec `gh pr create --body-file` rempli depuis le template openIMIS.138- L'API GitHub renvoie parfois des 503 intermittents (pas un problème d'auth : 401/403 = auth/permissions, 503 = indisponibilité serveur). Réessayer avec backoff. Si `gff` échoue seulement à l'étape création de PR (les branches sont déjà poussées sur `ynote`), créer les PR manuellement via REST :139 `gh api --method POST repos/mngoe/<repo>/pulls -f title="<titre>" -f head="Y-Note-SAS:<branche>" -f base="<base>"` (avec retry + sleep).140- Après exécution : vérifier les PR ouvertes (`gh pr list --repo mngoe/<repo> --state open`) et le diff avant de rendre la main ; résumer avec les liens des PR.