31.10.26
readmeta 🚀 0.2 : corriger les liens README PyPI13 min de lecture2 534 mots

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.

corriger les liens README PyPIreadmetapublication package PythonREADME PyPIintégration continue Python
readmeta 🚀 0.2 : corriger les liens README PyPI

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 ![Capture](docs/capture.png) 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.whl et *.fixed.tar.gz sont 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.

Questions frequentes

Non. readmeta vérifie des références dans la description longue de l’artefact et peut en réécrire certaines. `twine check` a un autre rôle et ne signale pas nécessairement les liens qui échouent lors du rendu sur PyPI. Les deux contrôles ne sont donc pas interchangeables.
Non. L’outil crée une copie corrigée de l’artefact construit, par exemple un fichier `.fixed.whl` ou `.fixed.tar.gz`. Le README source et les fichiers d’entrée ne sont pas modifiés.
Une ancre doit correspondre à un identifiant présent dans la page. Si aucun titre ne correspond, convertir le lien en URL absolue ne répare pas sa destination. readmeta signale le problème et laisse la correction du titre ou du lien à l’auteur.
Oui. L’option `--base-url` permet de résoudre les références sous une URL de base, par exemple celle d’un CDN. Il faut toutefois s’assurer que les ressources sont effectivement publiées à ces adresses et qu’elles resteront accessibles.

Articles similaires