From ed39b16bb9604c7935a400a3ed294d5d6ea56408 Mon Sep 17 00:00:00 2001 From: Sylvain Aurat Date: Tue, 14 Jul 2026 09:32:23 +0200 Subject: [PATCH 1/8] docs: simplify French catalog versioning guide --- doc/CatalogVersioning.fr.md | 272 ++++++++++++++---------------------- 1 file changed, 105 insertions(+), 167 deletions(-) diff --git a/doc/CatalogVersioning.fr.md b/doc/CatalogVersioning.fr.md index 391625f..04027f7 100644 --- a/doc/CatalogVersioning.fr.md +++ b/doc/CatalogVersioning.fr.md @@ -1,226 +1,164 @@ # Versionnage du catalogue -🌍 **Langues:** +🌍 **Langues :** 🇬🇧 [English](./CatalogVersioning.en.md) | đŸ‡«đŸ‡· Français (ce fichier) -Un code d'erreur ne reste pas Ă  l'intĂ©rieur du systĂšme qui l'Ă©met. Des applications clientes branchent leur logique dessus, des tableaux de bord dĂ©clenchent des alertes dessus, des procĂ©dures de support y font rĂ©fĂ©rence. Supprimer ou renommer un code est donc un **changement cassant** — de mĂȘme nature que la suppression d'un membre d'API publique — et mĂ©rite le mĂȘme garde-fou : une rĂ©fĂ©rence commitĂ©e, et une Ă©tape de CI qui Ă©choue quand le contrat dĂ©rive par accident. +Un code d'erreur ne reste pas Ă  l'intĂ©rieur du systĂšme qui l'Ă©met. Des applications clientes branchent leur logique dessus, des tableaux de bord dĂ©clenchent des alertes dessus et des procĂ©dures de support y font rĂ©fĂ©rence. -FirstClassErrors fournit ce garde-fou avec deux commandes : `fce catalog update` et `fce catalog diff`. +Supprimer ou renommer un code est donc un **changement cassant**, de mĂȘme nature que la suppression d'un membre d'API publique. FirstClassErrors permet de rendre ce changement visible dans la pull request avant qu'il n'atteigne la production. -## đŸ§Ÿ Le snapshot de contrat +## 🧭 Le fonctionnement en une minute -L'unitĂ© de comparaison est le **snapshot canonique** : une petite projection JSON dĂ©terministe du catalogue, contenant uniquement ce qui constitue le contrat. +```mermaid +flowchart LR + A[Catalogue extrait du code] --> B[Snapshot courant] + C[errors-baseline.json\ncontrat acceptĂ©] --> D[fce catalog diff] + B --> D + D --> E[Rapport des changements] + E --> F[Corriger le changement] + E --> G[Ou l'accepter explicitement] + G --> C +``` + +Trois notions suffisent : + +- le **snapshot** est la reprĂ©sentation canonique du contrat du catalogue Ă  un instant donnĂ© ; +- la **baseline** est le snapshot acceptĂ©, commitĂ© dans le dĂ©pĂŽt sous la forme de `errors-baseline.json` ; +- `fce catalog diff` compare le snapshot courant Ă  cette baseline. + +Autrement dit, la baseline rĂ©pond Ă  la question : + +> « Quels codes d'erreur et quelles donnĂ©es de contexte avons-nous explicitement promis de conserver ? » + +## đŸ§Ÿ Ce qui fait partie du contrat -| Suivi | RĂŽle | +Le snapshot ne contient que les informations nĂ©cessaires pour dĂ©tecter une rupture de contrat. + +| ÉlĂ©ment suivi | Pourquoi il est suivi | | --- | --- | -| `code` | L'identitĂ© de l'erreur. Sa suppression est cassante. | -| `context` (nom de clĂ© + type de valeur) | Les donnĂ©es structurĂ©es attachĂ©es aux occurrences. Les pipelines de logs et les tableaux de bord les lisent par leur nom ; une suppression ou un changement de type est cassant. | -| `title`, `source` | IdentitĂ© documentaire — les changements sont signalĂ©s Ă  titre informatif, et les titres identiques servent d'indice de renommage probable. | +| `code` | C'est l'identitĂ© stable de l'erreur. Sa suppression est cassante. | +| `context` : nom de clĂ© et type de valeur | Les pipelines de logs, tableaux de bord et outils de support peuvent lire ces donnĂ©es par leur nom et leur type. | +| `title`, `source` | Ils aident Ă  expliquer les changements et Ă  dĂ©tecter un renommage probable. Leur modification est seulement informative. | -Les messages, explications, rĂšgles mĂ©tier et diagnostics ne sont dĂ©libĂ©rĂ©ment **pas** suivis : c'est de la documentation, extraite d'exemples vivants, libre d'Ă©voluer sans toucher au contrat. +Les messages, explications, rĂšgles mĂ©tier et diagnostics ne sont volontairement **pas** versionnĂ©s comme un contrat. Ils constituent de la documentation et peuvent Ă©voluer sans casser un consommateur. -Le snapshot est indĂ©pendant du renderer : que le catalogue destinĂ© aux humains soit publiĂ© en HTML, Markdown, JSON ou dans un format personnalisĂ©, c'est le mĂȘme fichier de contrat qui pilote le versionnage. Il est dĂ©terministe — erreurs triĂ©es par code, clĂ©s de contexte par nom, fins de ligne fixĂ©es — si bien que le fichier commitĂ© ne dĂ©pend jamais de la machine qui l'a produit. Les commandes `fce catalog` l'extraient toujours sous la culture `en`, de sorte que la baseline reste indĂ©pendante de la langue mĂȘme quand votre catalogue est localisĂ© (voir [Internationalisation](Internationalisation.fr.md)). +## 📌 Mise en place initiale -## 📌 CrĂ©er la baseline +### 1. CrĂ©er la baseline ```bash fce catalog update --solution MyApp.sln ``` -Cette commande extrait le catalogue, le projette en snapshot et Ă©crit `errors-baseline.json` (modifiable avec `--baseline`, ou via `baseline` dans `fce.json`). **Commitez ce fichier** : c'est le contrat acceptĂ©, et chaque modification passe en revue de code comme n'importe quel autre changement de contrat. - -**En CI/CD**, initialisez-la automatiquement au premier passage pour que personne n'ait Ă  y penser — crĂ©ez et commitez le fichier uniquement s'il est absent. Cela relĂšve d'un push sur votre branche par dĂ©faut et nĂ©cessite un jeton capable de pousser : - -```yaml -# Se dĂ©clenche sur push vers main ; nĂ©cessite : permissions: { contents: write }. -- name: Seed the error-catalog baseline if missing - run: | - if [ ! -f errors-baseline.json ]; then - fce catalog update --solution MyApp.sln - git add errors-baseline.json - git -c user.name='github-actions[bot]' \ - -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ - commit -m 'chore: seed the error-catalog baseline' - git push - fi +La commande extrait le catalogue et crĂ©e `errors-baseline.json`. + +> `catalog update` signifie **accepter le contrat courant**. La commande ne corrige pas une incompatibilitĂ© : elle remplace la rĂ©fĂ©rence par l'Ă©tat actuel du catalogue. + +### 2. Examiner le fichier gĂ©nĂ©rĂ© + +Une baseline ressemble Ă  ceci : + +```json +{ + "schema": 1, + "errors": [ + { + "code": "PAYMENT_DECLINED", + "source": "Payment", + "title": "Payment declined", + "context": [ + { + "key": "PaymentId", + "valueType": "System.Guid" + } + ] + } + ] +} +``` + +Ce fichier est dĂ©terministe : les erreurs sont triĂ©es par code et les clĂ©s de contexte par nom. Un mĂȘme catalogue produit donc le mĂȘme fichier sur toutes les machines. + +### 3. Commiter la baseline + +```bash +git add errors-baseline.json +git commit -m "chore: add error catalog baseline" ``` -PrĂ©fĂ©rez une initialisation locale unique (lancez `fce catalog update` puis commitez) si vous voulez garder la CI en lecture seule — seul `catalog diff` a vraiment besoin de s'exĂ©cuter Ă  chaque pull request. +La baseline devient alors le contrat acceptĂ© par l'Ă©quipe. Toute modification ultĂ©rieure apparaĂźt dans le diff Git de la pull request. -## 🔍 DĂ©tecter la dĂ©rive en CI +### 4. VĂ©rifier le contrat ```bash fce catalog diff --solution MyApp.sln ``` -La commande extrait le catalogue courant, le compare Ă  la baseline et Ă©crit un rapport sur la sortie standard. Son code de sortie est conçu pour les pipelines : +Cette commande extrait le catalogue courant, le compare Ă  la baseline et affiche les changements dĂ©tectĂ©s. -| Code de sortie | Signification | -| --- | --- | -| `0` | Aucun changement au niveau du seuil `--fail-on` ou au-dessus. | -| `2` | Le contrat a dĂ©rivĂ© : au moins un changement atteint le seuil. | -| `1` | Erreur d'exĂ©cution — baseline manquante, extraction en Ă©chec, ou baseline Ă©crite par un schĂ©ma plus rĂ©cent (voir plus bas). | -| `130` | Interrompu avant la fin (Ctrl+C). | +Pour une intĂ©gration complĂšte dans GitHub Actions ou GitLab CI, consultez le guide [IntĂ©grer le versionnage du catalogue en CI/CD](CatalogVersioningCI.fr.md). -`--fail-on` choisit la politique : `breaking` (dĂ©faut), `any` (tout changement fait Ă©chouer, y compris les ajouts) ou `none` (rapport seul). `--report` choisit la sortie : `text` (dĂ©faut), `markdown` (prĂȘt Ă  poster en commentaire de pull request) ou `json` (pour l'outillage). +## 🔁 Le workflow quotidien -## 🧼 Classification des changements +### Aucun changement -| Changement | Impact | -| --- | --- | -| Code d'erreur supprimĂ© | đŸ’„ Cassant | -| ClĂ© de contexte supprimĂ©e | đŸ’„ Cassant | -| Type de valeur d'une clĂ© de contexte modifiĂ© | đŸ’„ Cassant | -| Code d'erreur ajoutĂ© | ✅ Compatible | -| ClĂ© de contexte ajoutĂ©e | ✅ Compatible | -| Titre ou source modifiĂ© | â„č Informatif | +La commande retourne `0` et indique que le catalogue n'a pas changĂ©. -Un **renommage** est une suppression plus un ajout — et reste cassant, car les consommateurs connaissent l'ancien code. Quand exactement une erreur ajoutĂ©e porte le mĂȘme titre que l'erreur supprimĂ©e, le rapport ajoute un indice : *« possibly renamed to 'NEW_CODE', which has the same title »*. +### Changement compatible -## ✍ Accepter un changement dĂ©libĂ©rĂ©ment +L'ajout d'un code d'erreur ou d'une clĂ© de contexte est signalĂ©, mais ne fait pas Ă©chouer la commande avec la politique par dĂ©faut. -Quand un changement de contrat est intentionnel, rafraĂźchissez la baseline et commitez-la : +Le dĂ©veloppeur peut ensuite mettre Ă  jour la baseline afin que le nouveau contrat soit commitĂ© : ```bash fce catalog update --solution MyApp.sln +git add errors-baseline.json +git commit -m "chore: update error catalog baseline" ``` -La commande rĂ©sume ce qu'elle absorbe (`1 breaking, 2 compatible and 0 documentation change(s) accepted`), et la pull request montre alors le diff de la baseline — un code supprimĂ© apparaĂźt comme une ligne supprimĂ©e. L'accident devient impossible ; le changement dĂ©libĂ©rĂ© devient visible et relisible. C'est la mĂȘme discipline qu'un fichier de baseline d'API publique, appliquĂ©e au catalogue d'erreurs. - -**En CI/CD**, faites de l'acceptation une action unique plutĂŽt qu'une Ă©tape locale manuelle : sur une pull request portant le label `accept-contract-change`, rĂ©gĂ©nĂ©rez la baseline et recommitez-la sur la branche de la PR, pour que le changement apparaisse comme un diff explicite et relisible (fonctionne pour les branches du mĂȘme dĂ©pĂŽt ; depuis un fork, lancez `fce catalog update` en local et poussez) : - -```yaml -# .github/workflows/error-catalog-accept.yml -on: - pull_request: - types: [labeled] - -jobs: - accept: - if: github.event.label.name == 'accept-contract-change' - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.ref }} - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '10.0.x' - # Rendez fce disponible sur le runner (voir l'exemple complet plus bas). - - name: Regenerate and commit the baseline - run: | - fce catalog update --solution MyApp.sln - git add errors-baseline.json - if git diff --cached --quiet; then - echo 'Baseline already up to date — nothing to accept.' - else - git -c user.name='github-actions[bot]' \ - -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ - commit -m 'chore: accept error-catalog contract change' - git push - fi -``` - -Pour un flux purement local, les deux mĂȘmes lignes derriĂšre une cible `make accept-errors` font tout aussi bien l'affaire. +### Changement cassant -## đŸ›Ąïž RĂ©silience de la baseline & versionnage du schĂ©ma +La suppression d'un code, la suppression d'une clĂ© de contexte ou la modification de son type fait retourner le code `2`. La CI peut utiliser ce code pour bloquer la pull request. -La baseline est un fichier versionnĂ© : au fil de la vie d'un projet, elle peut ĂȘtre corrompue par un merge malheureux ou produite par une version diffĂ©rente de l'outil. `fce catalog update` traite chaque cas de façon dĂ©libĂ©rĂ©e plutĂŽt que silencieuse : +Le dĂ©veloppeur doit alors choisir explicitement entre deux actions : -* **Une baseline corrompue ou illisible est rĂ©gĂ©nĂ©rĂ©e, jamais fatale.** Mettre Ă  jour, c'est prĂ©cisĂ©ment la façon de (re)construire une baseline : un fichier existant impossible Ă  parser est réécrit Ă  partir du catalogue courant, avec un avertissement — une baseline cassĂ©e ne vous bloque jamais. -* **Une baseline Ă©crite par un schĂ©ma _plus rĂ©cent_ est refusĂ©e, jamais rĂ©trogradĂ©e.** Chaque snapshot porte une version de `schema`. Si un collĂšgue a commitĂ© une baseline avec un outil plus rĂ©cent, un outil plus ancien ne l'Ă©crasera pas avec un schĂ©ma plus ancien — cela supprimerait silencieusement de l'information — : il s'arrĂȘte avec une erreur vous invitant Ă  mettre Ă  jour. `fce catalog diff` la refuse de la mĂȘme maniĂšre. Mettre Ă  jour l'outil, ou aligner les versions dans l'Ă©quipe, rĂ©sout le problĂšme. +1. **Le changement est accidentel** : il corrige le code afin de restaurer le contrat. +2. **Le changement est volontaire** : il exĂ©cute `fce catalog update`, vĂ©rifie le diff de `errors-baseline.json`, puis le committe. -Ainsi `fce catalog update` sort `0` quand la baseline est créée, dĂ©jĂ  Ă  jour ou rafraĂźchie (y compris auto-rĂ©parĂ©e) ; `1` sur une erreur d'exĂ©cution ou une baseline de schĂ©ma trop rĂ©cent ; et `130` en cas d'interruption. +Ainsi, un changement cassant n'est pas interdit ; il ne peut simplement plus ĂȘtre introduit silencieusement. -## ⚙ Des snapshots sans baseline +## đŸ§Ș Exemple : renommage d'un code -Deux autres façons de produire et comparer des snapshots : +Un dĂ©veloppeur renomme `PAYMENT.DECLINED` en `PAYMENT.REFUSED` pendant un refactoring. -* `fce generate --snapshot ` Ă©crit aussi le snapshot canonique Ă  cĂŽtĂ© du format rendu, quel qu'il soit — une seule gĂ©nĂ©ration produit Ă  la fois le catalogue pour les humains et le fichier de contrat. Il reflĂšte la langue de rendu `--language` ; lorsqu'elle n'est pas l'anglais, la commande Ă©met un avertissement, car une baseline commitĂ©e doit rester indĂ©pendante de la langue — utilisez `fce catalog update` (ou `--language en`) pour cela. -* `fce catalog diff --against ` compare la baseline Ă  un **fichier** de snapshot au lieu d'extraire depuis la source — utile pour comparer deux artefacts de release. +Pour un consommateur, ce n'est pas un simple renommage : l'ancien code disparaĂźt et un nouveau code apparaĂźt. Le rapport ressemble donc Ă  ceci : -`baseline` et `snapshot` peuvent ĂȘtre dĂ©finis dans `fce.json` pour ne pas rĂ©pĂ©ter les chemins Ă  chaque exĂ©cution. - -## 🚩 IntĂ©gration CI/CD : un exemple complet - -L'objectif de l'intĂ©gration CI est simple : **la dĂ©rive du contrat doit ĂȘtre visible lĂ  oĂč le changement est relu** — dans la pull request elle-mĂȘme, pas dans un log que personne ne lit. La boucle est la suivante : - -1. Chaque pull request exĂ©cute `fce catalog diff` contre la baseline commitĂ©e. -2. **Aucun changement** → le job passe silencieusement. -3. **Changements compatibles ou documentaires** → le job passe quand mĂȘme (avec le `--fail-on breaking` par dĂ©faut) ; le rapport peut ĂȘtre postĂ© pour information. -4. **Changement cassant** → le code de sortie `2` fait Ă©chouer le job, et le rapport Markdown atterrit en commentaire de la pull request. L'auteur n'a alors que deux issues honnĂȘtes : corriger la suppression accidentelle, ou l'accepter dĂ©libĂ©rĂ©ment avec `fce catalog update` — auquel cas le relecteur voit le diff de la baseline (le code supprimĂ© apparaĂźt comme une ligne supprimĂ©e) et approuve un changement cassant *en connaissance de cause*. - -DĂ©roulĂ© sur un scĂ©nario concret : un dĂ©veloppeur renomme `PAYMENT.DECLINED` en `PAYMENT.REFUSED` au cours d'un refactoring. Sans le garde-fou, le renommage part silencieusement et chaque tableau de bord ou client branchĂ© sur l'ancien code casse en production. Avec lui, la pull request Ă©choue avec : - -``` +```text Breaking changes (1): - [removed] PAYMENT.DECLINED — error removed (possibly renamed to 'PAYMENT.REFUSED', which has the same title) Compatible changes (1): - [added] PAYMENT.REFUSED — new error 'Payment declined' (source: Payment) ``` -Si le renommage Ă©tait accidentel, le dĂ©veloppeur le corrige. S'il Ă©tait dĂ©libĂ©rĂ©, il exĂ©cute `fce catalog update`, committe `errors-baseline.json`, et le changement de contrat devient une partie explicite et relisible de la pull request. - -### GitHub Actions - -```yaml -name: error-catalog - -on: - pull_request: - branches: [main] - -jobs: - catalog-diff: - runs-on: ubuntu-latest - permissions: - pull-requests: write # needed to post the report as a comment - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '10.0.x' +Si le renommage Ă©tait accidentel, le dĂ©veloppeur le corrige. S'il Ă©tait volontaire, la mise Ă  jour de la baseline rend la suppression visible dans la pull request et permet au relecteur de l'approuver en connaissance de cause. - # Make fce available on the runner (dotnet tool install, a cached - # build from source, or your internal distribution). - - - name: Compare the catalog against the baseline - run: fce catalog diff --solution MyApp.sln --report markdown > catalog-diff.md - # Exit code 2 (breaking change) fails this step, and therefore the job. - - - name: Post the report on the pull request - if: failure() # comment only when the contract drifted - run: gh pr comment ${{ github.event.pull_request.number }} --body-file catalog-diff.md - env: - GH_TOKEN: ${{ github.token }} -``` +## 🧼 Classification des changements -Deux comportements Ă  noter : le rapport est gĂ©nĂ©rĂ© *avant* que l'Ă©tape n'Ă©choue (la redirection capture la sortie standard, puis le code de sortie fait Ă©chouer l'Ă©tape), et l'Ă©tape de commentaire ne s'exĂ©cute que sur `if: failure()` — un pipeline sain reste silencieux. - -### GitLab CI - -```yaml -error-catalog: - stage: test - image: mcr.microsoft.com/dotnet/sdk:10.0 - script: - # Make fce available on the runner (dotnet tool install, a cached - # build from source, or your internal distribution). - - fce catalog diff --solution MyApp.sln --report markdown > catalog-diff.md - artifacts: - when: always # keep the report even when the job fails on a breaking change - paths: - - catalog-diff.md -``` +| Changement | Impact par dĂ©faut | +| --- | --- | +| Code d'erreur supprimĂ© | đŸ’„ Cassant | +| ClĂ© de contexte supprimĂ©e | đŸ’„ Cassant | +| Type d'une clĂ© de contexte modifiĂ© | đŸ’„ Cassant | +| Code d'erreur ajoutĂ© | ✅ Compatible | +| ClĂ© de contexte ajoutĂ©e | ✅ Compatible | +| Titre ou source modifiĂ© | â„č Informatif | -Le code de sortie pilote le rĂ©sultat du job exactement comme sur GitHub ; `artifacts: when: always` garde le rapport tĂ©lĂ©chargeable depuis le pipeline en Ă©chec, et il peut ĂȘtre postĂ© sur la merge request via l'[API notes](https://docs.gitlab.com/ee/api/notes.html) si vous souhaitez aussi automatiser le commentaire. +Un renommage reste cassant, car les consommateurs connaissent l'ancien code. Lorsque le titre permet d'identifier un renommage probable, le rapport ajoute seulement un indice pour aider le dĂ©veloppeur ; il ne transforme pas le changement en opĂ©ration compatible. -### Au-delĂ  des pull requests +## 📚 Aller plus loin -ExĂ©cuter le mĂȘme `fce catalog diff` sur la branche principale (Ă  chaque push ou de façon planifiĂ©e) attrape les dĂ©rives qui auraient contournĂ© le flux de pull request, et `fce catalog diff --against` permet Ă  un pipeline de release de comparer deux snapshots publiĂ©s — par exemple celui livrĂ© avec la release prĂ©cĂ©dente contre celui du candidat — pour gĂ©nĂ©rer des notes de version du contrat d'erreurs. +- [RĂ©fĂ©rence des commandes, du fichier de baseline et des codes de sortie](CatalogVersioningReference.fr.md) +- [IntĂ©gration CI/CD : GitHub Actions, GitLab CI et workflows avancĂ©s](CatalogVersioningCI.fr.md) --- From c96da844a27be9c2dd0121b1dce11f3a213499b6 Mon Sep 17 00:00:00 2001 From: Sylvain Aurat Date: Tue, 14 Jul 2026 09:41:58 +0200 Subject: [PATCH 2/8] docs: clarify catalog versioning guide --- doc/CatalogVersioning.en.md | 272 ++++++++++++++---------------------- 1 file changed, 105 insertions(+), 167 deletions(-) diff --git a/doc/CatalogVersioning.en.md b/doc/CatalogVersioning.en.md index ee150f6..3907e6e 100644 --- a/doc/CatalogVersioning.en.md +++ b/doc/CatalogVersioning.en.md @@ -3,224 +3,162 @@ 🌍 **Languages:** 🇬🇧 English (this file) | đŸ‡«đŸ‡· [Français](./CatalogVersioning.fr.md) -An error code does not stay inside the system that emits it. Client applications branch on it, dashboards alert on it, support procedures reference it. Removing or renaming a code is therefore a **breaking change** — of the same nature as removing a public API member — and it deserves the same guardrail: a committed reference, and a CI step that fails when the contract drifts by accident. +An error code does not stay inside the system that emits it. Client applications branch on it, dashboards alert on it, and support procedures reference it. -FirstClassErrors provides that guardrail through two commands: `fce catalog update` and `fce catalog diff`. +Removing or renaming a code is therefore a **breaking change**, just like removing a public API member. FirstClassErrors makes that change visible in the pull request before it reaches production. -## đŸ§Ÿ The contract snapshot +## 🧭 How it works in one minute -The unit of comparison is the **canonical snapshot**: a small, deterministic JSON projection of the catalog containing only what constitutes the contract. +```mermaid +flowchart LR + A[Catalog extracted from code] --> B[Current snapshot] + C[errors-baseline.json\naccepted contract] --> D[fce catalog diff] + B --> D + D --> E[Change report] + E --> F[Fix the change] + E --> G[Or accept it explicitly] + G --> C +``` + +Three concepts are enough: + +- a **snapshot** is the canonical representation of the catalog contract at a given point in time; +- the **baseline** is the accepted snapshot committed to the repository as `errors-baseline.json`; +- `fce catalog diff` compares the current snapshot with that baseline. + +In other words, the baseline answers this question: + +> “Which error codes and context data have we explicitly promised to preserve?” + +## đŸ§Ÿ What belongs to the contract -| Tracked | Role | +The snapshot contains only the information required to detect a contract break. + +| Tracked element | Why it is tracked | | --- | --- | -| `code` | The identity of the error. Its removal is breaking. | -| `context` (key name + value type) | The structured data attached to occurrences. Log pipelines and dashboards read these by name; a removal or a type change is breaking. | -| `title`, `source` | Documentation identity — changes are reported as informational, and matching titles are used to hint at probable renames. | +| `code` | The stable identity of the error. Removing it is breaking. | +| `context`: key name and value type | Log pipelines, dashboards, and support tooling may read these values by name and type. | +| `title`, `source` | They help explain changes and detect probable renames. Changing them is informational only. | -Messages, explanations, business rules and diagnostics are deliberately **not** tracked: they are documentation, extracted from live examples, and free to evolve without touching the contract. +Messages, explanations, business rules, and diagnostics are deliberately **not** versioned as contract data. They are documentation and may evolve without breaking a consumer. -The snapshot is independent of the renderer: whether you publish the human-facing catalog as HTML, Markdown, JSON or a custom format, the same contract file drives versioning. It is deterministic — errors ordered by code, context keys by name, pinned line endings — so the committed file never depends on the machine that produced it. The `fce catalog` commands always extract it under the `en` culture, so the baseline stays culture-independent even when your catalog is localized (see [Internationalization](Internationalization.en.md)). +## 📌 Initial setup -## 📌 Create the baseline +### 1. Create the baseline ```bash fce catalog update --solution MyApp.sln ``` -This extracts the catalog, projects it into its snapshot, and writes `errors-baseline.json` (override with `--baseline`, or set `baseline` in `fce.json`). **Commit this file**: it is the accepted contract, and every change to it goes through code review like any other contract change. - -**In CI/CD**, seed it automatically the first time so no one has to remember to bootstrap it — create and commit the file only when it is missing. This belongs on a push to your default branch, and needs a token that can push: - -```yaml -# Runs on push to main; needs: permissions: { contents: write }. -- name: Seed the error-catalog baseline if missing - run: | - if [ ! -f errors-baseline.json ]; then - fce catalog update --solution MyApp.sln - git add errors-baseline.json - git -c user.name='github-actions[bot]' \ - -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ - commit -m 'chore: seed the error-catalog baseline' - git push - fi +The command extracts the catalog and creates `errors-baseline.json`. + +> `catalog update` means **accept the current contract**. It does not fix an incompatibility: it replaces the reference with the current catalog state. + +### 2. Inspect the generated file + +A baseline looks like this: + +```json +{ + "schema": 1, + "errors": [ + { + "code": "PAYMENT_DECLINED", + "source": "Payment", + "title": "Payment declined", + "context": [ + { + "key": "PaymentId", + "valueType": "System.Guid" + } + ] + } + ] +} +``` + +The file is deterministic: errors are ordered by code and context keys by name. The same catalog therefore produces the same file on every machine. + +### 3. Commit the baseline + +```bash +git add errors-baseline.json +git commit -m "chore: add error catalog baseline" ``` -Prefer a one-time local bootstrap (run `fce catalog update` and commit) if you would rather keep CI read-only — only `catalog diff` truly needs to run on every pull request. +The baseline is now the contract accepted by the team. Every later modification appears in the pull-request Git diff. -## 🔍 Detect drift in CI +### 4. Verify the contract ```bash fce catalog diff --solution MyApp.sln ``` -The command extracts the current catalog, compares it against the baseline, and writes a report to standard output. Its exit code is designed for pipelines: +This command extracts the current catalog, compares it with the baseline, and reports the detected changes. -| Exit code | Meaning | -| --- | --- | -| `0` | No change at or above the `--fail-on` threshold. | -| `2` | The contract drifted: at least one change reaches the threshold. | -| `1` | Execution error — a missing baseline, a failed extraction, or a baseline written by a newer schema (see below). | -| `130` | Cancelled before completing (Ctrl+C). | +For complete GitHub Actions or GitLab CI integration, see [Integrating catalog versioning into CI/CD](CatalogVersioningCI.en.md). -`--fail-on` selects the policy: `breaking` (default), `any` (any change at all fails, including additions), or `none` (report only). `--report` selects the output: `text` (default), `markdown` (ready to post as a pull-request comment) or `json` (for tooling). +## 🔁 The daily workflow -## 🧼 How changes are classified +### No change -| Change | Impact | -| --- | --- | -| Error code removed | đŸ’„ Breaking | -| Context key removed | đŸ’„ Breaking | -| Context key value type changed | đŸ’„ Breaking | -| Error code added | ✅ Compatible | -| Context key added | ✅ Compatible | -| Title or source changed | â„č Informational | +The command exits with `0` and reports that the catalog has not changed. -A **rename** is a removal plus an addition — and stays breaking, because consumers know the old code. When exactly one added error shares the removed error's title, the report adds a hint: *"possibly renamed to 'NEW_CODE', which has the same title"*. +### Compatible change -## ✍ Accepting a change deliberately +Adding an error code or context key is reported, but does not fail with the default policy. -When a contract change is intentional, refresh the baseline and commit it: +The developer can then update the baseline so the new contract is committed: ```bash fce catalog update --solution MyApp.sln +git add errors-baseline.json +git commit -m "chore: update error catalog baseline" ``` -The command summarizes what it absorbs (`1 breaking, 2 compatible and 0 documentation change(s) accepted`), and the pull request then shows the baseline diff — a removed code appears as a removed line. The accident becomes impossible; the deliberate change becomes visible and reviewable. This is the same discipline as a public-API baseline file, applied to the error catalog. - -**In CI/CD**, make accepting a change one action instead of a manual local step: on a pull request labelled `accept-contract-change`, regenerate the baseline and commit it back onto the PR branch, so the change lands as an explicit, reviewable diff (works for same-repository branches; from a fork, run `fce catalog update` locally and push): - -```yaml -# .github/workflows/error-catalog-accept.yml -on: - pull_request: - types: [labeled] - -jobs: - accept: - if: github.event.label.name == 'accept-contract-change' - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.ref }} - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '10.0.x' - # Make fce available on the runner (see the full example below). - - name: Regenerate and commit the baseline - run: | - fce catalog update --solution MyApp.sln - git add errors-baseline.json - if git diff --cached --quiet; then - echo 'Baseline already up to date — nothing to accept.' - else - git -c user.name='github-actions[bot]' \ - -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ - commit -m 'chore: accept error-catalog contract change' - git push - fi -``` - -For a purely local flow, the same two lines behind a `make accept-errors` target work just as well. - -## đŸ›Ąïž Baseline resilience & schema versioning +### Breaking change -The baseline is a checked-in file, so over a project's life it can be corrupted by a bad merge or produced by a different version of the tool. `fce catalog update` handles each case deliberately rather than silently: +Removing a code, removing a context key, or changing its type makes the command exit with `2`. CI can use that code to block the pull request. -* **A corrupt or unreadable baseline is regenerated, never fatal.** Updating is exactly how a baseline is (re)built, so an existing file that cannot be parsed is rewritten from the current catalog with a warning — a broken baseline never blocks you. -* **A baseline written by a _newer_ schema is refused, never downgraded.** Every snapshot carries a `schema` version. If a teammate committed a baseline with a newer tool, an older tool will not overwrite it with an older schema — that would silently drop information — so it stops with an error telling you to upgrade. `fce catalog diff` refuses it the same way. Upgrading the tool, or aligning versions across the team, resolves it. +The developer must then choose explicitly between two actions: -So `fce catalog update` exits `0` when the baseline is created, already up to date, or refreshed (including a self-healed one); `1` on an execution error or a newer-schema baseline; and `130` if cancelled. +1. **The change is accidental:** fix the code and restore the contract. +2. **The change is intentional:** run `fce catalog update`, inspect the `errors-baseline.json` diff, then commit it. -## ⚙ Snapshots without a baseline +A breaking change is therefore not forbidden; it simply cannot be introduced silently. -Two more ways to produce and compare snapshots: +## đŸ§Ș Example: renaming a code -* `fce generate --snapshot ` also writes the canonical snapshot next to whatever format you render — one generation, both the human catalog and the contract file. It reflects the render `--language`; when that is not English the command warns, because a committed baseline should stay culture-independent — use `fce catalog update` (or `--language en`) for that. -* `fce catalog diff --against ` compares the baseline against a snapshot **file** instead of extracting from the source — useful for comparing two release artifacts. +A developer renames `PAYMENT.DECLINED` to `PAYMENT.REFUSED` during a refactoring. -Both `baseline` and `snapshot` can be set in `fce.json` so the paths need not be repeated on every run. +For a consumer, this is not a harmless rename: the old code disappears and a new one appears. The report therefore looks like this: -## 🚩 Wiring it into CI/CD: a complete example - -The goal of the CI integration is simple: **contract drift must be visible where the change is reviewed** — in the pull request itself, not in a log nobody reads. The loop looks like this: - -1. Every pull request runs `fce catalog diff` against the committed baseline. -2. **No change** → the job passes silently. -3. **Compatible or documentation changes** → the job still passes (with the default `--fail-on breaking`); the report can be posted for awareness. -4. **Breaking change** → exit code `2` fails the job, and the Markdown report lands as a pull-request comment. The author then has exactly two honest ways out: fix the accidental removal, or accept it deliberately with `fce catalog update` — in which case the reviewer sees the baseline diff (the removed code appears as a removed line) and approves a breaking change *knowingly*. - -Walked through on a concrete scenario: a developer renames `PAYMENT.DECLINED` to `PAYMENT.REFUSED` while refactoring. Without the guardrail, the rename ships silently and every dashboard and client branching on the old code breaks in production. With it, the pull request fails with: - -``` +```text Breaking changes (1): - [removed] PAYMENT.DECLINED — error removed (possibly renamed to 'PAYMENT.REFUSED', which has the same title) Compatible changes (1): - [added] PAYMENT.REFUSED — new error 'Payment declined' (source: Payment) ``` -If the rename was accidental, the developer reverts it. If it was deliberate, they run `fce catalog update`, commit `errors-baseline.json`, and the contract change becomes an explicit, reviewable part of the pull request. - -### GitHub Actions - -```yaml -name: error-catalog - -on: - pull_request: - branches: [main] - -jobs: - catalog-diff: - runs-on: ubuntu-latest - permissions: - pull-requests: write # needed to post the report as a comment - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '10.0.x' - - # Make fce available on the runner (dotnet tool install, a cached - # build from source, or your internal distribution). +If the rename was accidental, the developer fixes it. If it was intentional, updating the baseline makes the removal visible in the pull request so reviewers can approve it knowingly. - - name: Compare the catalog against the baseline - run: fce catalog diff --solution MyApp.sln --report markdown > catalog-diff.md - # Exit code 2 (breaking change) fails this step, and therefore the job. +## 🧼 Change classification - - name: Post the report on the pull request - if: failure() # comment only when the contract drifted - run: gh pr comment ${{ github.event.pull_request.number }} --body-file catalog-diff.md - env: - GH_TOKEN: ${{ github.token }} -``` - -Two behaviors worth noting: the report is generated *before* the step fails (the redirection captures standard output, the exit code fails the step afterwards), and the comment step runs only `if: failure()` — a quiet pipeline stays quiet. - -### GitLab CI - -```yaml -error-catalog: - stage: test - image: mcr.microsoft.com/dotnet/sdk:10.0 - script: - # Make fce available on the runner (dotnet tool install, a cached - # build from source, or your internal distribution). - - fce catalog diff --solution MyApp.sln --report markdown > catalog-diff.md - artifacts: - when: always # keep the report even when the job fails on a breaking change - paths: - - catalog-diff.md -``` +| Change | Default impact | +| --- | --- | +| Error code removed | đŸ’„ Breaking | +| Context key removed | đŸ’„ Breaking | +| Context key type changed | đŸ’„ Breaking | +| Error code added | ✅ Compatible | +| Context key added | ✅ Compatible | +| Title or source changed | â„č Informational | -The exit code drives the job result exactly as on GitHub; `artifacts: when: always` keeps the report downloadable from the failed pipeline, and it can be posted on the merge request with a call to the [notes API](https://docs.gitlab.com/ee/api/notes.html) if you want the comment automation too. +A rename remains breaking because consumers know the old code. When the title suggests a probable rename, the report adds a hint for the developer; it does not make the operation compatible. -### Beyond pull requests +## 📚 Further reading -Running the same `fce catalog diff` on the main branch (on push or on a schedule) catches drift that bypassed the pull-request flow, and `fce catalog diff --against` lets a release pipeline compare two published snapshots — for example, the snapshot shipped with the previous release against the candidate one — to generate release notes for the error contract. +- [Command, baseline format, and exit-code reference](CatalogVersioningReference.en.md) +- [CI/CD integration: GitHub Actions, GitLab CI, and advanced workflows](CatalogVersioningCI.en.md) --- @@ -228,4 +166,4 @@ Running the same `fce catalog diff` on the main branch (on push or on a schedule ← CI/CD and Operational Integration · ↑ Table of contents · Architecture of the Documentation Pipeline → ---- +--- \ No newline at end of file From 92a6228b5f9efc3bac5064dfe6c0f9a2705e6fe9 Mon Sep 17 00:00:00 2001 From: Sylvain Aurat Date: Tue, 14 Jul 2026 09:42:32 +0200 Subject: [PATCH 3/8] docs: add catalog versioning reference --- doc/CatalogVersioningReference.fr.md | 153 +++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 doc/CatalogVersioningReference.fr.md diff --git a/doc/CatalogVersioningReference.fr.md b/doc/CatalogVersioningReference.fr.md new file mode 100644 index 0000000..671de46 --- /dev/null +++ b/doc/CatalogVersioningReference.fr.md @@ -0,0 +1,153 @@ +# RĂ©fĂ©rence du versionnage du catalogue + +🌍 **Langues :** +🇬🇧 [English](./CatalogVersioningReference.en.md) | đŸ‡«đŸ‡· Français (ce fichier) + +Cette page constitue la rĂ©fĂ©rence technique de `fce catalog update`, `fce catalog diff` et du fichier de baseline. Pour dĂ©couvrir le mĂ©canisme, commencez par [Versionnage du catalogue](CatalogVersioning.fr.md). + +## đŸ§Ÿ Snapshot et baseline + +Le **snapshot canonique** est une projection JSON du catalogue contenant uniquement les donnĂ©es suivies par le versionnage : + +- le code de chaque erreur ; +- son titre et sa source ; +- le nom et le type de ses clĂ©s de contexte. + +La **baseline** est un snapshot choisi comme rĂ©fĂ©rence et commitĂ© dans le dĂ©pĂŽt. Par dĂ©faut, son chemin est `errors-baseline.json`. + +Le snapshot est indĂ©pendant du renderer utilisĂ© pour publier le catalogue humain. Il est dĂ©terministe : les erreurs sont triĂ©es par code, les clĂ©s de contexte par nom et les fins de ligne sont normalisĂ©es. Les commandes `fce catalog` extraient toujours le snapshot sous la culture `en`, afin que la baseline ne dĂ©pende pas de la langue du catalogue. + +## `fce catalog update` + +```bash +fce catalog update --solution MyApp.sln +``` + +La commande extrait le catalogue courant puis crĂ©e ou remplace la baseline. + +> ExĂ©cuter `catalog update` revient Ă  **accepter explicitement le contrat courant**, y compris ses Ă©ventuels changements cassants. + +Comportements : + +| Situation | Comportement | +| --- | --- | +| Baseline absente | Le fichier est créé. | +| Baseline dĂ©jĂ  identique | Aucun changement n'est Ă©crit. | +| Catalogue diffĂ©rent | La baseline est remplacĂ©e et les changements acceptĂ©s sont rĂ©sumĂ©s. | +| Baseline illisible ou corrompue | Elle est rĂ©gĂ©nĂ©rĂ©e avec un avertissement. | +| Baseline produite par un schĂ©ma plus rĂ©cent | La commande refuse de la rĂ©trograder et Ă©choue. | + +Codes de sortie : + +| Code | Signification | +| --- | --- | +| `0` | Baseline créée, dĂ©jĂ  Ă  jour ou remplacĂ©e avec succĂšs. | +| `1` | Erreur d'exĂ©cution ou schĂ©ma de baseline plus rĂ©cent que l'outil. | +| `130` | ExĂ©cution interrompue. | + +## `fce catalog diff` + +```bash +fce catalog diff --solution MyApp.sln +``` + +La commande compare la baseline au snapshot courant et Ă©crit le rapport sur la sortie standard. + +Codes de sortie : + +| Code | Signification | +| --- | --- | +| `0` | Aucun changement n'atteint le seuil dĂ©fini par `--fail-on`. | +| `2` | Au moins un changement atteint ce seuil. | +| `1` | Erreur d'exĂ©cution : baseline manquante, extraction impossible, fichier invalide, etc. | +| `130` | ExĂ©cution interrompue. | + +### Politique d'Ă©chec : `--fail-on` + +```bash +fce catalog diff --solution MyApp.sln --fail-on breaking +``` + +| Valeur | Effet | +| --- | --- | +| `breaking` | Valeur par dĂ©faut. Échoue uniquement sur les changements cassants. | +| `any` | Échoue dĂšs qu'un changement est dĂ©tectĂ©, y compris un ajout compatible ou une modification informative. | +| `none` | Produit le rapport sans jamais Ă©chouer Ă  cause d'une dĂ©rive. | + +### Format du rapport : `--report` + +```bash +fce catalog diff --solution MyApp.sln --report markdown +``` + +| Valeur | Usage | +| --- | --- | +| `text` | Valeur par dĂ©faut, destinĂ©e Ă  la lecture dans un terminal. | +| `markdown` ou `md` | Rapport prĂȘt Ă  publier dans une pull request. | +| `json` | Rapport exploitable par un outil. | + +### Comparer un snapshot existant : `--against` + +```bash +fce catalog diff --against candidate-snapshot.json +``` + +Cette variante compare la baseline Ă  un fichier de snapshot existant au lieu d'extraire le catalogue depuis le code. Elle est utile pour comparer deux artefacts de release. + +## Classification des changements + +| Changement | Impact | +| --- | --- | +| Code d'erreur supprimĂ© | Cassant | +| ClĂ© de contexte supprimĂ©e | Cassant | +| Type d'une clĂ© de contexte modifiĂ© | Cassant | +| Code d'erreur ajoutĂ© | Compatible | +| ClĂ© de contexte ajoutĂ©e | Compatible | +| Titre ou source modifiĂ© | Informatif | + +Un renommage est reprĂ©sentĂ© comme une suppression suivie d'un ajout et reste donc cassant. Lorsque exactement une nouvelle erreur possĂšde le mĂȘme titre que l'erreur supprimĂ©e, le rapport signale un renommage probable. + +## Produire un snapshot sans modifier la baseline + +```bash +fce generate --snapshot artifacts/error-catalog.snapshot.json +``` + +`fce generate --snapshot` Ă©crit le snapshot canonique en plus du catalogue rendu. Contrairement aux commandes `fce catalog`, ce snapshot reflĂšte la langue sĂ©lectionnĂ©e pour le rendu. Une baseline commitĂ©e doit rester indĂ©pendante de la langue : utilisez de prĂ©fĂ©rence `fce catalog update`, ou imposez `--language en`. + +## Configuration dans `fce.json` + +Les chemins peuvent ĂȘtre centralisĂ©s : + +```json +{ + "solution": "MyApp.sln", + "baseline": "errors-baseline.json", + "snapshot": "artifacts/error-catalog.snapshot.json" +} +``` + +Les chemins relatifs sont rĂ©solus par rapport au fichier de configuration. + +## Options d'extraction communes + +Les commandes `catalog update` et `catalog diff` acceptent notamment : + +| Option | RĂŽle | +| --- | --- | +| `--solution ` | Extrait le catalogue depuis une solution. | +| `--assemblies ` | Extrait depuis une ou plusieurs assemblies dĂ©jĂ  construites. | +| `--baseline ` | Remplace le chemin de baseline configurĂ©. | +| `--configuration ` | Choisit la configuration de build. | +| `--framework ` | Restreint une solution multi-cible Ă  un framework. | +| `--no-build` | Utilise les binaires existants sans reconstruire. | +| `--strict` | ArrĂȘte l'extraction Ă  la premiĂšre erreur. | +| `--verbose` | Écrit les diagnostics dĂ©taillĂ©s sur la sortie d'erreur. | + +--- + + + +--- \ No newline at end of file From ca02a19e02fedbe1c6926f519d1f3de56effb742 Mon Sep 17 00:00:00 2001 From: Sylvain Aurat Date: Tue, 14 Jul 2026 09:42:54 +0200 Subject: [PATCH 4/8] docs: add catalog versioning reference --- doc/CatalogVersioningReference.en.md | 153 +++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 doc/CatalogVersioningReference.en.md diff --git a/doc/CatalogVersioningReference.en.md b/doc/CatalogVersioningReference.en.md new file mode 100644 index 0000000..da31cf9 --- /dev/null +++ b/doc/CatalogVersioningReference.en.md @@ -0,0 +1,153 @@ +# Catalog Versioning Reference + +🌍 **Languages:** +🇬🇧 English (this file) | đŸ‡«đŸ‡· [Français](./CatalogVersioningReference.fr.md) + +This page is the technical reference for `fce catalog update`, `fce catalog diff`, and the baseline file. For an introduction, start with [Catalog Versioning](CatalogVersioning.en.md). + +## đŸ§Ÿ Snapshot and baseline + +The **canonical snapshot** is a JSON projection of the catalog containing only the data tracked by versioning: + +- each error code; +- its title and source; +- the name and type of its context keys. + +The **baseline** is a snapshot selected as the reference and committed to the repository. Its default path is `errors-baseline.json`. + +The snapshot is independent of the renderer used to publish the human-facing catalog. It is deterministic: errors are ordered by code, context keys by name, and line endings are normalized. The `fce catalog` commands always extract under the `en` culture so the baseline does not depend on the catalog language. + +## `fce catalog update` + +```bash +fce catalog update --solution MyApp.sln +``` + +The command extracts the current catalog, then creates or replaces the baseline. + +> Running `catalog update` means **explicitly accepting the current contract**, including any breaking changes it contains. + +Behavior: + +| Situation | Behavior | +| --- | --- | +| Baseline is missing | The file is created. | +| Baseline is already identical | Nothing is written. | +| Catalog differs | The baseline is replaced and the accepted changes are summarized. | +| Baseline is unreadable or corrupt | It is regenerated with a warning. | +| Baseline was produced by a newer schema | The command refuses to downgrade it and fails. | + +Exit codes: + +| Code | Meaning | +| --- | --- | +| `0` | Baseline created, already current, or replaced successfully. | +| `1` | Execution error or baseline schema newer than the tool. | +| `130` | Execution interrupted. | + +## `fce catalog diff` + +```bash +fce catalog diff --solution MyApp.sln +``` + +The command compares the baseline with the current snapshot and writes the report to standard output. + +Exit codes: + +| Code | Meaning | +| --- | --- | +| `0` | No change reaches the threshold selected by `--fail-on`. | +| `2` | At least one change reaches that threshold. | +| `1` | Execution error: missing baseline, failed extraction, invalid file, and so on. | +| `130` | Execution interrupted. | + +### Failure policy: `--fail-on` + +```bash +fce catalog diff --solution MyApp.sln --fail-on breaking +``` + +| Value | Effect | +| --- | --- | +| `breaking` | Default. Fails only on breaking changes. | +| `any` | Fails on any detected change, including compatible additions and informational changes. | +| `none` | Produces the report without failing because of drift. | + +### Report format: `--report` + +```bash +fce catalog diff --solution MyApp.sln --report markdown +``` + +| Value | Usage | +| --- | --- | +| `text` | Default terminal-oriented output. | +| `markdown` or `md` | Report ready to publish in a pull request. | +| `json` | Machine-readable report. | + +### Compare an existing snapshot: `--against` + +```bash +fce catalog diff --against candidate-snapshot.json +``` + +This variant compares the baseline with an existing snapshot file instead of extracting the catalog from source. It is useful for comparing two release artifacts. + +## Change classification + +| Change | Impact | +| --- | --- | +| Error code removed | Breaking | +| Context key removed | Breaking | +| Context key type changed | Breaking | +| Error code added | Compatible | +| Context key added | Compatible | +| Title or source changed | Informational | + +A rename is represented as a removal followed by an addition and therefore remains breaking. When exactly one new error has the same title as the removed error, the report indicates a probable rename. + +## Produce a snapshot without modifying the baseline + +```bash +fce generate --snapshot artifacts/error-catalog.snapshot.json +``` + +`fce generate --snapshot` writes the canonical snapshot in addition to the rendered catalog. Unlike the `fce catalog` commands, this snapshot reflects the selected render language. A committed baseline should remain language-independent: prefer `fce catalog update`, or force `--language en`. + +## Configuration in `fce.json` + +Paths can be centralized: + +```json +{ + "solution": "MyApp.sln", + "baseline": "errors-baseline.json", + "snapshot": "artifacts/error-catalog.snapshot.json" +} +``` + +Relative paths are resolved from the configuration file. + +## Common extraction options + +The `catalog update` and `catalog diff` commands accept, among others: + +| Option | Purpose | +| --- | --- | +| `--solution ` | Extract from a solution. | +| `--assemblies ` | Extract from one or more already-built assemblies. | +| `--baseline ` | Override the configured baseline path. | +| `--configuration ` | Select the build configuration. | +| `--framework ` | Restrict a multi-target solution to one framework. | +| `--no-build` | Use existing binaries without rebuilding. | +| `--strict` | Stop extraction on the first failure. | +| `--verbose` | Write detailed diagnostics to standard error. | + +--- + + + +--- \ No newline at end of file From 8538840136072c7dd0132ec7e4723893f33c4ef4 Mon Sep 17 00:00:00 2001 From: Sylvain Aurat Date: Tue, 14 Jul 2026 09:48:39 +0200 Subject: [PATCH 5/8] docs: add catalog versioning CI guide --- doc/CatalogVersioningCI.fr.md | 220 ++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 doc/CatalogVersioningCI.fr.md diff --git a/doc/CatalogVersioningCI.fr.md b/doc/CatalogVersioningCI.fr.md new file mode 100644 index 0000000..d57b21b --- /dev/null +++ b/doc/CatalogVersioningCI.fr.md @@ -0,0 +1,220 @@ +# IntĂ©grer le versionnage du catalogue en CI/CD + +🌍 **Langues :** +🇬🇧 [English](./CatalogVersioningCI.en.md) | đŸ‡«đŸ‡· Français (ce fichier) + +Ce guide part du principe que la baseline a dĂ©jĂ  Ă©tĂ© créée et commitĂ©e : + +```bash +fce catalog update --solution MyApp.sln +git add errors-baseline.json +git commit -m "chore: add error catalog baseline" +``` + +La CI n'a alors besoin que d'une opĂ©ration en lecture : comparer le catalogue courant au contrat acceptĂ©. + +```bash +fce catalog diff --solution MyApp.sln +``` + +## 🚩 Comportement attendu dans une pull request + +Le workflow recommandĂ© est le suivant : + +1. la pull request exĂ©cute `fce catalog diff` contre `errors-baseline.json` ; +2. aucun changement ne fait Ă©chouer le job ; +3. les ajouts compatibles sont signalĂ©s sans bloquer le job avec la politique par dĂ©faut ; +4. un changement cassant retourne `2` et bloque la pull request ; +5. l'auteur corrige le changement accidentel ou met volontairement Ă  jour la baseline. + +La dĂ©rive doit ĂȘtre visible Ă  l'endroit oĂč le changement est relu : idĂ©alement dans la pull request elle-mĂȘme, pas uniquement dans un log de pipeline. + +## GitHub Actions + +L'exemple suivant conserve le rapport, le publie uniquement lorsqu'un changement atteint le seuil configurĂ©, puis restitue le vĂ©ritable code de sortie de `fce`. + +```yaml +name: error-catalog + +on: + pull_request: + branches: [main] + +jobs: + catalog-diff: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + # Rendez fce disponible sur le runner : dotnet tool, build mis en cache + # ou mĂ©canisme de distribution interne. + + - name: Compare the catalog with the baseline + id: catalog + shell: bash + run: | + set +e + fce catalog diff \ + --solution MyApp.sln \ + --report markdown > catalog-diff.md + exit_code=$? + echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT" + exit 0 + + - name: Post the breaking-change report + if: steps.catalog.outputs.exit_code == '2' + run: gh pr comment "${{ github.event.pull_request.number }}" --body-file catalog-diff.md + env: + GH_TOKEN: ${{ github.token }} + + - name: Propagate the catalog result + if: steps.catalog.outputs.exit_code != '0' + run: exit "${{ steps.catalog.outputs.exit_code }}" +``` + +Cette sĂ©paration Ă©vite de confondre deux situations : + +- `2` signifie que le contrat a changĂ© selon la politique choisie ; +- `1` signifie que la commande n'a pas pu s'exĂ©cuter correctement. + +Avec `--fail-on breaking`, seuls les changements cassants font Ă©chouer le job. Pour faire Ă©chouer la CI sur tout changement, utilisez `--fail-on any`. + +## GitLab CI + +```yaml +error-catalog: + stage: test + image: mcr.microsoft.com/dotnet/sdk:10.0 + script: + # Rendez fce disponible sur le runner avant cette commande. + - fce catalog diff --solution MyApp.sln --report markdown > catalog-diff.md + artifacts: + when: always + paths: + - catalog-diff.md +``` + +Le code de sortie de `fce` pilote directement le rĂ©sultat du job. `artifacts: when: always` conserve le rapport mĂȘme lorsque le job Ă©choue. + +Vous pouvez ensuite publier `catalog-diff.md` dans la merge request au moyen de l'[API Notes de GitLab](https://docs.gitlab.com/ee/api/notes.html). + +## ✍ Accepter un changement + +Le flux le plus simple et le plus explicite reste local : + +```bash +fce catalog update --solution MyApp.sln +git diff -- errors-baseline.json +git add errors-baseline.json +git commit -m "chore: update error catalog baseline" +``` + +Le relecteur voit alors le changement de contrat dans le diff Git de la pull request. + +> N'exĂ©cutez pas `catalog update` automatiquement aprĂšs l'Ă©chec du diff. Cela transformerait toute rupture accidentelle en contrat acceptĂ© sans dĂ©cision humaine. + +## ⚙ Initialiser automatiquement une baseline absente + +L'initialisation locale est recommandĂ©e, car elle permet de garder la CI en lecture seule. Une initialisation automatique peut nĂ©anmoins ĂȘtre utile lors du dĂ©ploiement progressif de l'outil sur de nombreux dĂ©pĂŽts. + +ExĂ©cutez cette opĂ©ration uniquement sur la branche par dĂ©faut, avec une permission d'Ă©criture explicite : + +```yaml +permissions: + contents: write + +steps: + - uses: actions/checkout@v4 + + - name: Seed the error-catalog baseline if missing + run: | + if [ ! -f errors-baseline.json ]; then + fce catalog update --solution MyApp.sln + git add errors-baseline.json + git -c user.name='github-actions[bot]' \ + -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ + commit -m 'chore: seed the error-catalog baseline' + git push + fi +``` + +Cette Ă©tape ne doit crĂ©er le fichier que s'il est absent. Elle ne doit pas rafraĂźchir silencieusement une baseline existante. + +## đŸ·ïž Accepter un changement avec un label GitHub + +Une Ă©quipe peut transformer l'acceptation en action explicite sur la pull request. Par exemple, l'ajout du label `accept-contract-change` peut rĂ©gĂ©nĂ©rer puis commiter la baseline sur la branche de la PR. + +```yaml +name: accept-error-catalog-change + +on: + pull_request: + types: [labeled] + +jobs: + accept: + if: github.event.label.name == 'accept-contract-change' + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + # Rendez fce disponible sur le runner avant cette Ă©tape. + + - name: Regenerate and commit the baseline + run: | + fce catalog update --solution MyApp.sln + git add errors-baseline.json + + if git diff --cached --quiet; then + echo 'Baseline already up to date — nothing to accept.' + else + git -c user.name='github-actions[bot]' \ + -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ + commit -m 'chore: accept error-catalog contract change' + git push + fi +``` + +Ce workflow fonctionne directement pour les branches du mĂȘme dĂ©pĂŽt. Pour une pull request provenant d'un fork, l'auteur doit gĂ©nĂ©ralement exĂ©cuter `fce catalog update` localement puis pousser le commit sur son fork. + +## 📩 VĂ©rifier la branche principale et les releases + +ExĂ©cuter Ă©galement `fce catalog diff` sur la branche principale permet de dĂ©tecter une modification qui aurait contournĂ© le flux normal de pull request. + +Pour comparer un artefact de release Ă  la baseline sans reconstruire la solution : + +```bash +fce catalog diff --against path/to/release-snapshot.json +``` + +Cette forme peut servir Ă  produire des notes de version du contrat d'erreurs ou Ă  comparer le snapshot de la release prĂ©cĂ©dente Ă  celui d'un candidat. + +## 📚 Documents associĂ©s + +- [Comprendre et utiliser le versionnage du catalogue](CatalogVersioning.fr.md) +- [RĂ©fĂ©rence des commandes, formats et codes de sortie](CatalogVersioningReference.fr.md) + +--- + + + +--- From 06de228c1d7a08a88d29b64f278c1bce849b7b59 Mon Sep 17 00:00:00 2001 From: Sylvain Aurat Date: Tue, 14 Jul 2026 09:49:08 +0200 Subject: [PATCH 6/8] docs: add English catalog versioning CI guide --- doc/CatalogVersioningCI.en.md | 220 ++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 doc/CatalogVersioningCI.en.md diff --git a/doc/CatalogVersioningCI.en.md b/doc/CatalogVersioningCI.en.md new file mode 100644 index 0000000..f8fd9bc --- /dev/null +++ b/doc/CatalogVersioningCI.en.md @@ -0,0 +1,220 @@ +# Integrating Catalog Versioning into CI/CD + +🌍 **Languages:** +🇬🇧 English (this file) | đŸ‡«đŸ‡· [Français](./CatalogVersioningCI.fr.md) + +This guide assumes that the baseline has already been created and committed: + +```bash +fce catalog update --solution MyApp.sln +git add errors-baseline.json +git commit -m "chore: add error catalog baseline" +``` + +CI then needs only one read-only operation: compare the current catalog with the accepted contract. + +```bash +fce catalog diff --solution MyApp.sln +``` + +## 🚩 Expected pull-request behavior + +The recommended workflow is: + +1. the pull request runs `fce catalog diff` against `errors-baseline.json`; +2. no change lets the job pass; +3. compatible additions are reported but do not fail the job with the default policy; +4. a breaking change returns `2` and blocks the pull request; +5. the author either fixes the accidental change or deliberately updates the baseline. + +Drift should be visible where the change is reviewed: ideally in the pull request itself, not only in a pipeline log. + +## GitHub Actions + +The following example preserves the report, publishes it only when a change reaches the configured threshold, and then propagates the real `fce` exit code. + +```yaml +name: error-catalog + +on: + pull_request: + branches: [main] + +jobs: + catalog-diff: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + # Make fce available on the runner: dotnet tool, cached source build, + # or your internal distribution mechanism. + + - name: Compare the catalog with the baseline + id: catalog + shell: bash + run: | + set +e + fce catalog diff \ + --solution MyApp.sln \ + --report markdown > catalog-diff.md + exit_code=$? + echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT" + exit 0 + + - name: Post the breaking-change report + if: steps.catalog.outputs.exit_code == '2' + run: gh pr comment "${{ github.event.pull_request.number }}" --body-file catalog-diff.md + env: + GH_TOKEN: ${{ github.token }} + + - name: Propagate the catalog result + if: steps.catalog.outputs.exit_code != '0' + run: exit "${{ steps.catalog.outputs.exit_code }}" +``` + +This separation avoids confusing two situations: + +- `2` means the contract changed according to the selected policy; +- `1` means the command could not execute correctly. + +With `--fail-on breaking`, only breaking changes fail the job. To fail CI on every change, use `--fail-on any`. + +## GitLab CI + +```yaml +error-catalog: + stage: test + image: mcr.microsoft.com/dotnet/sdk:10.0 + script: + # Make fce available on the runner before this command. + - fce catalog diff --solution MyApp.sln --report markdown > catalog-diff.md + artifacts: + when: always + paths: + - catalog-diff.md +``` + +The `fce` exit code directly controls the job result. `artifacts: when: always` preserves the report even when the job fails. + +You can then publish `catalog-diff.md` on the merge request through the [GitLab Notes API](https://docs.gitlab.com/ee/api/notes.html). + +## ✍ Accepting a change + +The simplest and most explicit flow remains local: + +```bash +fce catalog update --solution MyApp.sln +git diff -- errors-baseline.json +git add errors-baseline.json +git commit -m "chore: update error catalog baseline" +``` + +The reviewer can then see the contract change in the pull request's Git diff. + +> Do not run `catalog update` automatically after a failed diff. That would turn every accidental break into an accepted contract without a human decision. + +## ⚙ Automatically seeding a missing baseline + +Local initialization is recommended because it keeps CI read-only. Automatic seeding can still be useful when rolling the tool out progressively across many repositories. + +Run this operation only on the default branch, with explicit write permission: + +```yaml +permissions: + contents: write + +steps: + - uses: actions/checkout@v4 + + - name: Seed the error-catalog baseline if missing + run: | + if [ ! -f errors-baseline.json ]; then + fce catalog update --solution MyApp.sln + git add errors-baseline.json + git -c user.name='github-actions[bot]' \ + -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ + commit -m 'chore: seed the error-catalog baseline' + git push + fi +``` + +This step must create the file only when it is absent. It must not silently refresh an existing baseline. + +## đŸ·ïž Accepting a change with a GitHub label + +A team can turn acceptance into an explicit pull-request action. For example, adding an `accept-contract-change` label can regenerate and commit the baseline on the PR branch. + +```yaml +name: accept-error-catalog-change + +on: + pull_request: + types: [labeled] + +jobs: + accept: + if: github.event.label.name == 'accept-contract-change' + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + # Make fce available on the runner before this step. + + - name: Regenerate and commit the baseline + run: | + fce catalog update --solution MyApp.sln + git add errors-baseline.json + + if git diff --cached --quiet; then + echo 'Baseline already up to date — nothing to accept.' + else + git -c user.name='github-actions[bot]' \ + -c user.email='41898282+github-actions[bot]@users.noreply.github.com' \ + commit -m 'chore: accept error-catalog contract change' + git push + fi +``` + +This workflow works directly for branches in the same repository. For a pull request from a fork, the author generally needs to run `fce catalog update` locally and push the commit to their fork. + +## 📩 Checking the default branch and releases + +Also running `fce catalog diff` on the default branch detects a change that bypassed the normal pull-request flow. + +To compare a release artifact with the baseline without rebuilding the solution: + +```bash +fce catalog diff --against path/to/release-snapshot.json +``` + +This form can produce release notes for the error contract or compare the previous release snapshot with a candidate snapshot. + +## 📚 Related documents + +- [Understanding and using catalog versioning](CatalogVersioning.en.md) +- [Command, format, and exit-code reference](CatalogVersioningReference.en.md) + +--- + + + +--- From a2e46c2076cf0e5677ba522758f8d80807875aa8 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 08:05:49 +0000 Subject: [PATCH 7/8] docs: use UPPER_SNAKE_CASE in the rename example The rename example used dotted error codes (PAYMENT.DECLINED) while the baseline JSON example in the same guide, and the FCE004 UPPER_SNAKE_CASE convention the library enforces, use underscores. Align the example on that convention in both the English and French guides. --- doc/CatalogVersioning.en.md | 6 +++--- doc/CatalogVersioning.fr.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/CatalogVersioning.en.md b/doc/CatalogVersioning.en.md index 3907e6e..6969346 100644 --- a/doc/CatalogVersioning.en.md +++ b/doc/CatalogVersioning.en.md @@ -129,15 +129,15 @@ A breaking change is therefore not forbidden; it simply cannot be introduced sil ## đŸ§Ș Example: renaming a code -A developer renames `PAYMENT.DECLINED` to `PAYMENT.REFUSED` during a refactoring. +A developer renames `PAYMENT_DECLINED` to `PAYMENT_REFUSED` during a refactoring. For a consumer, this is not a harmless rename: the old code disappears and a new one appears. The report therefore looks like this: ```text Breaking changes (1): - - [removed] PAYMENT.DECLINED — error removed (possibly renamed to 'PAYMENT.REFUSED', which has the same title) + - [removed] PAYMENT_DECLINED — error removed (possibly renamed to 'PAYMENT_REFUSED', which has the same title) Compatible changes (1): - - [added] PAYMENT.REFUSED — new error 'Payment declined' (source: Payment) + - [added] PAYMENT_REFUSED — new error 'Payment declined' (source: Payment) ``` If the rename was accidental, the developer fixes it. If it was intentional, updating the baseline makes the removal visible in the pull request so reviewers can approve it knowingly. diff --git a/doc/CatalogVersioning.fr.md b/doc/CatalogVersioning.fr.md index 04027f7..35ab612 100644 --- a/doc/CatalogVersioning.fr.md +++ b/doc/CatalogVersioning.fr.md @@ -129,15 +129,15 @@ Ainsi, un changement cassant n'est pas interdit ; il ne peut simplement plus ĂȘt ## đŸ§Ș Exemple : renommage d'un code -Un dĂ©veloppeur renomme `PAYMENT.DECLINED` en `PAYMENT.REFUSED` pendant un refactoring. +Un dĂ©veloppeur renomme `PAYMENT_DECLINED` en `PAYMENT_REFUSED` pendant un refactoring. Pour un consommateur, ce n'est pas un simple renommage : l'ancien code disparaĂźt et un nouveau code apparaĂźt. Le rapport ressemble donc Ă  ceci : ```text Breaking changes (1): - - [removed] PAYMENT.DECLINED — error removed (possibly renamed to 'PAYMENT.REFUSED', which has the same title) + - [removed] PAYMENT_DECLINED — error removed (possibly renamed to 'PAYMENT_REFUSED', which has the same title) Compatible changes (1): - - [added] PAYMENT.REFUSED — new error 'Payment declined' (source: Payment) + - [added] PAYMENT_REFUSED — new error 'Payment declined' (source: Payment) ``` Si le renommage Ă©tait accidentel, le dĂ©veloppeur le corrige. S'il Ă©tait volontaire, la mise Ă  jour de la baseline rend la suppression visible dans la pull request et permet au relecteur de l'approuver en connaissance de cause. From 5c35fb1248539562a6d32e9db3936f187d01c000 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 08:32:45 +0000 Subject: [PATCH 8/8] docs: connect the catalog versioning pages in nav and TOC Make the three catalog versioning pages navigable as one unit. The footer links now form a single linear path (operational integration -> guide -> reference -> CI/CD -> architecture) instead of the guide skipping its own sub-pages and the reference and CI/CD footers pointing at each other; every page also gains the "up to the table of contents" link. The README table of contents (English and French) groups the guide, reference, and CI/CD pages under a "Catalog versioning" sub-section, so the three are discoverable and the "table of contents" links land where the pages are actually listed. --- README.md | 5 ++++- doc/CatalogVersioning.en.md | 2 +- doc/CatalogVersioning.fr.md | 2 +- doc/CatalogVersioningCI.en.md | 2 +- doc/CatalogVersioningCI.fr.md | 2 +- doc/CatalogVersioningReference.en.md | 2 +- doc/CatalogVersioningReference.fr.md | 2 +- doc/README.fr.md | 5 ++++- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 264a7eb..9eeb9f1 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,10 @@ See the full documentation: - [Best Practices](doc/BestPractices.en.md) - [Testing Guide](doc/Testing.en.md) - [CI/CD and Operational Integration](doc/OperationalIntegration.en.md) -- [Catalog Versioning](doc/CatalogVersioning.en.md) +- Catalog versioning + - [Overview & workflow](doc/CatalogVersioning.en.md) + - [Command reference](doc/CatalogVersioningReference.en.md) + - [CI/CD integration](doc/CatalogVersioningCI.en.md) - [Architecture of the Documentation Pipeline](doc/ArchitectureOfTheDocumentationPipeline.en.md) - [Writing a custom renderer](doc/WritingACustomRenderer.en.md) - [Internationalization](doc/Internationalization.en.md) diff --git a/doc/CatalogVersioning.en.md b/doc/CatalogVersioning.en.md index 6969346..26e1ffe 100644 --- a/doc/CatalogVersioning.en.md +++ b/doc/CatalogVersioning.en.md @@ -163,7 +163,7 @@ A rename remains breaking because consumers know the old code. When the title su --- --- \ No newline at end of file diff --git a/doc/CatalogVersioning.fr.md b/doc/CatalogVersioning.fr.md index 35ab612..1442673 100644 --- a/doc/CatalogVersioning.fr.md +++ b/doc/CatalogVersioning.fr.md @@ -163,7 +163,7 @@ Un renommage reste cassant, car les consommateurs connaissent l'ancien code. Lor --- --- diff --git a/doc/CatalogVersioningCI.en.md b/doc/CatalogVersioningCI.en.md index f8fd9bc..0440dde 100644 --- a/doc/CatalogVersioningCI.en.md +++ b/doc/CatalogVersioningCI.en.md @@ -214,7 +214,7 @@ This form can produce release notes for the error contract or compare the previo --- --- diff --git a/doc/CatalogVersioningCI.fr.md b/doc/CatalogVersioningCI.fr.md index d57b21b..d8d4c1a 100644 --- a/doc/CatalogVersioningCI.fr.md +++ b/doc/CatalogVersioningCI.fr.md @@ -214,7 +214,7 @@ Cette forme peut servir Ă  produire des notes de version du contrat d'erreurs ou --- --- diff --git a/doc/CatalogVersioningReference.en.md b/doc/CatalogVersioningReference.en.md index da31cf9..13fe18c 100644 --- a/doc/CatalogVersioningReference.en.md +++ b/doc/CatalogVersioningReference.en.md @@ -147,7 +147,7 @@ The `catalog update` and `catalog diff` commands accept, among others: --- --- \ No newline at end of file diff --git a/doc/CatalogVersioningReference.fr.md b/doc/CatalogVersioningReference.fr.md index 671de46..2d97948 100644 --- a/doc/CatalogVersioningReference.fr.md +++ b/doc/CatalogVersioningReference.fr.md @@ -147,7 +147,7 @@ Les commandes `catalog update` et `catalog diff` acceptent notamment : --- --- \ No newline at end of file diff --git a/doc/README.fr.md b/doc/README.fr.md index c360509..759e5e8 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -249,7 +249,10 @@ Consultez la documentation complĂšte : - [Bonnes pratiques](BestPractices.fr.md) - [Guide des tests](Testing.fr.md) - [IntĂ©gration CI/CD et exploitation](OperationalIntegration.fr.md) -- [Versionnage du catalogue](CatalogVersioning.fr.md) +- Versionnage du catalogue + - [Vue d'ensemble & workflow](CatalogVersioning.fr.md) + - [RĂ©fĂ©rence des commandes](CatalogVersioningReference.fr.md) + - [IntĂ©gration CI/CD](CatalogVersioningCI.fr.md) - [Architecture du pipeline de documentation](ArchitectureOfTheDocumentationPipeline.fr.md) - [Écrire son propre renderer](WritingACustomRenderer.fr.md) - [Internationalisation](Internationalisation.fr.md)