108 votes

Comment exécuter une tâche rake à partir de Capistrano ?

J'ai déjà un deploy.rb qui peut déployer mon application sur mon serveur de production.

Mon application contient une tâche rake personnalisée (un fichier .rake dans le répertoire lib/tasks).

Je voudrais créer une tâche cap qui va exécuter à distance cette tâche rake.

2 votes

Quelqu'un peut-il expliquer les avantages et les inconvénients de l'utilisation de l'interface de Capistrano ? #{rake} variable ? Il semble que ce ne soit pas toujours la meilleure option.

60voto

Coward Points 449

Un peu plus explicite, dans votre \config\deploy.rb ajouter en dehors de toute tâche ou espace de nom :

namespace :rake do  
  desc "Run a task on a remote server."  
  # run like: cap staging rake:invoke task=a_certain_task  
  task :invoke do  
    run("cd #{deploy_to}/current; /usr/bin/env rake #{ENV['task']} RAILS_ENV=#{rails_env}")  
  end  
end

Ensuite, de /rails_root/ tu peux courir :

cap staging rake:invoke task=rebuild_table_abc

1 votes

Il est préférable d'utiliser /usr/bin/env rake pour que les configurations rvm prennent en compte le bon rake.

9 votes

Avec "bundle exec" si disponible

48voto

marinosbern Points 1533

Capistrano 3 Generic Version (exécuter n'importe quelle tâche de rake)

Construire une version générique de la réponse de Mirek Rusin :

desc 'Invoke a rake command on the remote server'
task :invoke, [:command] => 'deploy:set_rails_env' do |task, args|
  on primary(:app) do
    within current_path do
      with :rails_env => fetch(:rails_env) do
        rake args[:command]
      end
    end
  end
end

Exemple d'utilisation : cap staging "invoke[db:migrate]"

Notez que deploy:set_rails_env

1 votes

Ceci ne supporte qu'un seul argument, si vous remplacez rake args[:command] avec execute :rake, "#{args.command}[#{args.extras.join(",")}]" vous pouvez exécuter une tâche avec plusieurs arguments comme suit : cap production invoke["task","arg1","arg2"]

1 votes

@ Robin Clowers Vous pouvez passer plusieurs arguments, par exemple cap staging invoke['task[arg1\,arg2]'] . Je préfère cette approche à celle que vous mentionnez car elle reflète l'invocation réelle de rake. Avec cette approche, vous pouvez également enchaîner plusieurs tâches, ce qui est souvent utile : cap staging invoke['task1 task2[arg1] task3[arg2\,arg3]'] . Fonctionne avec rake 10.2.0 ou plus récent.

0 votes

C'est très bien, mais je tiens à préciser que vous devez inclure :app dans les rôles de votre serveur.

44voto

Mirek Rusin Points 5880

...quelques années plus tard...

Jetez un coup d'œil au plugin rails de Capistrano, que vous pouvez consulter à l'adresse suivante https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/migrations.rake#L5-L14 ça peut ressembler à quelque chose comme :

desc 'Runs rake db:migrate if migrations are set'
task :migrate => [:set_rails_env] do
  on primary fetch(:migration_role) do
    within release_path do
      with rails_env: fetch(:rails_env) do
        execute :rake, "db:migrate"
      end
    end
  end
end

3 votes

Ceci est pour capistrano v3, seulement.

0 votes

Ça a beaucoup aidé. Merci ! @Mirek Rusin

0 votes

Les autres réponses, qui utilisent run fonctionnera sur capistrano jusqu'à la version 2. À partir de la version 3, c'est la voie à suivre.

41voto

Richard Poirier Points 1948
run("cd #{deploy_to}/current && /usr/bin/env rake `<task_name>` RAILS_ENV=production")

Je l'ai trouvé avec Google -- http://ananelson.com/said/on/2007/12/30/remote-rake-tasks-with-capistrano/

El RAILS_ENV=production était un piège - je n'y ai pas pensé au début et je ne pouvais pas comprendre pourquoi la tâche ne faisait rien.

2 votes

Une amélioration mineure : si vous remplacez le point-virgule par &&, la deuxième instruction (exécuter la tâche rake) ne s'exécutera pas si la première instruction (changer le répertoire) échoue.

2 votes

Cela ne fonctionnera pas si vous déployez sur plusieurs serveurs. Cela va exécuter la tâche rake plusieurs fois.

4 votes

On doit vraiment respecter le réglage du râteau de capistrano "cd #{deploy_to}/current && #{rake} <task_name> RAILS_ENV=production"

20voto

CaptainPete Points 2991

Utilisation d'invocations rake de type Capistrano

Il y a un moyen commun qui va "juste marcher" avec require 'bundler/capistrano' et d'autres extensions qui modifient rake. Cela fonctionnera également avec les environnements de pré-production si vous utilisez multistage. L'essentiel ? Utilisez les variables de configuration si vous le pouvez.

desc "Run the super-awesome rake task"
task :super_awesome do
  rake = fetch(:rake, 'rake')
  rails_env = fetch(:rails_env, 'production')

  run "cd '#{current_path}' && #{rake} super_awesome RAILS_ENV=#{rails_env}"
end

2 votes

C'est la solution la plus agréable, elle utilise les valeurs de capistrano lorsqu'elles sont disponibles.

2 votes

Il est probablement utile d'ajouter que si votre tâche est namespaced (c'est-à-dire qu'elle n'est pas définie dans l'espace de noms de premier niveau), vous pourriez avoir à utiliser top.run au lieu de simplement run

0 votes

Merci @dolzenko. Je viens de trouver le pour le top méthode . Dans le cas où nous avons défini run dans le même espace de noms, top.run est requis, sinon il devrait toujours trouver le fichier de premier niveau run même lorsque la tâche est nommée. Ai-je manqué quelque chose ? Que s'est-il passé dans votre cas ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X