Run `rails db:migrate` with capistrano in a gem/submodule - ruby-on-rails

I have a rails 5.2 app. I am trying to deploy it using Capistrano.
The app has a gem dependency submodule, which contains all of the models and migrations needed for this project. This submodule depends on other gems in it's .gemspec.
Therefore, I need to run rails db:migrate in the submodule root, instead of the parent project root.
I have added the following to deploy.rb:
desc 'Runs rake db:migrate if migrations are set'
task :migrate => [:set_rails_env] do
on primary fetch(:migration_role) do
within "#{release_path}/PATH/TO/SUBMODULE" do
with rails_env: fetch(:rails_env) do
execute :rake, "db:migrate"
end
end
end
end
before :starting, :migrate
Gemfile:
gem 'dependency', path: 'PATH/TO/SUBMODULE'
gem 'capistrano-git-with-submodules', '~> 2.0'
group :development do
gem 'capistrano', require: false
gem 'capistrano-rvm', require: false
gem 'capistrano-rails', require: false
gem 'capistrano-bundler', require: false
gem 'capistrano3-puma', require: false
end
When I try to run this task, I get an error message saying:
DEBUG [b4c1cf18] [31mCould not find aasm-5.0.2 in any of the sources[0m
DEBUG [b4c1cf18]
DEBUG [b4c1cf18] [33mRun `bundle install` to install missing gems.[0m
DEBUG [b4c1cf18]
It seems like the gem set (containing all parent and submodule gems) used in deploying the parent project isn't in the path or is unavailable when it comes time to run this task.
I can get the parent project running without the migrations, so I know that the parent project is loading all the correct gem set at runtime. Just not during this task.
I'm not quite sure how Capistrano works under the hood, how could I make sure that these gems are available to this task when it runs?

I figured it out, I needed 3 things:
1.execute :bundle before execute :rake, :"db:migrate"
Provide a second argument to within "#{release_path}/PATH/TO/SUBMODULE" to make it within "#{release_path}/PATH/TO/SUBMODULE", release_path - couldn't find docs on this, only this PR: https://github.com/capistrano/bundler/pull/84
symlink secrets to the engine so it doesn't prevent any tasks from running:
task :symlink_secrets do
on roles(:app) do
execute "rm -rf #{release_path}/PATH/TO/SUBMODULE/spec/dummy/config/secrets.yml"
execute "ln -nfs ~/secrets.yml #{release_path}/PATH/TO/SUBMODULE/spec/dummy/config/secrets.yml"
end
end

Related

deploy database.yml with Capistrano 3 in rails app

I have a Rails 4 app that connects to a second, external database. So I added the database credentials to my database.yml file and excluded it from version control in git. I need to deploy it when I push to Heroku using Capistrano.
I found some questions raised for this task, but they don't work for me and they were answered prior to the release of Capistrano 3.
I set up capistrano by adding:
group :development, :test do
gem 'capistrano-rails', '~> 1.1.1'
end
and
running bundle install then bundle exec cap install as it says in the install instructions.
I created a new folder in my app and copied the database.yml file there: myApp/shared/config/database.yml (not sure if this was necessary)
Finally, I created the following task in deply.rb:
after "deploy:update_code","deploy:config_symlink"
namespace :deploy do
task :config_symlink do
run "cp #{shared_path}/shared/config/database.yml #{release_path}/config/database.yml"
end
end
This didn't work and threw an error when pushed to Heroku:
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/connection_specification.rb:248:in `resolve_symbol_connection': 'pg_development' database is not configured. Available: ["production"] (ActiveRecord::AdapterNotSpecified)
I tried putting this task in the production.rb file as well as adding set :linked_files, %w{config/database.yml} to the development.rb file.
Can someone help me get the database.yml file into production on Heroku?

Rails crons task only running in production

I have a task defined in crons.rake but this task only runs in production mode. how can I got this running in dev mode?
task(:generate_mindmails => :environment) do
I whould suggest you to use the whenever gem instead. It can be configured more comfortable. Like this:
every 5.hours do
runner "MyModel.my_method", :environment => :development
end
You can install it by adding gem 'whenever' to your Gemfile then run bundle install. You should read the documentation or at least the README.md of the github project.
// You can also run it in both environments:
every 5.hours do
runner "MyModel.my_method", :environment => :development
runner "MyModel.my_method", :environment => :production
end
Simply set the environment before executing the command:
$ RAILS_ENV=development rake generate_mindmails

Cron + Rake task trying to invoke sqlite3 (only Dev/Test) in Staging (rake works from shell)

In my Rails 3.2 app I have a custom rake task that I am trying to run every day at 5pm with a cron job. Right now I am running it on our site's Staging server. The cron job is setup correctly but according to the e-mail output from the cron daemon the rake is being aborted because it's trying to invoke sqlite3.
Here is my cron job:
#crontab
0 17 * * * cd /u/apps/my_app/current && /usr/local/bin/rake my_task
I have reserved sqlite3 for development and test, like so:
#Gemfile
group :development, :test do
gem 'factory_girl_rails'
gem 'letter_opener'
gem 'rspec-rails'
gem 'sqlite3'
gem 'thin'
gem 'pry-rails'
end
I also have set my rake task to load the proper environment like so:
#mytask.rake
task :my_task => :environment do
# my task
end
This is the error I'm getting in the e-mail from crond:
rake aborted!
Please install the sqlite3 adapter: `gem install activerecord-sqlite3-adapter` (sqlite3 is not part of the bundle. Add it to Gemfile.)
If I run the rake tasks directly from the shell I don't get an error. It would seem that this works because of the following line in ~/.bashrc:
alias rake='RAILS_ENV=staging rake'
This, however, doesn't seem to have any effect on the task when run from the cron job. I've tried adding export RAILS_ENV=staging to the .bashrc file as recommended here but it didn't help.
The one thing I've found that works is writing the cron job like this:
#crontab
0 17 * * * cd /u/apps/my_app/current && /usr/local/bin/rake my_task RAILS_ENV=staging
...with the env declaration directly in the cron command. This doesn't seem very elegant but it's okay for now. Is there a better way to go about this?
Υou can set the environment variables in crontab (not in Arch or RedHat though...)
try setting your crontab as follows
#crontab
RAILS_ENV=staging
0 17 * * * cd /u/apps/my_app/current && /usr/local/bin/rake my_task

is delayed job will work rails 4?

Will delayed job work with Rails 4?
Currently, I am upgrading my application to Rails 4 and using
gem "delayed_job", :git => 'git://github.com/collectiveidea/delayed_job.git'
in gemfile.
when i run rake jobs:work i got error like this
Error while reserving job: undefined method reserve for
Delayed::Job:Class
any help on this?
add this gem 'delayed_job_active_record' line below gem "delayed_job" to your gem file like this,
gem "delayed_job", :git => 'git://github.com/collectiveidea/delayed_job.git'
gem 'delayed_job_active_record'
and do
bundle install
then try
bundle exec rake jobs:work
hope it will work.
Delayed job will work on rails 4. But the delayed_job folder inside the bin folder.
So, You can run delayed job by following command
bin/delayed_job start`

why would I get `no such file to load -- ruby-debug` in production rake task?

I have a rake task that looks like so (crontab):
cd /data/TheApp/current && bundle exec rake nightly_tasks[3]
--trace --silent 2>> /data/TheApp/shared/log/tasks_prod_errors.log
It all runs fine in test and dev, but on prod I get this error:
rake aborted!
no such file to load -- ruby-debug
/usr/lib/ruby/gems/1.9.1/gems/bundler-1.0.21/lib/bundler/runtime.rb:68:in
`require'
/usr/lib/ruby/gems/1.9.1/gems/bundler-1.0.21/lib/bundler/runtime.rb:68:in
`block (2 levels) in require'
OK so I check my gemfile and I have this:
group :development, :test do
gem 'ruby-debug19', :require => 'ruby-debug', :platforms => :ruby
...
Production env should be ignoring that ruby-debug requirement. So I check my RAILS_ENV and it's correct:
$ echo $RAILS_ENV
production
On top of that the line that used to require ruby debug in this rake task is commented out. So to me it looks like there's no way bundle exec should be trying to load ruby-debug in prod. Is this maybe something to do with the gemfile.lock? There is an entry for ruby-debug19 in there. But why would my rake task be loading it in that case?
Also, running the command from the command line works fine. Confusing.
The rails environment and bundler groups are two completely different things. One doesn't know about the other although they use similar terms in your case
As a workaround, you can use bundle install --without development test in production to tell bundler to not install those groups. Alternatively, you can use something like this in your Gemfile:
unless ENV['RAILS_ENV'] == "production"
gem 'ruby-debug19', :require => 'ruby-debug', :platforms => :ruby
end
That expects that you have the environment variable RAILS_ENV set. during your bundle install run as well as during your bundle exec run (i.e. always).
All you need to do is use the “debugger” gem for ruby 1.9.
gem install debugger

Resources