5

On our staging server we run our Rails application in the production environment so as to be as similar as possible to our production server. We're using whenever to create our crontab. However, we need to run a slightly different rake task for our sitemap generation so it doesn't ping Google and Bing.

In deploy.rb, we have: set :stages, %w(production staging), but in both deploy/staging.rb and deploy/production.rb we have :rails_env, "production" set, so I can't use Rails.env.

In schedule.rb, I want to do something like:

every :day, at: '1am' do
  if @stage == 'production'
    rake 'sitemap:refresh'
  else
    rake 'sitemap:refresh:no_ping'
  end
end

How can I make that variable available?

Update

I was able to solve it by putting

set :whenever_variables, defer { "stage=#{stage}" }

into my deploy/staging.rb. I then had access to @stage in schedule.rb

Muntasim
  • 6,689
  • 3
  • 46
  • 69
Jason
  • 63
  • 1
  • 5

3 Answers3

5

not really sure if this will work but worth a try (from the whenever readme)

# deploy.rb
set :whenever_environment, defer { stage }
require "whenever/capistrano"

then in your schedule.rb

set :environment, ENV['RAILS_ENV']

case environment
when 'production', 'staging'
  ...
when 'production'
  ...
when 'staging'
  ...
end

UPDATE: you can also use

set(:whenever_command) { "STAGE=#{stage} bundle exec whenever" }

so that you have access to a STAGE environment variable inside schedule.rb

jvnill
  • 29,479
  • 4
  • 83
  • 86
  • The problem is that in our case, environment/RAILS_ENV is always equal to "production". I need to get at the capistrano stage. – Jason Mar 01 '13 at 16:33
  • i haven't tried this out yet but I think what `set :whenever_environment, defer { stage }` does is it sets the whenever environment to the value of `stage`. – jvnill Mar 01 '13 at 16:36
  • Thanks for your help @jvnill. See my update for how I solved my problem. I think your whenever_command solution probably would have worked, too. – Jason Mar 01 '13 at 17:39
3

The defer method doesn't appear to work in the later versions of Capistrano (3.4.1) / whenever (0.9.7). I was hitting an error with NoMethodError: undefined method 'defer' for main:Object. Here's what worked for me:

deploy.rb:

set :whenever_environment, Proc.new { fetch :stage }

schedule.rb:

if @environment == 'production'
  every 15.minutes, roles: [:my_custom_role] do
    rake 'my_rake_task'
  end
end
dmccabe
  • 1,044
  • 12
  • 11
0

@jvnill has the right answer. If you're using config/deploy/ for separate environments, you can keep it a little neater by putting the setting in the proper stage.

# config/deploy/staging.rb
set :whenever_command, "STAGE=#{stage} bundle exec whenever"

# config/deploy/production.rb
set :whenever_command, "STAGE=production bundle exec whenever"

# config/deploy.rb
require "whenever/capistrano"

By requiring 'whenever/capistrano,' you take care of running the whenever after deploy:finalize_update.

https://github.com/javan/whenever/blob/master/lib/whenever/capistrano/v2/hooks.rb

richardun
  • 693
  • 5
  • 11