readmeta 🚀 0.2 : corriger les liens README PyPI
Découvrez readmeta 0.2 : corrige les liens README PyPI cassés à la construction, sans modifier vos sources. Intégrez-le à votre pipeline CI Python.

Des liens README cassés sur PyPI ? readmeta 0.2 les corrige à la construction
Un README peut être parfaitement lisible dans le dépôt GitHub, puis se retrouver incomplet une fois le paquet publié sur PyPI : images manquantes, liens relatifs qui pointent dans le vide, SVG qui ne s'affichent pas comme prévu. Et le pire, c'est que ça passe facilement entre les mailles du filet, parce que twine check ne fait pas toujours le même type de contrôle que le rendu réel côté PyPI.
La version 0.1 de readmeta inspectait la description longue produite pour l'artefact construit, pas uniquement le fichier README qui traîne dans le dépôt. La version 0.2 ajoute une étape pratique : avec --fix, l'outil réécrit certaines références problématiques dans une copie de l'artefact, pendant la construction. Les sources restent intactes. En clair : le README continue de fonctionner sur GitHub, tandis que la version destinée à PyPI reçoit les URL adaptées.
Voici ce que readmeta 0.2 peut corriger, ce qu'il ne peut pas, et comment l'intégrer sans rendre votre pipeline de publication plus fragile.
Pourquoi les README changent de comportement entre GitHub et PyPI
Un README Markdown n'est pas rendu dans le même contexte partout. Sur GitHub, les chemins relatifs sont interprétés à partir de l'emplacement du fichier dans le dépôt. Sur PyPI, c'est la description longue intégrée au paquet qui est affichée. Résultat : même si le texte « semble » identique, le rendu se fait depuis une autre base, donc pas les mêmes chemins.
Côté développement, on ne voit presque rien. Un lien du type [guide](docs/guide.md) peut très bien fonctionner depuis la page du dépôt. Une image écrite comme  peut aussi sembler OK. Mais une fois la même description rendue sur PyPI, le chemin relatif ne pointe plus forcément vers la ressource attendue. Au mieux, le lien renvoie quelque part d'inexistant ; au pire, il échoue carrément.
Souvent, la publication réussit : le paquet est bien téléversé, mais une image manque, ou un lien renvoie une erreur. Et si votre contrôle s'arrête au dépôt source, c'est exactement le genre de défaut qui passe inaperçu.
Pourquoi vérifier l'artefact publié
L'idée de readmeta est simple : contrôler la description longue telle qu'elle se retrouve réellement dans le paquet construit. C'est le bon niveau de vérification, parce que c'est cette version-là qui sera rendue sur PyPI.
La version 0.1 regardait déjà plusieurs cas : images et liens relatifs, SVG bruts, et ancres internes qui ne correspondaient à aucun titre. Ces références peuvent sembler valides sur GitHub et ne plus fonctionner sur PyPI. Et twine check ne détecte pas nécessairement ce qui casse au moment du rendu.
En pratique : tester uniquement le fichier source ne garantit pas que la documentation affichée sera utilisable. Si votre construction modifie la description, ou si vous publiez une roue et une archive source, c'est l'artefact final qu'il faut inspecter.
Le rĂ´le de la version 0.2
La version 0.2 ajoute --fix pour traiter une partie des problèmes détectés. Important : l'outil ne modifie pas le README dans le dépôt. Il produit une copie corrigée de l'artefact construit. Comme ça, on peut garder des sources reproductibles et conserver des références relatives côté dépôt.
Ce choix répond à une contrainte assez concrète : modifier manuellement un fichier dans dist/ juste après la construction, puis espérer que tout le monde reproduira exactement la même chose, c'est rarement fiable. À l'inverse, mettre des URL absolues directement dans le README source peut rendre l'affichage moins confortable sur GitHub, ou introduire une dépendance à une branche ou à une URL qui bouge.
Le principe de readmeta est donc : garder une source adaptée au dépôt, et ajuster ce qui doit l'être dans le paquet publié.
Ce que readmeta 0.2 corrige avec --fix
Avec --fix, readmeta réécrit les références relatives détectées quand il peut les convertir de façon cohérente. Pour les images, les URL générées pointent vers raw.githubusercontent.com. Pour les autres liens relatifs, elles pointent vers github.com/.../blob/....
Par défaut, la référence utilisée est main. Vous pouvez la préciser avec --ref si votre documentation correspond à une autre branche ou à une autre référence. Dans ce cas, évitez de choisir « au hasard » : l'URL générée doit correspondre au contenu que vous voulez associer à la version publiée.
Transformer les chemins relatifs en URL adaptées
Pour générer des URL GitHub, l'outil a besoin du dépôt, passé via --repo. Exemple :
readmeta check dist/* --fix --repo octo/demo
Dans ce scénario, une image sous docs/shot.png peut être réécrite en URL absolue du type https://raw.githubusercontent.com/octo/demo/main/docs/shot.png. Un lien vers un autre fichier du dépôt devient plutôt une URL du style github.com/.../blob/....
Cette conversion aide à faire correspondre le rendu PyPI à ce que vous vouliez, mais elle suppose que les fichiers existent bien à l'adresse générée. Si vous construisez à partir d'une référence autre que main, indiquez-la avec --ref ; sinon, un lien « valide » peut quand même afficher une version différente de celle que contient votre paquet.
Utiliser votre propre hébergement
GitHub n'est pas la seule destination possible. Avec --base-url, vous pouvez demander à readmeta de résoudre les références à partir d'une URL de base que vous contrôlez, par exemple :
readmeta check dist/* --fix --base-url https://cdn.example.com/static/
Ça peut être pratique si vos ressources de documentation sont distribuées via un CDN stable. Mais ça vous met aussi face à une responsabilité : maintenir les fichiers, et garder des chemins cohérents. Une URL absolue n'est pas « magiquement durable » : si la ressource est supprimée ou déplacée, le lien finira par casser.
Préserver le texte d'exemple
readmeta ne réécrit pas les références à l'intérieur des blocs de code clôturés, du code en ligne, ni des balises <pre> et <code>. C'est intentionnel : dans un README technique, un exemple peut volontairement contenir un lien relatif « cassé » pour illustrer un cas. Corriger automatiquement ces zones pourrait changer le sens du document.
En pratique, le contenu « informatif » et le contenu « exécutable ou démonstratif » ne sont pas toujours la même chose. Le fait d'exclure les zones de code réduit le risque qu'une correction automatique modifie une explication.
Intégrer readmeta à une publication Python
Le bon moment, c'est après la construction du paquet et avant le téléversement. L'outil inspecte les artefacts produits, crée des versions corrigées, puis vous publiez celles-là .
pip install readmeta
python -m build
readmeta check dist/* --fix --repo octo/demo
twine upload dist/*.fixed.*
Dans un script réel, retirez l'espace avant twine si vous copiez l'exemple tel quel : une commande shell ne doit pas commencer avec un espace en début de ligne. La séquence attendue est : installer readmeta, construire, vérifier et corriger, puis téléverser les artefacts qui portent le suffixe .fixed.
Une version sans l'espace initial :
twine upload dist/*.fixed.*
Les fichiers d'entrée ne sont pas modifiés. Par défaut, les artefacts corrigés sont créés à côté des originaux, avec un nom du style *.fixed.whl ou *.fixed.tar.gz. Vous pouvez aussi les envoyer dans un répertoire distinct avec --out-dir.
Pourquoi la correction se fait Ă la construction
dist/ contient des sorties générées. Modifier manuellement une roue ou une archive source après coup, c'est créer une étape que le code du projet ne décrit pas. La prochaine construction ne reproduira pas forcément ce que vous avez fait, et quelqu'un d'autre (ou vous, plus tard) peut passer à côté.
Faire le traitement pendant la publication (dans un pas de pipeline clair) est plus simple à automatiser : les sources restent lisibles et compatibles avec GitHub, et le paquet destiné à PyPI est corrigé de manière explicite. Ça ne supprime pas l'intérêt de vérifier le paquet, mais ça rend la transformation visible et traçable dans votre workflow.
Et oui, il y a aussi une raison « pragmatique » de ne pas inscrire systématiquement des URL absolues dans le README source. Une URL vers un tag GitHub peut renvoyer une erreur tant que le tag n'existe pas encore. On tombe vite dans un cercle vicieux : publier le tag pour que le README soit valide, alors que le contenu doit être prêt avant le tag. Utiliser une branche peut éviter cette attente, mais le contenu de la branche peut évoluer et ne plus correspondre à ce qui est réellement publié.
Comprendre les résultats et les codes de sortie
Après correction, readmeta sort un rapport : ce qui a été réécrit, et ce qui reste problématique. Par exemple, l'outil peut transformer une image relative en URL GitHub, puis signaler une ancre interne qu'il ne sait pas corriger automatiquement.
Les codes de sortie permettent d'intégrer l'outil dans une CI :
0: contrôle OK, ou problèmes corrigés entièrement ;1: il reste des problèmes impossibles à réécrire automatiquement (par exemple des ancres cassées) ;2: erreur d'exécution.
La distinction entre 1 et 2 compte. 1 signifie que du contenu doit être ajusté. 2 signifie que l'outil a échoué pendant le traitement. Dans une CI, vous pouvez donc faire échouer la publication si une référence exige une intervention manuelle, sans confondre ça avec un crash.
Limites, arbitrages et cas à vérifier
--fix n'est pas une baguette magique de réécriture. Il corrige ce pour quoi il peut déduire une destination absolue cohérente. Pour les erreurs éditoriales ou les problèmes de structure, il ne peut pas toujours « deviner » la bonne transformation.
Les ancres cassées restent manuelles
Une ancre comme #instalation devrait pointer vers un titre qui existe. Si aucun titre ne correspond à cet identifiant, la convertir en URL absolue ne changera rien : le fragment restera introuvable sur PyPI. readmeta signale donc le problème, mais c'est à vous de corriger la source.
Le plus souvent, il faut vérifier si le titre a changé, si l'identifiant est mal orthographié, ou si le lien cible une section supprimée. Ensuite seulement : corriger, reconstruire, et relancer.
Éviter les références qui dérivent
Une URL pointant vers main est pratique, mais une branche bouge. Si vous voulez une documentation associée à une version, choisir une référence explicite peut mieux refléter le contenu réellement publié. Attention quand même : il faut aussi gérer le moment où cette référence devient disponible, notamment si elle dépend d'un tag pas encore créé.
Ce n'est pas un détail : c'est un arbitrage entre disponibilité immédiate et fidélité à une version. Dans certains projets, une branche stable ou un hébergement contrôlé est préférable ; dans d'autres, une URL vers main suffit. Le bon choix dépend de votre façon de construire et de publier.
Contrôler les artefacts que vous téléversez
Comme les fichiers corrigés portent le suffixe .fixed, votre commande de téléversement doit viser ces fichiers, pas les originaux. Mélanger les deux motifs dans un script peut provoquer la publication des mauvaises versions (ou des deux), selon la commande utilisée. Regardez ce qui sort réellement dans dist/ avant d'automatiser.
Avant d'activer le téléversement automatique, testez le flux sur un paquet de préproduction (ou sans publication réelle). Vérifiez notamment :
- que
*.fixed.whlet*.fixed.tar.gzsont bien générés ; - que les chemins réécrits correspondent aux ressources réellement présentes ;
- que les ancres restantes sont bien examinées ;
- que la commande de téléversement ne sélectionne que les fichiers attendus.
Et petit clin d'œil : le paquet readmeta applique ce principe à lui-même. Lors de la préparation de la version 0.2, son propre contrôle a repéré un lien relatif [LICENSE](LICENSE) dans le README. La documentation publiée a ensuite été ajustée pour utiliser une URL GitHub absolue. Autrement dit : un contrôle automatique est aussi utile quand il montre un défaut dans l'outil qui le fait.
Installation et périmètre du projet
readmeta s'installe avec pip install readmeta. La version décrite ici (0.2) est annoncée compatible avec Python 3.9 et les versions ultérieures, n'utilise que la bibliothèque standard, et est distribuée sous licence MIT. Vous pouvez consulter le projet readmeta sur PyPI et son dépôt GitHub.
Utiliser la bibliothèque standard limite la surface de dépendances, mais ne supprime pas l'intérêt de tester dans votre environnement de construction. Comme pour tout outil de publication : faites un test avec vos propres roues, archives et habitudes de README avant de l'ajouter à une étape sensible.
Conclusion
readmeta 0.2 règle un problème fréquent : un README qui semble OK sur GitHub ne garantit pas un rendu complet sur PyPI. Son intérêt ne tient pas seulement à --fix, mais aussi à son mode de fonctionnement : inspecter l'artefact, produire une copie corrigée à la construction, et laisser les sources intactes.
Ça ne remplace pas une relecture ni une validation du paquet. Les ancres cassées restent à corriger à la main, et les URL générées doivent correspondre à la bonne référence (ou à votre hébergement). Mais pour éviter de publier des images ou des liens relatifs défectueux, l'étape est simple à tester et facile à automatiser.
Installez readmeta, lancez-le sur vos artefacts de test, puis vérifiez ce que votre commande de téléversement sélectionne réellement. C'est le moyen le plus direct de savoir si l'étape améliore votre pipeline sans ajouter de surprise au moment de publier.