Nieco bardziej wyraźne, w swoim \config\deploy.rb, dodaj poza jakimkolwiek zadaniem lub przestrzenią nazw:
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}")endend
Capistrano 3 Generic Version (uruchom dowolne zadanie rake)
Tworzenie ogólnej wersji odpowiedzi Mirka Rusina:
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]endendendend
Przykładowe użycie: cap staging "invoke[db:migrate]"
Zauważ, że deploy:set_rails_envwymagania pochodzą z klejnotu capistrano-rails
To urządzenie obsługuje tylko jeden argument, jeśli zastąpić rake args[:command] z execute :rake, "#{args.command}[#{args.extras.join(",")}]" was może wykonywać zadania z wieloma argumentami tak: cap production invoke["task","arg1","arg2"]
@ Robin Clowers Możesz przekazać wiele argumentów, np cap staging invoke['task[arg1\,arg2]']. Wolę to podejście od tego, o którym wspominasz, ponieważ odzwierciedla faktyczne wywołanie rake. Dzięki takiemu podejściu można również łańcuch wielu zadań, które często przydatne: cap staging invoke['task1 task2[arg1] task3[arg2\,arg3]']. Działa dla rake'a 10.2.0 lub nowszego
Drobne ulepszenie: jeśli zamienisz średnik na &&, druga instrukcja (uruchamiająca zadanie rake) nie zostanie uruchomiona, jeśli pierwsza instrukcja (zmiana katalogu) zawiedzie.
@Mark Redding: Czy mógłbyś przypisać jednemu z serwerów jego własną rolę do zadań rake'u i ograniczyć swoje zadanie capistrano do uruchamiania tylko na serwerach z tą rolą?
Zrobiłem coś, gdzie utworzyłem zadanie w pliku deploy.rb. To zadanie ma: roles =>: db tak, że będzie wykonywane tylko na tym samym serwerze, który zdefiniowałem jako mój podstawowy dla db: migrate.
Istnieje powszechny sposób, który „po prostu działa” z require 'bundler/capistrano'innymi rozszerzeniami, które modyfikują rake. Będzie to również działać w środowiskach przedprodukcyjnych, jeśli korzystasz z wielu etapów. Istota? Jeśli możesz, użyj zmiennych konfiguracyjnych.
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
Prawdopodobnie warto dodać, że jeśli twoje zadanie ma przestrzeń nazw (tj. Zdefiniowane nie w przestrzeni nazw najwyższego poziomu), być może będziesz musiał użyć top.runzamiast po prosturun
Dzięki @dolzenko. Właśnie znalazłem dokumentację dla topmetody . W przypadku, gdy zdefiniowaliśmy runw tej samej przestrzeni nazw, top.runjest to wymagane, w przeciwnym razie nadal powinno znaleźć najwyższy poziom, runnawet jeśli zadanie ma przestrzeń nazw. Czy coś przegapiłem? Co się stało w twoim przypadku?
Najwyraźniej nie miałem zdefiniowanej żadnej metody uruchamiania w tej samej przestrzeni nazw, więc nie jestem pewien, dlaczego tego potrzebowałem. W każdym razie Capistrano 2.0 to już historia, a następna wersja jest oparta na
Pozwala to na uruchomienie zadania rake podobnie jak przy użyciu metody run (polecenie).
UWAGA: jest podobny do tego, co zaproponował Duke , ale ja:
użyj funkcji latest_release zamiast current_release - z mojego doświadczenia wynika, że jest to więcej, czego oczekujesz, wykonując polecenie rake;
postępuj zgodnie z konwencją nazewnictwa Rake i Capistrano (zamiast: cmd -> task and rake -> run_rake)
nie ustawiaj RAILS_ENV = # {rails_env}, ponieważ właściwym miejscem do ustawienia jest zmienna default_run_options. Np. Default_run_options [: env] = {'RAILS_ENV' => 'produkcja'} # -> SUCHA!
Istnieje interesująca peleryna z klejnotami, która sprawia, że zadania rake są dostępne jako zadania Capistrano, więc możesz je uruchamiać zdalnie. capejest dobrze udokumentowany, ale oto krótki przegląd tego, jak go skonfigurować.
Po zainstalowaniu klejnotu po prostu dodaj go do swojego config/deploy.rbpliku.
# config/deploy.rb
require 'cape'Capedo# Create Capistrano recipes for all Rake tasks.
mirror_rake_tasks
end
Teraz możesz uruchamiać wszystkie swoje rakezadania lokalnie lub zdalnie cap.
Jako dodatkowy bonus capepozwala ustawić, w jaki sposób chcesz uruchamiać zadanie prowizji lokalnie i zdalnie (nie więcej bundle exec rake), po prostu dodaj to do swojego config/deploy.rbpliku:
# Configure Cape to execute Rake via Bundler, both locally and remotely.Cape.local_rake_executable ='/usr/bin/env bundle exec rake'Cape.remote_rake_executable ='/usr/bin/env bundle exec rake'
to jest sprzeczne, ponieważ capistrano definiuje swoją własną zmienną rake (używaną do określenia, której prowizji użyć), a tym samym łamie wbudowane wpływy, na przykład tę, która prekompiluje aktywa
task :invoke,:command do|task, args|
on roles(:app)do
within current_path do
with rails_env: fetch(:rails_env)do
execute :rake, args[:command]endendendend
Następnie po prostu biegnij cap production "invoke[task_name]"
{deploy_to} / current nie będzie tutaj działać. Dowiązanie symboliczne nie uległo zmianie. Jeśli zaktualizujesz zadanie rake, uruchomi to stary kod. Zamiast tego rozważ użycie {release_path}.
Jeśli chcesz mieć możliwość przekazywania wielu argumentów, spróbuj tego (w oparciu o odpowiedź marinosbern):
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
execute :rake,"#{args.command}[#{args.extras.join(",")}]"endendendend
Następnie możesz uruchomić takie zadanie: cap production invoke["task","arg1","arg2"]
Więc pracowałem nad tym. wydaje się działać dobrze. Jednak potrzebujesz formatera, aby naprawdę wykorzystać kod.
Jeśli nie chcesz używać programu formatującego, po prostu ustaw poziom dziennika na tryb debugowania. Te semestry do h
SSHKit.config.output_verbosity =Logger::DEBUG
Cap Stuff
namespace :invoke do
desc 'Run a bash task on a remote server. cap environment invoke:bash[\'ls -la\'] '
task :bash,:execute do|_task, args|
on roles(:app),in::sequence doSSHKit.config.format =:supersimple
execute args[:execute]endend
desc 'Run a rake task on a remote server. cap environment invoke:rake[\'db:migrate\'] '
task :rake,:task do|_task, args|
on primary :app do
within current_path do
with rails_env: fetch(:rails_env)doSSHKit.config.format =:supersimple
rake args[:task]endendendendend
To jest formater, który zbudowałem do pracy z powyższym kodem. Opiera się na: textimple wbudowanym w sshkit, ale nie jest to zły sposób wywoływania zadań niestandardowych. Och, to wiele nie działa z najnowszą wersją klejnotu sshkit. Wiem, że działa z 1.7.1. Mówię to, ponieważ gałąź główna zmieniła dostępne metody SSHKit :: Command.
namespace :deploy do# ....# @example# bundle exec cap uat deploy:invoke task=users:update_defaults
desc 'Invoke rake task on the server'
task :invoke do
fail 'no task provided'unless ENV['task']
on roles(:app)do
within release_path do
with rails_env: fetch(:rails_env)do
execute :rake, ENV['task']endendendendend
do uruchomienia zadania użyj
bundle exec cap uat deploy:invoke task=users:update_defaults
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.
#{rake}
zmiennej Capistrano ? Wydaje się, że nie zawsze jest to najlepsza opcja.