A short blog post in lieu of a longer one, since I’m so busy. However I noticed this recently and figured someone else might be wondering.
The workflow for my biggest client involves using Jenkins as a coordinator for builds & deploys. This often involves checking out something from git, running tests and whatever, then using Capistrano to deploy it (we generally use Capistrano even if the project isn’t Ruby, unless it comes with something else).
While working on a python project recently, using virtualenv, I noticed that I couldn’t use source in a run command:
* executing `app:pip' * executing "cd /mnt/web_stage/sites/someclient.com/web-app/releases/20120430160812 && source someclient/bin/activate && pip install -r requirements/requirements.txt" servers: ["localhost"] [localhost] executing command *** [err :: localhost] sh: source: not found
Turns out, by default, Capistrano won’t send the command itself directly, such as:
ssh foo@bar 'cap production deploy'
but rather attempts to make any potential shell differences irrelevant, and uses:
ssh foo@bar 'sh -c 'cap production deploy' '
…opting for the lowest common denominator, sh. Which is fine, but not helpful for what I was trying to do (install stuff in a virtualenv environment, for which
source is useful).
You can change this by setting :shell to be either false (to execute commands directly) or a path to a shell you prefer.
Interestingly, setting this is not intuitive. Trying to set this as you might expect:
set :shell, false
does absolutely nothing.
After looking through the gem source, I found that this works:
default_run_options[:shell] = false
That allowed me to source the activation script for virtualenv, and then everything works as you might expect.
Also, please, don’t give me any jibba jabba about how I’m not using Fabric. We decided on a standard and we use the standard.