Ce que la compilation vérifie
Les échecs silencieux qu’a connus cette couche, transformés en messages.
Chaque bogue qu’a réellement connu cette couche était silencieux : une collection que Content écartait parce que son nom n’était pas un identifiant JavaScript, une page en 404 parce qu’un lien avait vieilli, une navigation qui revenait vide. Aucun des trois ne disait quoi que ce soit — la compilation était verte et le site faux. Des vérifications s’exécutent donc après la compilation, toutes lisant la même chose : le cache d’analyse que Content laisse derrière lui.
| Vérification | Gravité |
|---|---|
| Une collection sans aucune page | erreur |
| Un dossier en conflit avec un segment d’URL | erreur |
Un title ou une description manquant | avertissement |
| Un lien interne ou une ancre cassés | avertissement |
| Ce qu’une section générée n’a pas pu lire | avertissement |
| Ce que porte chaque langue et ce qui s’est figé | note |
Pourquoi la gravité n’est pas uniforme
Une erreur coûte une page que personne ne peut atteindre et que rien sur le site n’expliquerait jamais — une collection vide, c’est un 404 sur chaque page d’une version. Un avertissement coûte de la qualité : la page s’affiche toujours, et une source distante peut vieillir d’une publication à l’autre sans que ce soit la faute de cette compilation. Faire échouer la compilation parce que le dépôt de quelqu’un d’autre a avancé rendrait une compilation verte dépendante d’un tiers.
Une note ne coûte rien du tout : c’est un état du site, pas un défaut dans le site. Une page non traduite n’est pas une faute, et la signaler comme avertissement apprendrait à tout le monde à passer les avertissements.
Sections générées
Une section générée est vérifiée comme toute autre collection, dans ses propres termes. Ce qui arrive dans ce rapport est l’une de trois choses :
- l’artefact n’était pas là à cette ref, la section n’a donc pas été construite ;
- le type n’en a rien lu, la section revendique donc des URL et n’en sert aucune ;
- le type est passé outre quelque chose — un
$refirrésoluble dans un document OpenAPI, un titre de changelog qui ressemble à une release mais ne s’analyse pas comme telle et s’est donc retrouvé intégré à la release au-dessus.
Les trois sont des avertissements, et ce n’est pas un compromis. Tout ce qu’un artefact local peut avoir de faux — un chemin qui n’existe pas, un fichier que le type ne sait pas lire du tout, une option qu’il ne connaît pas — fait déjà échouer la compilation pendant le chargement de la configuration, bien avant que ce rapport existe : la configuration propre du site est une faute que la compilation ne doit pas porter. Ce qui reste ici est soit un artefact distant, qui peut légitimement avoir vieilli d’une publication à l’autre, soit une page qui s’est affichée avec quelque chose en moins.
Un artefact est analysé pendant le chargement de la configuration : un
avertissement sur un $ref écarté était donc affiché avant même que le serveur
de développement ait fini de démarrer, et avait défilé quand quelqu’un regardait
enfin — alors que tous les autres constats de cette couche attendaient dans un
seul rapport. Ils passent désormais par le rapport, et avec lui par le panneau
Checks.
Le rapport de traduction
Une ligne par langue, à chaque compilation :
[duxt] translations
[duxt] de: 118/121 pages, 3 behind the original
[duxt] "docs/guides/deploying.md" has no de translation.
[duxt] "docs/de/concepts/sources.md" has not moved since the original changed.
Le second chiffre exige history: true sur la source : les dates viennent de
git, et une source qui n’a pas demandé son historique n’en a aucune. Sans lui le
rapport compte la couverture et ne dit rien du décalage, plutôt que de le
deviner à partir de l’absence.
Il existe à cause d’un échec précis. OpenCode a traduit sa documentation en dix-sept langues avec un agent en CI, a coupé le workflow, et nulle part il n’était dit que les traductions avaient cessé de bouger. La couche sait déjà, page par page, quelles langues la portent et quand chaque fichier a changé pour la dernière fois ; un rapport est ce qui en fait quelque chose que quelqu’un voit.
Le même rapport, en commande
Les constats vivent à deux endroits difficiles à transmettre à qui que ce soit :
un journal de compilation qui a défilé, et des panneaux de devtools qui
n’existent qu’à l’intérieur d’un serveur de développement en cours d’exécution.
duxt-report est le troisième — les mêmes données en Markdown sur stdout. Il
est livré avec le paquet : étendre la couche suffit donc à en disposer.
pnpm exec duxt-report # Markdown
pnpm exec duxt-report --json # les mêmes données, non rendues
Il lit l’app.config.ts du site, les artefacts à côté et les pages depuis le
cache d’analyse de Content — aucun serveur, il s’exécute donc en CI et dans
un pipe. Il sort en 1 sur une erreur et en 0 sur des avertissements, ce qui
est la règle de gravité que suit la compilation.
Trois panneaux n’ont pas d’équivalent ici, et délibérément : l’index de recherche, le débogueur de chemins et la liste du cache sont des questions sur un processus en cours d’exécution, et y répondre depuis l’extérieur reviendrait à deviner.
Les pages viennent du cache de Content : une page écrite depuis la dernière compilation ou la dernière exécution en développement n’y est donc pas. Lancez l’une ou l’autre d’abord — le rapport le dit clairement quand il ne trouve aucun cache, plutôt que de signaler chaque collection comme vide.
Ce que les vérifications savent et pas vous
- Une collision de dossiers n’est un problème que tant qu’un préfixe est
actif. Un dossier de documentation nommé
v2est correct sur un site non versionné et inaccessible sur un site versionné, car le préfixe l’emporte. La compilation sait de quel cas il s’agit, et le message nomme le fichier et propose la correction. - Un lien est résolu comme le thème le résout. Un chemin absolu écrit dans une page est relatif à la source de cette page : il est donc essayé d’abord sous le préfixe de la source, puis nu. Un vérificateur ne faisant que la forme nue signalerait chaque lien correct d’un site multi-dépôts.
- Un lien est résolu dans sa propre langue. Chaque langue d’une source sert des chemins de contenu identiques — la locale se place devant l’URL, pas dans l’arbre de contenu — et les ancres dérivent du texte des titres : un titre allemand a donc une ancre allemande. Une vérification résolvant par le seul chemin confronterait un lien allemand à des titres anglais et signalerait chaque ancre correcte d’un site traduit. Un lien vers une page qu’une langue ne porte pas se replie sur l’original, ce que fait aussi le site.
- Les URL externes ne sont pas vérifiées. En vérifier une mettrait le réseau dans la compilation, et un hôte tiers injoignable n’est pas une raison pour que votre documentation ne soit pas publiée.
Écrivez les liens en chemins de documentation absolus
/concepts/sources, et non ../2.concepts/2.sources.md. Le préfixe sous lequel
une page est servie est décidé à la compilation : écrire des chemins sans
préfixe est donc ce qui permet au même Markdown de servir /guides/deploying
sur un site et /acme/v2.0.0/guides/deploying sur un autre. C’est aussi la
seule forme que voit le vérificateur de liens.