conditional tasks depending on environment ? (using cap-ext)

1,650 views
Skip to first unread message

ivar vasara

unread,
Apr 10, 2009, 10:00:44 AM4/10/09
to Capistrano
I've been using Capistrano for some time now, but one thing I haven't
been able to figure out is how to conditionally invoke tasks based on
environment. For example, on production there are additional
configurations to be made and static assets to be uploaded to s3. I'm
using the cap-ext plugin successfully, but being able to add before/
after filters based on environment would be a big win. Is there a
standard way of doing this ?

Jamis Buck

unread,
Apr 10, 2009, 10:26:34 AM4/10/09
to capis...@googlegroups.com
Just put your before/after declarations in the corresponding stage file.
E.g., in config/deploy/production.rb, say:

after "deploy:update", "upload_static_assets_to_s3"

etc.

- Jamis

Ivar Vasara

unread,
Apr 16, 2009, 8:22:44 PM4/16/09
to Capistrano
Jamis,

That looks like a perfect solution. I've followed your suggestion and
added the after "deploy:update" hook to config/deploy/staging.rb but
the stage files don't seem to be parsed. Unfortunately, I haven't
been able to find any documentation or notes about capistrano-ext
supporting the various stage files. To be honest, your reply was the
first I'd heard of the stage file feature, but inspired by your
solution I poked around and noticed the multistage:prepare task, which
I must have missed earlier. I started a post here, but figured I
should poke around the source a bit to understand my issue.. in I got
to (line 15 from multistage.rb in capistrano-ext on github):

stages.each do |name|
desc "Set the target stage to `#{name}'."
task(name) do
set :stage, name.to_sym
load "#{location}/#{stage}"
end
end

and it appears that the code inside the second 'do' is never
executed.. I haven't dug deep enough to know what's wrong but that
code has been there for ages, so it must be something to do with my
environment, but I can't tell what. The 'stages' array appears to be
set correctly by the time it gets to that code, but in config/deploy I
have three files - dev.rb, staging.rb and production.rb - none of
which are read.

Any help/pointers appreciated.

Jamis Buck

unread,
Apr 16, 2009, 9:10:21 PM4/16/09
to capis...@googlegroups.com
Each stage essentially becomes it's own task, so in order to invoke a
task in the environment of a particular stage, you need to specify that
stage:

cap production deploy
cap staging deploy:pending

etc.

- Jamis

Ivar Vasara

unread,
Apr 17, 2009, 1:26:54 AM4/17/09
to Capistrano
I'm been able to make use of the basic capistrano-ext multistage
functionality and deploy common tasks based on environment
successfully, but what I'm aiming to do is to customize the deployment
tasks that get invoked based on the environment. That is to say, I can
customize behaviour based on the variables I set in the stage (ie:
development/staging/production) task , but I would also like to
customize behaviour a bit further using after: hooks.

In response to my initial post you replied

-- snip --
Just put your before/after declarations in the corresponding stage
file.
E.g., in config/deploy/production.rb, say:
after "deploy:update", "upload_static_assets_to_s3"
etc.
-- snip --

which, if it worked, would have answered my question.

Buoyed by your reply, I added some tasks to my main deploy.rb file and
aimed to customize my deployment by adding some after
"deploy:update_code" hooks to the stage files in config/deploy/ -- eg.
my development.rb invokes the task that links the attachment-fu folder
to a folder on the filesystem, whereas staging.rb and production.rb
both call the task that configures attachment-fu for S3.

As I tried to communicate in my earlier post (on Thu, 16 Apr 2009), it
doesn't seem as if the stage files are actually being loaded. I'm not
sure how to get capistrano to recognize the files generated by cap
multistage:prepare.

Is there a problem with the approach of 1. defining all tasks in
deploy.rb then 2. customizing deployments for specific environments
using hooks in the appropriate stage file ?


- Ivar

Jamis Buck

unread,
Apr 17, 2009, 1:33:21 AM4/17/09
to capis...@googlegroups.com
On 4/16/09 11:26 PM, Ivar Vasara wrote:
> As I tried to communicate in my earlier post (on Thu, 16 Apr 2009), it
> doesn't seem as if the stage files are actually being loaded. I'm not
> sure how to get capistrano to recognize the files generated by cap
> multistage:prepare.

Are you requiring the multistage code in deploy.rb? You need to make
sure and have a line something like this:

require 'capistrano/ext/multistage'

But that really ought to be all it takes for it work.

> Is there a problem with the approach of 1. defining all tasks in
> deploy.rb then 2. customizing deployments for specific environments
> using hooks in the appropriate stage file ?

That should work just fine. At this point, I think the best thing you
could do is post your recipe files somewhere for us to review.

- Jamis

Ivar Vasara

unread,
Apr 17, 2009, 2:20:42 AM4/17/09
to Capistrano
Thanks for the blazingly quick reply !

I do have the appropriate "require 'capistrano/ext/multistage'" in my
deploy.rb.
I've posted what I think is the relevant data (relevant chunks of
deploy.rb, and the stage files) at http://pastie.org/449514
This is on os X, I've checked file permissions, everything *should* be
in order.

Jamis Buck

unread,
Apr 17, 2009, 9:19:07 AM4/17/09
to capis...@googlegroups.com
It all looks good to me. When you (e.g.) "cap staging deploy", what is
the output?

- Jamis

Ivar Vasara

unread,
Apr 17, 2009, 10:06:11 AM4/17/09
to Capistrano

I posted the output at http://pastie.org/449790

There are a couple of unclear messages like the following:

[staging.examplesite.com] executing command
command finished

But none of the tasks set as hooks in staging.rb were executed.

- Ivar


p.s. Your time spent looking into this is very much appreciated.
Thanks



On Apr 17, 6:19 am, Jamis Buck <ja...@37signals.com> wrote:
> It all looks good to me. When you (e.g.) "cap staging deploy", what is
> the output?
>
> - Jamis
>
> On Fri, Apr 17, 2009 at 12:20 AM, Ivar Vasara <i...@oobik.com> wrote:
>
> > Thanks for the blazingly quick reply !
>
> > I do have the appropriate "require 'capistrano/ext/multistage'" in my
> > deploy.rb.
> > I've posted what I think is the relevant data (relevant chunks of
> > deploy.rb, and the stage files) athttp://pastie.org/449514

Sarah Mei

unread,
Apr 18, 2009, 5:22:11 PM4/18/09
to capis...@googlegroups.com
I think you're running into method name conflicts. You have tasks in
your default namespace called :development and :staging that are
clobbering the stage-related methods.

Move that role-setting logic to deploy/development.rb and
deploy/staging.rb and you should be fine.

Ivar Vasara

unread,
Apr 20, 2009, 10:07:33 AM4/20/09
to Capistrano
That's exactly it! I feel a bit sheepish for missing this, but thank
you very much for pointing it out !
I've updated the capistrano-ext wiki with a pointer to this thread to
spare anyone else the same pain.
( http://wiki.github.com/jamis/capistrano-ext )
Reply all
Reply to author
Forward
0 new messages