Contexte
Je travaille dans une équipe qui cherche à mettre en œuvre des déploiements sans temps d'arrêt. Nous prévoyons d'utiliser une stratégie de déploiement bleu / vert pour y parvenir. En réalisant cette recherche, je réalise notamment à quel point il est difficile de modifier les bases de données. Une opération simple, comme renommer une colonne, peut prendre 3 cycles complets avant d'être complétée!
Il me semble que le déploiement complet d'un changement prend plusieurs cycles de publication, ce qui crée un potentiel d'erreur humaine. Dans l'article lié, il est montré que les modifications de code sont nécessaires pour 2 versions et qu'une migration de base de données est nécessaire pour 3 versions.
Ce que je cherche
Actuellement, si nous voulons nous souvenir de faire quelque chose, nous pouvons créer un ticket dans notre système de gestion des problèmes, ce qui crée un fouillis et peut également être déplacé vers un sprint ultérieur ou le retard accumulé par la direction; ou nous pouvons créer un commentaire TODO, qui sera probablement complètement oublié.
Ce que je recherche, c’est la manière dont un commentaire TODO peut être assorti d’un délai, et notre système d’intégration continue (actuellement indécis, que nous utiliserons) rejetterait la construction si ce délai était expiré.
Par exemple, si nous renommons une colonne, nous pourrions créer la migration initiale correspondante, puis deux commentaires TODO pour garantir la création des deux migrations restantes:
// TODO by v55: Create migration to move constraints to new column, remove references to old column in app
// TODO by v56: Create migration to drop old column
Cela semble assez simple à mettre en œuvre, mais je me demande si quelque chose comme cela existe déjà, car je ne veux pas réinventer la roue.
Pensées supplémentaires
Je pense que je pourrais souffrir du problème XY ici, étant donné que les déploiements progressifs et les déploiements bleu / vert sont considérés comme une pratique exemplaire. Il semble donc étrange que je ne trouve pas de solution pour rendre les mises à jour de base de données moins pénibles. Si vous pensez que je cherche à me tromper complètement, faites-le-moi savoir dans un commentaire! Cela dit, l'exemple de base de données que j'ai donné n'est qu'un exemple, et je pense que les commentaires de TODO avec les dates d'échéance seraient également utiles dans d'autres situations. Par conséquent, même si j'aborde cette situation en particulier de manière erronée, j'aimerais vraiment répondre à mes questions. question réelle aussi. Merci!
EDIT: Je viens de penser à une autre situation où cela pourrait être utile. Si vous utilisez Feature Toggles pour activer des parties de votre application lorsqu'elles sont prêtes, vous devez faire attention à les nettoyer, sinon vous risquez de vous retrouver avec Basculer la dette . Les commentaires avec des délais pourraient être un bon moyen de s'en souvenir.
la source
TODO <Bug#>:
pour suivre les solutions de contournement des problèmes liés aux autres composants. Lorsqu'un bogue est effacé sur l'un de ces composants, vous pouvez facilement trouver et résoudre les solutions de contournement pertinentes. Il ne remplace pas un outil de suivi des problèmes, il facilite la maintenance.Réponses:
Cette question est vraiment deux questions en une.
Todo commentaires
De toutes les façons de suivre les actions, c'est la pire. Les commentaires de TODO sont bons pendant le travail actif ou comme moyen de suggestion au responsable, "voici quelque chose qui pourrait peut-être être amélioré dans le futur". Mais si vous vous fiez aux commentaires de TODO pour accomplir votre travail, vous êtes voué à l'échec.
Que faire à ce sujet
Les commentaires de TODO sont essentiellement des dettes techniques, ils doivent donc être traités comme toute autre dette technique. Vous pouvez soit vous en occuper immédiatement, si vous en avez le temps, soit les mettre dans l'arriéré afin qu'ils puissent être suivis et hiérarchisés.
De manière générale, et ceci est totalement une opinion et ouverte au débat, les commentaires de TODO pourraient être considérés comme une odeur de code. Si un commentaire TODO parvient jusqu'à être enregistré dans le contrôle de version, vous devez vous demander: allez-vous le suivre maintenant? Si non, ça va. Soyez juste honnête avec vous-même et mettez-le dans l'arriéré.
La façon dont vous gérez cet arriéré dépend des processus opérationnels, de la politique de l'entreprise et peut-être de l'autonomie personnelle. Mais vous avez toujours besoin d'un arriéré suivi et hiérarchisé pour vous en assurer.
Changements de base de données
Oui, les modifications de base de données sont délicates avec une politique de zéro temps d'arrêt. Quelques astuces pour aider à le rendre moins douloureux:
Processus post-déploiement
Créez un processus post-déploiement qui s'exécute dans la même version. Cependant, vous voulez que cela fonctionne. Sur le dernier système sur lequel j'ai travaillé, j'ai conçu un déploiement en 4 phases:
L'idée était que, dans la mesure du possible, nous intégrerions autant que possible les modifications apportées à la base de données.
Postapp était réservé aux cas inhabituels dans lesquels nous devions apporter des modifications de schéma incompatibles. Dans ces cas, preapp apporterait une modification suffisante pour rendre le nouveau code d'application compatible (en créant éventuellement une vue temporaire), et postapp supprimerait tout artefact temporaire de ce type.
La phase de la fenêtre de maintenance était réservée aux modifications qui nécessitaient réellement des temps d'arrêt ou pour lesquelles le risque ou le coût d'un déploiement réel n'en valait pas la peine. Par exemple, les scripts qui modifient des quantités énormes de données peuvent avoir besoin de verrouiller une table entière.
Déployer fréquemment
Si vous déployez suffisamment de nouvelles versions, vous pouvez atteindre un point où effectuer une modification sur 2 ou 3 versions est simple. Les cycles de publication longs amplifient le coût des modifications apportées à la base de données.
la source
N'utilisez pas de TODO. Vous avez déjà une liste TODO dans votre projet. C'est ce qu'on appelle le suivi des problèmes.
Je pense que le vrai problème est dans cette phrase:
Si votre outil de suivi des problèmes génère beaucoup de fouillis, trouvez des moyens de remédier à cela. Peut-être un type / tag spécial qui implique moins de cérémonie. Peut-être des sous-problèmes. Peut-être moins de cérémonie tout à fait. Nous ne pouvons pas vraiment dire. Mais si votre système de suivi des problèmes crée tellement de travail, que les gens préfèrent formuler une question complexe sur un forum public que pour simplement ajouter ce problème, quelque chose ne va vraiment pas.
Si votre gestion retarde indûment la dernière partie d'une tâche, vous avez deux options:
demandez à votre direction pourquoi c’est une mauvaise idée.
gérez-le comme une tâche unique. Cela pourrait être la solution de référence. Dans un monde parfait, vous devriez être capable de faire les trois changements nécessaires à chaque étape. Appliquez-en un à la branche principale, laissez-la se construire et se déployer. Pendant ce temps, appliquez la seconde à la branche principale, laissez-la se construire et se déployer, etc., de manière à ce que tout se passe dans le même sprint. Sinon, ce n'est pas fait. Peut-être même que quelque chose d'automatique a du sens lorsque vous faites logiquement un déploiement, mais il est en fait divisé en 3.
la source
// TODO(#12345): Frobnicate the sprocket before passing it along
, à condition que le bogue n ° 12345 soit un "vrai" numéro de problème et que le problème soit attribué à quelqu'un. Cela rend la source plus facile à lire en clarifiant: "Non, l'étape frobnicate ne se cache pas dans l'une des méthodes d'assistance, elle est simplement complète et non implémentée. Consultez le bogue n ° 12345 pour plus de contexte." Idéalement, vous feriez une linter journalière sur la base de code à la recherche de numéros d’émission fermés ou invalides, bien sûr.Ce que vous demandez est faisable si vous êtes prêt à faire le travail et à le suivre.
grep pour
//TODO by v55
quand il est temps de déployer v55. Deploy build exécute un script qui le fait en tant que test d'intégration.Vous pouvez associer 55 à votre suivi de version ou tout simplement demander une confirmation.
Cela devient intéressant si vous voulez vérifier // TODO by v54 en effectuant 55. Plutôt que de rechercher dans la base de code 55 fois, il vous suffit de rechercher // TODO by. Puis filtrez ce résultat de 1 à 55. Maintenant, 56 ne déclenchera pas un échec.
Vous pourriez penser "Oh, nous n'en aurons pas besoin. Nous réglerons cela à chaque fois que nous aurons le chèque". Non, vous ne le ferez pas.
la source
Nous avons eu un problème très similaire dans notre équipe. Pour résoudre ce problème, nous avons écrit une vérification d'analyse statique qui gère ces TODO en vérifiant le problème JIRA ou le problème Git auquel ils font référence. Notre génération échoue lorsque le problème spécifié dépasse la colonne "En développement".
Par conséquent, nous pouvons facilement avoir des TODO sans nous soucier de les oublier.
J'ai créé une implémentation open-source de celui-ci, en Java. Oui, un avis de non-responsabilité est que j'ai écrit ceci, mais comme je l'ai dit, il s'agit d'une source complètement ouverte et d'une licence.
L'outil s'appelle Westie et un exemple de l' outil de vérification des problèmes de Jira figure dans le fichier README.md. Voir aussi le GitIssueAnalyser.
Pour éviter toute promotion personnelle, si vous avez d'autres questions, envoyez-moi un message. Si vous décidez de l'utiliser et que vous avez des suggestions, veuillez soulever les problèmes éventuels sur github.
la source
Ne pas faire. Fais le maintenant.
TLDR: écrivez (et testez) vos scripts de base de données maintenant, pas plus tard; il suffit de les coder pour que leur exécution dépende de la version de la base de données.
Exemple
Pour un exemple, imaginons que vous souhaitez modifier un nom de colonne de
SSN
àTaxID
, une exigence commune lors du passage international.Pour ce faire, vous aurez peut-être temporairement
TaxID
uneSSN
colonne et une . Et tout en prenant en charge les deux versions, vous aurez un déclencheur pour mettre à jour l’une de l’autre. Mais vous ne voulez pas garder ce déclencheur indéfiniment. Par conséquent, plus tard, lorsque la compatibilité en amont n'est plus nécessaire, vous souhaitez que ce déclencheur soit supprimé (et laSSN
colonne supprimée). Nous allons coder tout cela à l’avance sans qu’il soit nécessaire de créer des tâches.Dans notre exemple, nous allons déployer la version 102 (qui contient la nouvelle colonne) tout en maintenant la compatibilité avec la version 101 (ce qui n’est pas le cas).
Voici les étapes.
1. Configurer la table de gestion des versions
Ajouter une seule table appelée
Configuration
avec deux colonnes,Name
etValue
.Ajoutez une ligne avec
Name
"TargetVersion" et définissez-leValue
sur la version de la nouvelle version à déployer.Ajoutez une ligne avec
Name
"CompatibleWith" et définissez leValue
sur le numéro de version minimum avec lequel le déploiement doit être compatible.Inspectez et mettez à jour ces lignes avant chaque déploiement.
2. Modifier les scripts de déploiement
Ajoutez un script qui crée une nouvelle colonne
TaxID
, côte à côte avec elleSSN
, et la remplit à partir de laSSN
colonne. Placez ce code dans uneIf
instruction qui vérifie TargetVersion; Si la version cible est trop basse (c’est-à-dire qu’elleTaxID
n’est pas encore utilisée), ignorez.Ajoutez un script qui crée un déclencheur à remplir
TaxID
lors de l'insertion ou de la mise à jour,SSN
et inversement. Placez ce code dans uneIf
instruction qui vérifie la version cible et la version compatible. ignore si TargetVersion est trop bas (ceTaxID
n'est pas nécessaire) ou si la version CompatibleWith est trop élevée (leSSN
champ n'est pas nécessaire).Ajoutez un script pour supprimer la
SSN
colonne. Placez-le dans uneIf
instruction qui supprime la colonne uniquement si la version CompatibleWith est suffisamment élevée (SSN
n'est plus nécessaire).3. Test
Assurez-vous de tester votre déploiement avec toute combinaison de numéros de version Bleu / Vert que vous souhaitez pouvoir prendre en charge en production. Vous pouvez tester dès que le code est prêt, en manipulant la
Configuration
table dans votre environnement d'assurance qualité.4. Dans votre livre de déploiement
Ajoutez une étape permettant à un ingénieur de mettre à jour les lignes CompatibleWith version et TargetVersion. Si vous effectuez un déploiement sur Blue, définissez TargetVersion sur le numéro de version de Blue et la version CompatibleWith sur le numéro de version de Green. inversez-les si vous déployez Green.
Les pièges
Les scripts de déploiement peuvent référencer et utiliser les numéros de version contenus dans cette table de base de données. PAS le code d'exécution.
Si vous commencez à écrire votre code d'exécution pour inspecter les numéros de version, vous introduisez un nouveau niveau de complexité dans votre application qui pourrait potentiellement devenir un énorme problème de maintenabilité. Chaque chemin d'exécution doit être testé. Si vous gardez ces conditions à l'avenir, QA devra créer une matrice de douleur pour les valider à chaque sortie. Mon conseil est de conserver les conditions telles que celles-ci dans les scripts de déploiement uniquement.
Le résultat de tout cela
En fin de compte, vous devriez être capable d'écrire tout le code à l'avance (et de le tester aussi) sans craindre qu'il ne soit exécuté trop tôt. En outre, le code effacera le déclencheur de compatibilité ascendante le moment venu sans que vous ayez à vous en préoccuper davantage.
De cette façon, vous pouvez écrire et tester tout le code dès le départ, sans avoir à vous soucier de ces commentaires désordonnés de la tâche.
la source
Votre idée de TODO suscite beaucoup de critiques, mais je ne vois personnellement aucun problème avec cette idée. En fin de compte, le meilleur moyen (et le plus simple) de s'assurer que la migration passe en production consiste à échouer un test unitaire s'il ne réussit pas. Cela vous prendra littéralement moins d'une minute pour remplacer une fonction de migration vide qui lève une exception si la version est au moins égale à 55 (ou quelles que soient les conditions requises).
Ensuite, si vous essayez de le libérer, vous obtiendrez un test qui échouera et quelqu'un devra transformer cette exception en code de migration réel.
la source
Personne ne semble se focaliser sur la racine de sa plainte, à savoir que les changements de base de données peuvent prendre trop de cycles de publication. Il souhaite poursuivre son calendrier de déploiement bleu / vert et la solution devrait déjà être là, mais à moins que quelque chose ne me manque, sa description semble indiquer qu'il n'existe qu'une seule base de données partagée par les deux systèmes. Pas un vrai système bleu / vert si c'est le cas. Comme il semble que la base de données soit le long pôle de la tente, il convient de la dupliquer également, de sorte que peu importe la durée ou le nombre de cycles de publication nécessaires à la mise en œuvre des modifications de la base de données sur le système hors ligne, elles ne seront pas actives tant qu'elles ne seront pas terminées et entièrement testé. Dans l'intervalle, les scripts système hors ligne peuvent maintenir la base de données hors ligne entièrement mise à jour quotidiennement.
la source