Planificateur de mise à niveau Sanity Studio
Génère un plan de mise à niveau pour Sanity Studio dans le dépôt actuel.
La valeur du plan réside dans la soustraction. Une liste de tous les changements non compatibles entre deux versions existe déjà ; elle s'appelle le changelog, et elle n'est pas utile à quelqu'un en pleine mise à niveau. Cette compétence produit la liste beaucoup plus courte des changements applicables à ce dépôt, ainsi que les questions qu'un humain seul peut répondre.
Trois règles qui déterminent si la sortie est fiable
1. Ne jamais énoncer un numéro de version de mémoire. Cherche-le et confirme qu'il existe.
Les versions des paquets changent chaque semaine. Chaque version du rapport doit provenir soit du fichier de verrous du dépôt (pour l'état actuel), soit d'une requête de registre en direct (pour les cibles). Si une recherche n'est pas possible, dis-le dans le rapport plutôt que de deviner. Un plan qui nomme une version « latest » obsolète est pire qu'aucun plan, car le lecteur agira dessus.
Il existe une deuxième version, pire, de cet échec : un numéro de version qui n'a jamais été publié, obtenu en supposant qu'un paquet suit la numérotation d'un autre. Celle-ci échoue à l'installation. Tout numéro de version que tu t'apprêtes à décrire comme « lockstep » ou « correspond au noyau » a besoin d'une vérification d'existence d'abord.
La même chose s'applique aux noms d'API. Une exportation, un sous-chemin d'importation ou une signature de fonction rappelée de mémoire est une supposition, et c'est une supposition que le lecteur collera dans son éditeur. Lis-la depuis le README du paquet ou sa carte exports, ou marque-la avec un commentaire // VERIFY: en ligne dans l'extrait lui-même. Voir la section 6 de plugins.md et la section 8 de report-template.md.
2. Lire et rapporter. Ne jamais modifier.
Inspecte des fichiers, exécute des commandes shell en lecture seule, interroge les registres. Ne modifie pas package.json, les fichiers de configuration ou le code source. Le lecteur décide ce qui change ; un planificateur qui modifie le code sera désactivé. Si l'utilisateur te demande explicitement de réaliser la mise à niveau après, c'est une tâche séparée à laquelle il a consenti.
Où la ligne s'établit réellement, car une version vague de cette règle rend un agent hésitant sur des commandes qui vont bien :
- Jamais : écrire dans n'importe quel fichier du dépôt, installer dedans, ou muter un fichier de verrous.
pnpm install,npm install,npm cietnpxsans--no-installsont tous exclus. - Correct : lire des fichiers et les lectures réseau telles que
npm view, une récupération de changelog, ounpm packdans un répertoire temporaire en dehors du dépôt que tu supprimes ensuite. - Recommandé au lecteur, non exécuté par toi :
pnpm install --lockfile-onlyest comment une prédiction de dépendance se confirme. Elle appartient au rapport en tant que commande pour que le lecteur l'exécute, avec ce qu'il faut attendre. Ne l'exécute pas toi-même, car elle réécrit son fichier de verrous.
Le seul endroit où cette compétence écrit quelque chose est en déballant une archive pour inspecter des déclarations de type, et la section 6 de plugins.md montre comment garder cela en dehors du projet.
3. Sépare ce que tu as vérifié de ce que tu as déduit.
Chaque découverte se classe dans l'un des trois groupes : applicable confirmé (tu as trouvé la condition dans le repo), nécessite une réponse humaine (tu ne peux pas le déterminer à partir du code), ou non applicable (l'omettre entièrement). Ne rembourre jamais le rapport d'éléments que tu n'as pas pu vérifier. Un rapport court honnête est meilleur qu'un qui semble complet.
L'une des conséquences est facile à manquer et vaut la peine d'être énoncée sans détour : un planificateur en lecture seule n'a pas de résolveur de dépendances, donc il ne peut pas savoir ce qu'un arbre contiendra après un changement. Les prédictions sur la déduplication appartiennent au rapport en tant que attentes avec la commande de vérification jointe, jamais en tant que découvertes. Voir package-coupling.md.
Les règles de vérification, en un seul endroit
Elles sont référencées par numéro dans tous les fichiers de référence, elles sont donc énoncées une seule fois ici plutôt que réénoncées dans chacun. Tout ce qui précède est R1 à R4 ; le reste est les façons spécifiques dont ces dernières se trompent.
| Règle | Où cela pose problème | |
|---|---|---|
| R1 | Ne jamais énoncer une version de mémoire. Prendre l'état actuel du fichier de verrous, les cibles d'une requête de registre en direct. | version-lookup.md §1 |
| R2 | Lire et rapporter. Rien ne change dans le dépôt, rien n'est installé, aucun fichier de verrous n'est muté. | Ci-dessus, et plugins.md §6 |
| R3 | Séparer vérifié de déduit. Ne jamais affirmer ce qu'un arbre de dépendances contiendra après un changement ; un planificateur n'a pas de résolveur. | package-coupling.md §6, plugins.md §5 |
| R4 | Confirmer que chaque version recommandée a réellement été publiée avant qu'elle n'entre dans le rapport. | version-lookup.md §3 |
| R5 | Chaque « X nécessite Y » nomme le manifeste d'où il a été lu, à la version en cours d'installation à cet arrêt. Les exigences ne se reportent pas vers l'arrière à travers les majeurs. | version-lookup.md §6 |
| R6 | Évalue une plage de versions, ne la lis jamais. Tout ce qui contient un \|\|, un <, ou deux comparateurs dans une clause passe d'abord par semver.satisfies. |
version-lookup.md §6 |
| R7 | Un nom dans une liste d'exportation n'est pas une exportation fonctionnelle. Vérifie son type déclaré et toute balise @deprecated ; never signifie supprimé. |
plugins.md §6 |
R6 et R7 existent parce que tous les deux ont déjà produit des conseils confiants, incorrects et spécifiques : une version de Node signalée comme non supportée alors qu'elle était correcte, et une modification de code requise classée sous « déjà satisfait ». Ils sont bon marché à exécuter et échouent silencieusement quand ils sont ignorés.
Portée : v3 et ultérieures
Cette compétence planifie les mises à niveau à partir de Studio v3 et ultérieures. Studio v2 est hors de portée et est un arrêt définitif.
Ce n'est pas que v2 soit difficile. C'est que v2 vers v3 est une réécriture de la couche configuration et plugin de Studio plutôt qu'une mise à niveau de dépendance : le format de config a changé, le système « parts » sur lequel v2 plugins et les remplacements étaient construits n'existe plus, les paquets ont été consolidés, et une grande partie de l'écosystème de plugins d'époque v2 n'a jamais été porté. Un plan généré pour cette limite serait une liste de spécificités confiantes que cette compétence ne peut pas vérifier, remise à quelqu'un qui s'apprête à passer des semaines sur le travail. C'est le pire résultat possible.
Si tu détectes v2, arrête et rapporte plutôt que de planifier. L'étape 1 couvre la détection et ce qu'il faut dire. N'écris pas de fichier de plan pour un projet v2.
Procédure
Étape 1 : Établir la vérité terrain et vérifier le plancher de version
Lis references/detect.md et suis-le. Il liste les fichiers à lire, les commandes à exécuter et les faits à enregistrer.
La plus grande erreur commune est de lire les versions de package.json. Les plages avec caret ne sont pas les versions installées. Obtiens la version résolue du fichier de verrous.
La deuxième plus grande erreur commune est de les lire du mauvais fichier de verrous. Un dépôt peut contenir plusieurs installations qui ne concordent pas, donc décide quel arbre le plan concerne, prends tous les faits de version de cet arbre, et nomme-le dans l'en-tête du rapport.
S'il n'y a pas de Sanity Studio dans ce dépôt, dis-le et arrête-toi.
Vérifie ensuite le plancher avant de faire autre chose. Si le majeur sanity résolu est inférieur à 3, ou s'il n'y a pas de paquet sanity et que le projet dépend de paquets d'époque v2 tels que @sanity/base ou @sanity/desk-tool, ou s'il y a un sanity.json et pas de sanity.config.*, c'est un projet v2. Arrête-toi là et dis au lecteur :
- Ce que tu as détecté et la preuve en est
- Que cette compétence couvre v3 et ultérieures, et pourquoi v2 vers v3 est une sorte de projet différente : une réécriture de la couche configuration et plugin, pas un bump de version
- Que le point de départ qui convient est le guide officiel de migration v2 à v3, qu'il devrait trouver sur le site de documentation Sanity plutôt que de te le prendre en deuxième main
- Que chaque plugin d'époque v2 a besoin de sa propre vérification de compatibilité, car beaucoup n'ont jamais été portés
- Qu'une fois qu'ils sont sur v3, exécuter à nouveau cette compétence planifiera le reste de l'intervalle, ce qui est un travail beaucoup plus petit
Sois utile à ce sujet. Un arrêt définitif qui s'explique et pointe quelque part est une bonne réponse ; un refus ne l'est pas. Mais ne l'adoucis pas en plan partiel, et n'estime pas le travail v2 vers v3.
Si sanity.json et sanity.config.* sont tous les deux présents, traite la version sanity résolue comme autoritaire. Un sanity.json résiduel dans un projet autrement v3+ vaut la peine d'être mentionné comme nettoyage, pas une raison de s'arrêter.
Étape 2 : Déterminer l'intervalle
Tu as besoin de deux versions : de (résolue, installée) et à (la cible).
Lis references/version-lookup.md pour savoir comment interroger les versions actuelles et les changelogs de manière autoritaire.
La cible est latest. Recommande-la et donne le raisonnement. Atterrir court signifie faire tout le travail et rester quand même en retard, et plus important encore, les versions actuelles des plugins suivent le noyau actuel, donc un noyau plus ancien avec des plugins actuels produit souvent un pire arbre de dépendances que la version la plus récente. Rapporte la date de publication de la cible et une alternative d'une ligne pour que le lecteur puisse appliquer les contraintes que tu ne peux pas voir, mais c'est une divulgation, pas une réserve, et cela ne change pas la recommandation. Dévie seulement pour une contrainte que le lecteur a réellement énoncée, et donne ensuite à la cheville une date d'examen.
Énonce l'intervalle explicitement dans le rapport. Un projet v3 et un projet v5.31 sont des travaux complètement différents et le lecteur doit savoir lequel il a.
Étape 3 : Charger seulement les limites que tu franchis
Lis d'abord references/boundaries.md. C'est un court index : les bornes de couverture, la règle de récupération à deux bordures, et un tableau indiquant quels fichiers de limite l'intervalle a besoin.
Puis ne lis que ces fichiers. Le contenu des limites est divisé un fichier par majeur, donc un intervalle qui franchit une limite charge un fichier plutôt que tous. Un projet sur 5.31 franchissant v6 lit l'index, boundary.v6.md et deprecations.md, et rien d'autre : les fichiers v4 et v5 coûteraient du contexte et inviteraient des découvertes qui ne s'appliquent pas.
Chaque boundary.v*.md contient le franchissement dans ce majeur plus les changements à l'intérieur de la ligne de ce majeur, car un intervalle qui franchit une limite atterrit quelque part dans la ligne au-dessus et a besoin des deux.
Puis lis references/package-coupling.md. Elle s'applique à chaque intervalle.
Étape 4 : Récupère ce que les références ne couvrent pas
references/boundaries.md déclare deux bornes sur sa couverture intra-ligne, et les deux doivent être respectées.
Récupère le changelog pour toute partie de l'intervalle qui tombe au-dessus de la borne supérieure ou au-dessous de la borne inférieure. Un projet commençant en-dessous de la borne inférieure a besoin de deux récupérations : de sa version actuelle jusqu'à cette borne, et de la borne supérieure à la cible. Le milieu organisé est utilisé tel quel.
La borne inférieure importe autant que la supérieure, et elle échoue plus silencieusement. Sans elle tu vas faire confiance au fichier pour une plage qu'il n'a jamais examinée et rapporter que rien là ne s'applique, ce qui se lit comme une découverte vérifiée et est en réalité un vide inxaminé. Ne déclare jamais qu'une plage est propre à moins qu'elle ne soit intérieure aux bornes déclarées ou que tu l'aies récupérée toi-même et obtenu un contenu réel en retour.
Cette dernière clause n'est pas du remplissage. En-dessous de la borne inférieure le changelog en amont n'existe pas du tout, donc la récupération retourne presque rien, et une récupération vide n'est pas une plage propre. boundaries.md dit quelle plage cela affecte et ce qu'il faut rapporter à la place. Rapporter le silence comme « rien ne s'applique » là est la façon la plus facile pour cette compétence de produire un mensonge confiant.
Fais particulièrement attention aux changements non compatibles qui ont été livrés dans les versions mineures sans être étiquetés comme non compatibles. Ce sont ceux qui surprennent les gens, car personne ne lit les notes de version mineures sur quarante versions. Les références en listent les exemples connus ; suppose que d'autres existent.
Étape 5 : Tester l'applicabilité
Pour chaque changement candidat, trouve la condition dans le dépôt. Si tu ne peux pas le déterminer à partir du code, il va dans la section questions humaines, pas dans les découvertes.
Exemples de la différence :
- « Les fournisseurs d'authentification personnalisés remplacent maintenant les intégrés au lieu de s'ajouter » → grep la config pour un bloc
auth. Présent ou absent. Déterminable. - « La stratégie de recherche par défaut a changé, les résultats vont s'estomper » → si cela importe dépend de comment les éditeurs cherchent. Non déterminable. Pose la question.
Préfère les conditions que tu peux réellement évaluer. grep -r "data-slate" est un vrai test. « Avez-vous des composants personnalisés complexes ? » ne l'est pas.
Étape 6 : Résoudre le graphe de dépendances
Applique references/package-coupling.md. C'est là que la plupart des mises à niveau cassent réellement, et c'est la partie qu'un changelog ne peut pas te dire, car elle dépend de quels paquets ce projet arrive à dépendre directement.
La règle qui importe le plus : pour tout paquet @sanity/* duquel le projet dépend directement, vérifie quelle version la version sanity cible dépend et apparie ça, plutôt que de prendre la latest du paquet. Prendre latest pour un paquet partagé comme @sanity/ui met deux majeurs de lui dans un arbre de dépendances, ce qui produit des erreurs de contexte dupliqué et des composants non stylisés qui ressemblent à des bugs non liés.
Étape 6b : Évaluer les plugins
Lis references/plugins.md et suis-le chaque fois que le projet a un plugin, ce qui est presque toujours.
Les plugins bloquent plus de mises à niveau que Studio lui-même ne le fait, ils ont donc leur propre passage et leur propre section dans le rapport. Trois choses à porter dedans : vérifie la compatibilité de chaque plugin plutôt que de l'assumer d'après qui le publie ; laisse la propriété décider le chemin une fois que quelque chose est incompatible, pas le verdict ; et vérifie la forme API de tout extrait que tu écris contre le paquet, séparé de la vérification de sa version, car une version compatible peut toujours avoir renommé l'exportation que tu t'apprêtes à recommander.
Étape 7 : Rédige le rapport
Suis references/report-template.md exactement. Écris-le dans SANITY-UPGRADE-PLAN.md à la racine du dépôt sauf si l'utilisateur nomme un chemin différent.
Écris un fichier plutôt que seulement d'imprimer au terminal. Le plan a généralement besoin de rejoindre des gens qui ne sont pas à ce clavier : un chef, un relecteur, un ingénieur support. Un fichier peut aller dans une pull request ou être collé dans un thread ; la sortie terminal ne peut pas.
Appels de jugement qui méritent d'être énoncés explicitement
Recommande une séquence, pas un seul saut. Franchir plusieurs majeurs dans un commit rend les défaillances impossibles à attribuer. Suggère des arrêts intermédiaires à la dernière version de chaque majeur, et dis pourquoi : cela isole chaque ensemble de changements.
Mais un arrêt n'est réel que s'il est atteignable. Chacun a besoin que ses versions de plugin soient résolues, car un plugin ne visant que les majeurs récents peut rendre un arrêt intermédiaire impossible à installer. Si tu ne peux pas résoudre un arrêt, étiquette-le comme provisoire plutôt que de présenter la séquence comme validée. Moins d'arrêts vérifiés battent plus hypothétiques.
Quand tu lâches un arrêt, nomme ce que cela coûte. Le sauter est souvent juste : une limite dont le seul changement applicable est un plancher Node ne vaut pas un commit de son propre, et un arrêt qui ne peut pas être atteint sans un majeur dupliqué forcé est pire qu'aucun arrêt. Mais le saut résultant traverse ensuite deux limites à la fois, et c'est exactement la chose que la séquence existe pour prévenir. Un plan qui montre la preuve de sauter et reste silencieux sur la conséquence se lit comme si l'échange était gratuit.
Donc énonce les deux moitiés : pourquoi l'arrêt a été lâché, et qu'une défaillance dans le saut combiné pourrait provenir de l'une ou l'autre limite, donc la déboguer signifie bissecter plutôt que lire le plan. Une phrase le couvre. Le lecteur peut accepter l'échange une fois qu'il peut le voir.
Taille le travail honnêtement. Si le projet a deux fichiers important de @sanity/ui et pas d'authentification personnalisée, dis que la mise à niveau est petite. Gonfler la portée pour avoir l'air thorough gaspille la semaine du lecteur. Également, si le projet importe de sanity/_internal ou a une grande surface de composants personnalisés, dis que la mise à niveau est substantielle plutôt que de produire un plan qui rend le travail dur facile à la vue.
Fais le plan survivre à une lecture en travers. Il le fera. Un plan multi-limite monte à plusieurs milliers de mots, et la personne qui le lit s'apprête à passer une semaine sur le travail, pas une après-midi à étudier le document. Donc le haut du plan porte le tout en un écran, tout en-dessous est référence à lire comme le travail le rejoint, et les découvertes sont groupées par ce que le lecteur a à faire plutôt que par quelle version le changement venait. L'échec spécifique à concevoir contre : un changement qui échoue silencieusement, assis dans un tableau uniforme entre deux qui sont cosmétiques, avec un poids visuel identique. La longueur n'est pas l'ennemi ; le poids plat l'est.
Écris pour l'ingénieur qui doit faire le travail, et décris l'arbre plutôt que l'équipe. Ce plan est généralement lu par quelqu'un au client, souvent quelqu'un qui n'a pas pris les décisions qui produisirent l'état actuel. Garde la preuve, la spécificité et la sévérité exactement aussi fortes que les faits le soutiennent : adoucir un vrai bloqueur ou un vrai coût est un désservice, et un ingénieur peut le dire. Ce qu'il faut lâcher est le verdict implicite. « Le pipeline de déploiement est construit à partir des plages caret plutôt que du fichier de verrous » et « quiconque a mis cela en place s'est trompé » contiennent la même découverte, et seulement une d'elles est actée. Réserve « tu » pour ce qu'il faut faire ensuite. Reste dedans aussi : une dépendance inutilisée n'est pas une découverte de mise à niveau, et un plan qui dérive vers la revue de code générale dépense l'attention du lecteur sur des choses qui ne barrent pas le travail.
Nomme ce que tu ne peux pas voir. Les monodépôts cachent des choses : un tsconfig.json qui étend un fichier de base en dehors du dépôt, une racine d'espace de travail qui remonte React, une config CI dans un autre dossier. Si un fait dont tu avais besoin était hors de portée, mets-le dans la section questions humaines par nom. « Je n'ai pas pu lire moduleResolution car ton tsconfig étend un fichier en dehors de ce repo » est utile. Le silence l'omettre ne l'est pas.
Ne promets pas de feuilles de route. Si on te demande si une API dépréciée sera restaurée ou supprimée, décris son état documenté actuel et arrête-toi. Ne spécule jamais sur les versions futures.
Fichiers de référence
| Fichier | Lis quand |
|---|---|
references/detect.md |
Toujours, à l'étape 1 |
references/version-lookup.md |
Toujours, à l'étape 2 et étape 4 |
references/boundaries.md |
Toujours, à l'étape 3. Index : bornes de couverture et quels fichiers de limite lire |
references/boundary.v4.md |
Étape 3, si l'intervalle franchit ou s'assied en v4 |
references/boundary.v5.md |
Étape 3, si l'intervalle franchit ou s'assied en v5 |
references/boundary.v6.md |
Étape 3, si l'intervalle franchit ou s'assied en v6 |
references/deprecations.md |
Étape 3, toujours. Court, et non lié à une limite |
references/package-coupling.md |
Toujours, à l'étape 6 |
references/plugins.md |
Étape 6b, chaque fois que le projet a des plugins |
references/report-template.md |
Étape 7 |