Guide du contributeur
Ce guide explique pas à pas comment contribuer à meteopendata2netcdf, de la création d’une branche de travail jusqu’à la publication d’une nouvelle version sur PyPI, en passant par la CI, les tests et la documentation.
Il s’adresse à toute personne souhaitant corriger un bug, ajouter une fonctionnalité ou intégrer une nouvelle source de données.
Prérequis
Avant de commencer, assurez-vous d’avoir :
Python >= 3.12 installé (vérifiez avec
python --version)git installé
eccodes installé sur votre système (requis par
cfgrib) :# Linux (Debian/Ubuntu) sudo apt-get install libeccodes-dev # macOS brew install eccodes # Windows : inclus dans la wheel cfgrib, aucune action supplémentaire
Un compte GitHub avec accès en écriture au dépôt (ou un fork si vous n’êtes pas encore collaborateur)
Clonage et installation
# Cloner le dépôt
git clone https://github.com/miki4iaml/meteopendata.git
cd meteopendata
# Installer le package en mode éditable avec tous les extras
pip install -e ".[dev,docs]"
# Vérifier que l'installation est fonctionnelle
python -c "import meteopendata2netcdf; print(meteopendata2netcdf.__version__)"
# Vérifier que la suite de tests passe
pytest -m "not network"
Stratégie de branches
Le projet utilise un modèle de branches structuré pour s’intégrer proprement avec PyPI et Read the Docs.
Vue d’ensemble
main ← branche de référence (toujours stable, toujours publiable)
│
├── develop ← intégration des features avant merge sur main
│ ├── feature/nom-de-la-feature
│ ├── fix/description-du-bug
│ └── docs/description-de-la-doc
│
└── (tags) ← v0.2b0, v0.3b0, ..., v1.0.0, v1.1.0, ...
Description de chaque branche
- ``main``
La branche de production. Tout ce qui est sur
mainest publié sur PyPI et correspond à la versionlatestsur Read the Docs. On n’y pousse jamais directement (hors corrections critiques). Chaque merge surmainprovient d’une pull request validée avec CI verte.- ``develop``
La branche d’intégration. Les features et corrections sont mergées ici en premier. Quand
developest stable et que l’on veut préparer une release, on mergedevelopsurmain.- ``feature/*``, ``fix/*``, ``docs/*``
Branches de travail éphémères, créées depuis
develop, supprimées après merge. Exemples :feature/aifs-support— ajout du support du modèle AIFSfix/grib-multigroup-windows— correction d’un bug Windowsdocs/ecmwf-source-page— rédaction d’une page de documentation
Intégration avec Read the Docs
Read the Docs construit automatiquement plusieurs versions de la documentation :
Version RTD |
Branche/tag correspondant |
Quand la configurer |
|---|---|---|
|
|
Automatique (défaut RTD) |
|
Dernier tag |
Automatique dès la v1.0.0 |
|
Tags correspondants |
Activer dans RTD → Versions → Activer |
|
Branches |
À partir de la v1.0.0 |
Pour activer une version de doc sur RTD : aller dans l’interface Read the Docs → Versions → cocher la version souhaitée → Save.
Astuce
Pendant la phase bêta (0.x), seules latest (= main) et les tags
de release sont utiles. Les branches v1, v2… n’ont de sens qu’à
partir de la version 1.0.
Cycle de vie d’une contribution
Étape 1 — Créer sa branche de travail
Toujours partir depuis develop à jour :
# Se placer sur develop et la mettre à jour
git checkout develop
git pull origin develop
# Créer et basculer sur la nouvelle branche
# Convention de nommage : type/description-courte-en-kebab-case
git checkout -b feature/aifs-support
# ou
git checkout -b fix/grib-multigroup-windows
# ou
git checkout -b docs/ecmwf-ensemble-page
Étape 2 — Développer
Travaillez normalement. Quelques règles :
Un commit = une unité logique cohérente. Préférez plusieurs petits commits à un seul commit géant.
Messages de commit en anglais, au format
type: description courte(50 caractères max sur la première ligne) :git commit -m "feat: add AIFS model support" git commit -m "fix: handle missing heightAboveGround coord in cfgrib" git commit -m "docs: add ENFO parameters table in ecmwf.rst" git commit -m "test: add unit tests for AIFS downloader" git commit -m "chore: bump version to 0.3b0" git commit -m "refactor: extract _validate_steps() from _downloader.py"
Types reconnus :
feat,fix,docs,test,chore,refactor,perf,ci.Ne pas committer : fichiers
.grib2,.nc,.idx,htmlcov/,dist/,*.egg-info/(tous listés dans.gitignore).
Étape 3 — Vérifier localement avant de pousser
Avant chaque push, lancer la chaîne qualité complète. Un push avec des erreurs de lint ou des tests cassés fait échouer la CI et bloque la PR.
# 1. Lint : détection d'erreurs et vérification du formatage
ruff check src tests
ruff format src tests
# 2. Vérification des types
mypy src/meteopendata2netcdf
# 3. Tests (hors réseau — pas de téléchargement ECMWF)
pytest -m "not network" --tb=short
# 4. Tests avec rapport de couverture
pytest -m "not network" --cov=meteopendata2netcdf --cov-report=term-missing
# La couverture doit rester >= 80 % (fail_under = 80 dans pyproject.toml)
Astuce
Pour corriger automatiquement les erreurs de lint et de formatage :
ruff check --fix src tests
ruff format src tests
Étape 4 — Pousser la branche
# Premier push (crée la branche sur GitHub)
git push -u origin feature/aifs-support
# Pushs suivants
git push
Étape 5 — Ouvrir une Pull Request vers develop
Sur GitHub :
Aller sur la page du dépôt
GitHub affiche une bannière « Compare & pull request » pour votre branche — cliquer dessus (ou aller dans Pull requests → New pull request)
Vérifier que la cible est bien ``develop`` (et non
main)Remplir le titre et la description :
Titre : même format que les commits (
feat: ...,fix: ...)Description : expliquer pourquoi le changement, pas seulement quoi
Mentionner l’issue résolue si applicable (
Closes #42)
Cliquer Create pull request
La CI se déclenche automatiquement sur la PR (workflow ci.yml) :
✅ Lint (ruff check + ruff format)
✅ mypy strict
✅ Tests sur 6 combinaisons OS × Python (Linux, Windows, macOS × 3.12, 3.13)
✅ Build wheel + sdist + twine check
La PR ne peut pas être mergée tant que la CI n’est pas entièrement verte.
Étape 6 — Review et merge dans develop
Après validation :
# Sur GitHub : cliquer "Squash and merge" ou "Merge pull request"
# (Squash and merge recommandé pour garder develop propre)
# Supprimer la branche de travail après merge (bouton GitHub ou en ligne)
git push origin --delete feature/aifs-support
# Mettre à jour develop localement
git checkout develop
git pull origin develop
Préparer et publier une release
Une release est déclenchée quand develop contient un ensemble de
changements cohérents et stables que l’on veut publier sur PyPI.
Étape 1 — Mettre à jour la version et le changelog
Sur une branche dédiée depuis develop :
git checkout develop
git pull origin develop
git checkout -b chore/release-0.3b0
Modifier ``pyproject.toml`` :
[project]
version = "0.3b0"
Mettre à jour ``CHANGELOG.md`` en déplaçant la section [Unreleased]
vers la nouvelle version :
## [0.3b0] — 2026-07-15
### Added
- Support du modèle AIFS (stream oper, résolution 0.25°)
### Fixed
- Correction de la gestion des groupes GRIB sur Windows
## [Unreleased]
*(rien pour l'instant)*
Committer :
git add pyproject.toml CHANGELOG.md
git commit -m "chore: bump version to 0.3b0"
git push -u origin chore/release-0.3b0
Ouvrir une PR chore/release-0.3b0 → develop, la merger après CI verte.
Étape 2 — Merger develop dans main
git checkout main
git pull origin main
git merge --no-ff develop -m "release: merge develop into main for v0.3b0"
git push origin main
La CI se relance sur main. Attendre qu’elle soit verte avant de continuer.
Étape 3 — Créer le tag Git
# Créer un tag annoté (recommandé : contient un message et une date)
git tag -a v0.3b0 -m "Release v0.3b0"
# Pousser le tag
git push origin v0.3b0
Étape 4 — Créer la release GitHub
Sur GitHub (méthode IHM — recommandée) :
Releases → Draft a new release
Choose a tag → sélectionner
v0.3b0Target →
mainRelease title →
v0.3b0Description → coller le contenu du CHANGELOG pour cette version
Cocher « Set as a pre-release » si version bêta (suffixe
b)Cliquer Publish release
Avertissement
La création d’une release via l’IHM GitHub déclenche l’événement
release: published, pas l’événement push: tags. Le workflow
publish.yml est configuré pour répondre aux deux. Si vous avez créé
le tag en ligne de commande avant la release GitHub, le workflow aura
déjà été déclenché par push: tags.
Pour éviter une double exécution, l’ordre recommandé est :
Pousser le tag (
git push origin v0.3b0) → déclenchepublish.ymlCréer la release GitHub manuellement sans repousser le tag
Étape 5 — Vérifier la publication
Dans l’onglet Actions → Publish to PyPI :
Publish to PyPI
├── Build ← construction wheel + sdist
└── build-and-publish
├── Checkout
├── Build
└── Publish to PyPI (Trusted Publishing OIDC)
↑ échange un token de courte durée avec PyPI
sans aucun secret stocké dans GitHub
Après succès, vérifier sur PyPI :
https://pypi.org/project/meteopendata2netcdf/0.3b0/
Étape 6 — Activer la version sur Read the Docs
Read the Docs détecte automatiquement le nouveau tag. Pour rendre la documentation de cette version accessible :
Aller sur
https://readthedocs.org/projects/meteopendata2netcdf/versions/Trouver
v0.3b0dans la listeCliquer Edit → cocher Active → Save
La documentation sera disponible sur :
https://meteopendata2netcdf.readthedocs.io/en/v0.3b0/
Gestion des versions majeures (à partir de v1.0)
À partir de la version 1.0, une branche de maintenance v1 sera créée
pour permettre des correctifs sur la v1 tout en développant la v2 sur
develop.
Création de la branche v1 au moment du tag v1.0.0
# Après avoir mergé develop → main et créé le tag v1.0.0
git checkout main
git checkout -b v1
git push origin v1
Cette branche v1 :
reçoit les correctifs critiques (backports depuis
develop)est configurée dans Read the Docs comme version active permanente
est protégée en écriture directe sur GitHub (PRs obligatoires)
Modèle de branches avec plusieurs versions majeures
main ← v2.x en développement actif
│
├── develop ← intégration features v2.x
├── v1 ← maintenance v1.x (correctifs uniquement)
│
├── (tags) v1.0.0, v1.1.0, v1.2.3 ...
└── (tags) v2.0.0b0, v2.0.0 ...
Intégration Read the Docs multi-versions
URL RTD |
Source |
Usage |
|---|---|---|
|
branche |
Développement en cours (peut être instable) |
|
Dernier tag sans |
Référence recommandée pour les utilisateurs |
|
branche |
Documentation maintenance v1 |
|
tag |
Version exacte archivée |
Pour configurer RTD correctement :
Settings → Default branch →
mainVersions → v1 → Active = oui, Privacy = Public
Advanced Settings → Default version →
stable(pointe sur le dernier tag non-bêta)
Déclenchement manuel de la CI
Si la CI ne s’est pas déclenchée automatiquement (par exemple après un changement de configuration GitHub Actions), vous pouvez la déclencher manuellement :
GitHub → Actions → [nom du workflow] → Run workflow → Sélectionner la branche → Run
Pour publish.yml spécifiquement (re-publier une version déjà taguée) :
GitHub → Actions → Publish to PyPI → Run workflow → main → Run
Avertissement
PyPI refuse catégoriquement le re-upload d’une version existante. Si le workflow de publication échoue après que la wheel a déjà été uploadée, il faut obligatoirement incrémenter la version avant de retenter.
Règles de contribution (résumé)
Toujours partir depuis ``develop``, jamais depuis |
|
Un PR = une fonctionnalité ou un correctif. Ne pas mélanger refactorisations et ajouts de fonctionnalités. |
|
La CI doit être entièrement verte avant de demander un merge. |
|
Tout nouveau code public doit être couvert par des tests. La couverture ne doit pas descendre sous 80 %. |
|
Zéro dépendance réseau dans les tests. Toute interaction avec
|
|
Les docstrings suivent le style Google (Args, Returns, Raises). |
|
Mettre à jour ``CHANGELOG.md`` dans la section |
|
Ne pas modifier la version dans ``pyproject.toml`` dans un PR de
fonctionnalité. La version est incrémentée uniquement dans un PR de
release dédié ( |
|
Ne jamais forcer un push sur ``main`` ( |
|
Signaler les problèmes via les Issues GitHub avant d’ouvrir un PR pour discuter de l’approche. |
Ajouter le support d’une nouvelle source de données
L’ajout d’une nouvelle source (par exemple NOAA GFS) suit un modèle reproductible :
Créer la branche
feature/noaa-gfs-supportdepuisdevelopAjouter un module
src/meteopendata2netcdf/sources/noaa.pyavec :Une classe
NOAAGFSDownloadersuivant la même interface queIFSSurfaceDownloader(méthodesdownload()etget_latest_run_time())Un dataclass
DownloadResultou réutiliser celui existantDes constantes dans
_constants.pyou dans un module dédié
Écrire les tests dans
tests/test_noaa.pyen mockant tous les appels réseau (même approche quetest_downloader.py)Documenter la source dans
docs/source/sources/noaa.rsten suivant le modèle dedocs/source/sources/ecmwf.rstMettre à jour
docs/source/sources/index.rst,__init__.py(__all__),CHANGELOG.mdetdocs/source/vision.rst(périmètre couvert)Ouvrir un PR vers
developavec la CI verte
Avant d’intégrer une nouvelle source, vérifier qu’elle n’est pas déjà
couverte par meteofetch ou une autre bibliothèque établie — voir la
philosophie du projet dans Vision et objectifs du projet.