Cas avances¶
Sites de documentation, versioning multi-branches, internationalisation et métriques — la documentation comme produit a part entière.
Sites de documentation : comparatif¶
Quand un README et quelques fichiers Markdown ne suffisent plus, il faut un site de documentation dédié.
| Outil | Écosystème | Format source | Points forts | Limites |
|---|---|---|---|---|
| MkDocs Material | Python | Markdown | Rapide, beau, plugins riches | Moins de themes tiers |
| Sphinx | Python | reStructuredText / MD | Puissant, API docs natives | Configuration verbeuse |
| Docusaurus | JavaScript | Markdown / MDX | React, versioning intégré | Plus lourd a configurer |
| VitePress | JavaScript | Markdown / Vue | Ultra rapide, léger | Moins de plugins |
| Starlight | JavaScript | Markdown / MDX | Astro, performant, i18n natif | Jeune écosystème |
MkDocs Material — configuration type¶
# mkdocs.yml
site_name: "Documentation Projet"
site_url: "https://docs.example.com"
repo_url: "https://github.com/example/projet"
repo_name: "example/projet"
theme:
name: material
language: fr
palette:
- scheme: default
toggle:
icon: material/brightness-7
name: Mode sombre
- scheme: slate
toggle:
icon: material/brightness-4
name: Mode clair
features:
- navigation.tabs
- navigation.sections
- navigation.top
- search.suggest
- content.code.copy
plugins:
- search:
lang: fr
- mkdocstrings:
handlers:
python:
options:
docstring_style: google
- mike:
version_selector: true
markdown_extensions:
- admonition
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true
- pymdownx.snippets
- tables
- toc:
permalink: true
Docusaurus — configuration type¶
// docusaurus.config.js
export default {
title: "Documentation Projet",
tagline: "Reference technique complète",
url: "https://docs.example.com",
baseUrl: "/",
i18n: {
defaultLocale: "fr",
locales: ["fr", "en"],
},
themeConfig: {
navbar: {
title: "Mon Projet",
items: [
{ type: "docSidebar", sidebarId: "tutorialSidebar", label: "Docs" },
{ type: "docsVersionDropdown" },
{ type: "localeDropdown" },
],
},
},
presets: [
[
"classic",
{
docs: {
sidebarPath: "./sidebars.js",
editUrl: "https://github.com/example/projet/edit/main/",
versions: {
current: { label: "Next (canary)" },
},
},
},
],
],
};
Versioning multi-branches avec mike¶
mike est le plugin standard pour versionner la documentation MkDocs. Il publie chaque version dans une branche gh-pages séparée.
graph LR
main["main\n(v3.0 — latest)"] --> ghpages["gh-pages"]
v2["release/v2.x\n(v2.5 — stable)"] --> ghpages
v1["release/v1.x\n(v1.9 — legacy)"] --> ghpages
ghpages --> site["docs.example.com"] Workflow de publication¶
# Depuis la branche main
mike deploy --push --update-aliases 3.0 latest
# Depuis release/v2.x
git checkout release/v2.x
mike deploy --push --update-aliases 2.5 stable
# Marquer la version par defaut (redirige / vers latest)
mike set-default --push latest
# Lister toutes les versions deployees
mike list
# v3.0 [latest]
# v2.5 [stable]
# v1.9 [legacy]
# Supprimer une ancienne version
mike delete --push 1.8
CI/CD pour la documentation¶
# .github/workflows/docs.yml
name: Documentation
on:
push:
branches: [main, "release/*"]
pull_request:
branches: [main]
jobs:
deploy:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Necessaire pour mike
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install mkdocs-material mkdocstrings[python] mike
- name: Configure git
run: |
git config user.name "docs-bot"
git config user.email "docs@example.com"
- name: Deploy docs
run: |
VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
mike deploy --push --update-aliases "$VERSION" latest
Internationalisation (i18n)¶
Documentation multilingue
La traduction de documentation est coûteuse. Ne la faites que si votre audience le nécessité vraiment. Pour la plupart des projets open-source, l'anglais suffit comme langue commune.
Docusaurus i18n¶
# Generer les fichiers de traduction
npm run docusaurus write-translations -- --locale en
# Structure generee
i18n/
en/
docusaurus-plugin-content-docs/
current/
intro.md # traduction de docs/intro.md
docusaurus-theme-classic/
footer.json # traductions des elements UI
MkDocs avec contenu multilingue¶
# mkdocs.yml — approche par dossier de langue
plugins:
- i18n:
default_language: fr
languages:
fr:
name: Francais
default: true
en:
name: English
build: true
nav_translations:
Accueil: Home
Guide: Guide
Documentation d'onboarding¶
Le premier jour d'un nouveau membre de l'équipe est le meilleur test de votre documentation. Structurez l'onboarding en étapes chronologiques.
# Onboarding developpeur — Jour 1 a Jour 5
## Jour 1 : Environnement
- [ ] Cloner le depot principal
- [ ] Lancer `make setup` (installe les dependances et les hooks pre-commit)
- [ ] Verifier que `make test` passe
- [ ] Lire [Architecture overview](../architecture/overview.md)
## Jour 2 : Comprendre le produit
- [ ] Lire les 5 derniers ADR
- [ ] Faire un shadowing avec un dev senior sur un ticket en cours
- [ ] Lire [Modele de donnees](../architecture/data-model.md)
## Jour 3-5 : Premier ticket
- [ ] Choisir un ticket labele `good-first-issue`
- [ ] Ouvrir une PR avec les tests et la doc mise a jour
- [ ] Presenter le resultat en weekly technique
Métriques de documentation¶
Métriques de fraicheur¶
#!/usr/bin/env python3
"""Rapport de sante de la documentation."""
import subprocess
from pathlib import Path
from datetime import datetime, timedelta
def doc_freshness_report(docs_dir: str = "docs", threshold_days: int = 90):
docs = list(Path(docs_dir).rglob("*.md"))
stale = []
threshold = datetime.now() - timedelta(days=threshold_days)
for doc in docs:
result = subprocess.run(
["git", "log", "-1", "--format=%ai", str(doc)],
capture_output=True, text=True
)
date_str = result.stdout.strip()
if not date_str:
continue
last_modified = datetime.fromisoformat(date_str[:19])
if last_modified < threshold:
age = (datetime.now() - last_modified).days
stale.append((doc, age))
stale.sort(key=lambda x: -x[1])
print(f"Documentation analysee : {len(docs)} fichiers")
print(f"Fichiers non modifies depuis +{threshold_days}j : {len(stale)}")
for doc, age in stale[:10]:
print(f" {age}j — {doc}")
doc_freshness_report()
Métriques de couverture¶
| Métrique | Comment la mesurer |
|---|---|
| Couverture docstrings | interrogate (Python) — % de fonctions documentees |
| Liens morts | mkdocs-linkcheck ou lychee en CI |
| Fraicheur | Script Git — fichiers non touches depuis N jours |
| Temps de lecture moyen | Analytics (Plausible, Fathom) sur le site de doc |
| Recherches sans résultat | Logs du moteur de recherche |
# Verifier la couverture des docstrings Python
pip install interrogate
interrogate src/ --verbose --fail-under 80
# Verifier les liens
pip install mkdocs-linkcheck
mkdocs build --strict
Documentation comme produit¶
La documentation est un produit
Traitez votre documentation comme vous traitez votre logiciel :
- Backlog : les lacunes documentaires sont des tickets
- Feedbacks : un bouton "Cette page est-elle utile ?" avec collecte
- Iterez : analysez les recherches populaires et les pages visitees
- OKR : mesurez la satisfaction des nouveaux arrivants a J+30
graph TD
A[Feedback utilisateur] --> B[Backlog doc]
B --> C[Priorisation]
C --> D[Redaction / mise a jour]
D --> E[Review]
E --> F[Publication]
F --> G[Mesure d'impact]
G --> A Recapitulatif du tutoriel¶
Vous avez parcouru l'ensemble du cycle de documentation :
| Chapitre | Ce que vous pouvez faire maintenant |
|---|---|
| Fondamentaux | Choisir le bon niveau de doc pour chaque situation |
| Docstrings | Documenter le code dans Python, TS, Java, Go, Rust |
| ADR | Capturer les décisions architecturales durablement |
| Diagrammes | Produire des diagrammes versionnables avec Mermaid et C4 |
| Documentation API | Publier un contrat OpenAPI avec génération automatique |
| Bonnes pratiques | Maintenir une documentation vivante et testée |
| Cas avances | Déployer un site, versionner, mesurer |