Rails 3 et Heroku: automatiquement “rake db: migrer” sur push?

Je suis un peu contrarié par mon processus push / deploy de heroku, qui a été une joie à découvrir et à utiliser.

Si j’ajoute une nouvelle migration à mon application, la seule façon de le faire sur le serveur heroku est de faire un push sur la télécommande heroku. Cela le télécharge et redémarre l’application. Mais il ne lance pas la migration, donc je dois faire heroku rake db:migrate --app myapp , puis heroku restart --app myapp . En attendant, l’application est cassée car elle n’a pas exécuté les migrations et le code fait référence aux champs / tables, etc. dans la migration.

Il doit y avoir un moyen de modifier le processus de déploiement pour exécuter la rake db:migrate automatiquement dans le cadre du processus de déploiement, mais je ne peux pas le résoudre.

Est-ce que c’est quelque chose que je mets dans un hoku cpanel? Est-ce une option que je passe à heroku depuis la ligne de commande? Est-ce un crochet? Quelqu’un peut-il me mettre au clair? merci, max

Voici une tâche de rake qui englobe tout en une seule ligne (et prend également en charge la restauration):

https://gist.github.com/362873

Vous pourriez quand même vous déployer au-dessus de la démo de votre patron, mais au moins vous ne perdez pas de temps à taper entre la commande git push et la rake db:migrate .

Qu’en est-il de cette solution de chaînage de commandes simple:

 git push heroku master && heroku run rake db:migrate 

Il lancera automatiquement la migration dès que le premier sera terminé avec succès. Il est généralement de 1 à 2 secondes de retard ou moins.

Heroku a maintenant la possibilité de gérer cela dans le cadre de sa fonctionnalité de “phase de publication”.

Vous pouvez append un processus appelé release à votre Procfile et qui sera exécuté lors de chaque déploiement.

Rails> = 5 Exemple

release: bundle exec rails db:migrate

Rails <5 exemple

release: bundle exec rake db:migrate

J’ai créé un buildpack personnalisé qui permet à Heroku d’exécuter rake db:migrate automatiquement pour vous lors du déploiement. C’est juste un fork du pack de compilation Ruby par défaut de Heroku, mais avec la tâche rake db:migrate ajoutée.

Pour l’utiliser avec votre application, procédez comme suit:

 heroku config:set BUILDPACK_URL=https://github.com/dtao/rake-db-migrate-buildpack 

Notez également que pour que cela fonctionne, vous devez activer la fonctionnalité Heroku Labs compilée par l’ utilisateur-env- comp. Voici comment vous faites cela:

 heroku labs:enable user-env-comstack 

Et voici ma preuve que cela fonctionne:

rake db: migrer sur un déploiement Heroku

Vous pourriez peut-être essayer de séparer vos commits de schéma (migrations, etc.) validés par des commits de code (modèles, validations, etc.).

(Notez que ce qui suit suppose que vos modifications de migration NE sont PAS destructives, comme vous l’avez indiqué dans la plupart des cas d’utilisation.)

Votre processus de déploiement pourrait alors être:

  1. Push schema change à Heroku
  2. émigrer
  3. Poussez le code d’application vers Heroku

Ceci est bien entendu loin de la forme optimale, mais est un moyen efficace d’éviter les temps d’arrêt dans la situation que vous avez décrite: au moment où l’application reçoit le code pour les champs dynamics, la firebase database aura déjà migré.

(Bien sûr, la solution la plus simple serait de simplement pousser et migrer pendant que votre patron est en train de déjeuner ;-D)

Sinon, même si les modifications du schéma ont été effectuées automatiquement, vous courez toujours le risque qu’une requête soit transmise juste avant l’exécution des migrations.

Juste pour les gens comme Google, je veux donner une solution simple ici.

J’utilise Rails 4 et je devais append une simple tâche Rake au déploiement sur heroku. Comme j’utilise le bouton ‘deploy to heroku’ dans github, il n’y a aucune chance d’exécuter “heroku run …” immédiatement après le déploiement.

Ce que j’ai fait: J’ai étendu la tâche Rake standard «assets: clean» qui s’exécute automatiquement lors d’un déploiement sur heroku. La tâche s’exécute toujours normalement, mais j’ai attaché mes propres fichiers à la fin. Ceci est fait avec la méthode ‘améliorer’ . Dans l’exemple ci-dessous, j’ajoute une firebase database: migrer car c’est probablement ce que la plupart des gens veulent:

 # in lib/tasks/assets_clean_enhance.rake Rake::Task['assets:clean'].enhance do Rake::Task['db:migrate'].invoke end 

J’avoue que ce n’est pas une solution parfaite. Mais le Heroku Ruby Buildpack ne supporte toujours aucun autre moyen. Et écrire mon propre buildback semblait un peu exagéré pour une chose si simple.

J’utilise une tâche de rake pour mettre l’application en mode maintenance, la pousser, la migrer et la désactiver.

J’ai écrit SmartMigrate buildpack qui est un simple buildpack Heroku pour avertir des migrations en attente après une compilation Ruby à chaque fois que de nouvelles migrations sont détectées. Ce buildpack est destiné à faire partie d’un Multipack doté d’un buildpack Ruby précédent.

Compte tenu des autres solutions, ce buildpack présente 3 avantages par rapport à ceux-ci:

  1. Pas besoin de mode maintenance
  2. Pas besoin de fourches de fabrication de rbuy désuètes qui insèrent la migration à la fin
  3. Pas besoin d’exécuter des migrations TOUS LES TEMPS, un avertissement ne s’affiche que si de nouvelles migrations sont détectées depuis le dernier déploiement

Je pense que l’approche de David Sulc est la seule qui garantit que vous évitiez les demandes pendant que l’application est en panne.

C’est un peu douloureux, mais peut être nécessaire dans certaines circonstances.

Comme il l’a déclaré, cela nécessite que les migrations de firebase database soient non destructives.

Cependant, il peut être difficile de pousser vos migrations et vos modifications de schéma avant le rest du code, car l’approche évidente («git push heroku {revnum}») repose sur la vérification des migrations avant le rest du code.

Si vous ne l’avez pas fait, il est toujours possible de le faire en utilisant une twig temporaire:

  • Créez une twig basée sur la révision git que vous avez récemment envoyée à heroku:

     git branch   
  • Découvrez cette twig:

     git checkout  
  • Si la migration de votre firebase database ne contient que des migrations, et qu’aucun changement de code, sélectionnez les modifications contenant les modifications de la firebase database:

     git cherry-pick  ... 
  • Si vous avez activé les modifications de la firebase database dans les révisions contenant également des modifications de code, vous pouvez utiliser «git cherry-pick -n» qui ne sera pas automatiquement validé. Utilisez ‘git reset HEAD’ pour supprimer les fichiers qui ne sont pas des modifications de firebase database de l’ensemble des éléments à valider. Une fois que vous avez juste les changements de firebase database, validez-les dans votre twig temporaire.

     git cherry-pick -n  ... git reset HEAD  git status ... check that everything looks ok ... git commit 
  • Poussez cette twig temporaire vers heroku (idéalement vers une application de transfert pour vérifier que vous avez bien compris, car éviter les temps d’arrêt est le but de sauter à travers ces cerceaux)

     git push heroku :master 
  • Exécuter les migrations

     heroku run rake db:migrate 
  • À ce stade, vous pourriez penser que vous pourriez simplement pousser «master» sur heroku pour que le code change. Cependant, vous ne pouvez pas, car ce n’est pas une fusion rapide. La façon de procéder est de fusionner le rest de «master» dans votre twig temporaire, puis de le fusionner en master, ce qui recombine les historiques de validation des deux twigs:

     git checkout  git merge master git diff  master ... shouldn't show any differences, but just check to be careful ... git checkout master git merge  
  • Maintenant, vous pouvez pousser master sur heroku comme d’habitude, ce qui fera passer le rest de votre code.

Dans l’avant-dernière étape, je ne suis pas sûr à 100% que la fusion de master avec {branchname} est nécessaire. Le faire de cette façon devrait vous permettre de faire une fusion rapide, ce qui vous permet de restr heureux lorsque vous passez à heroku, mais il est possible d’obtenir le même résultat en fusionnant {branchname} avec master sans cette étape.

Bien sûr, si vous n’utilisez pas «master», remplacez le nom de twig approprié dans les endroits appropriés ci-dessus.

J’ai utilisé le gem heroku_san comme outil de déploiement pendant un certain temps. C’est un petit outil bien ciblé pour la migration push +. Il ajoute d’autres commandes rake qui facilitent l’access à d’autres fonctions (comme la console). En plus de ne pas avoir à mémoriser les migrations de firebase database, ma fonction préférée est son fichier de configuration Heroku – je peux donc nommer tous mes serveurs (production, mise en scène, playground4, shirley) et les garder dans ma tête.