Open pmeinhardt opened 5 years ago
Mmh 🤔 Setting up the mapping after deploy:starting
wasn't such a great idea. This means that the command will only work properly when you run a deploy:*
task that also invokes deploy:starting
(I should've seen that).
However, as mentioned before, setting up the mapping in the top scope in config/deploy.rb
breaks for me, as I am using a different :deploy_to
path per stage, e.g.
# config/deploy/staging.rb
set :deploy_to, '/var/www/app-staging'
# config/deploy/production.rb
set :deploy_to, '/var/www/app-production'
When I set up the command mapping in config/deploy.rb
, I get the following result:
set :application, 'app'
SSHKit.config.command_map[:composer] = "php #{shared_path.join('composer.phar')}"
Printing the mapping in a task (say maptest
) and running cap staging maptest
yields:
php /var/www/app/shared/composer.phar
It should be:
php /var/www/app-staging/shared/composer.phar
When I define the command mapping in the separate stage files (after the final, stage-specific :deploy_to
value is set), everything works as expected. This totally makes sense 😁 That does mean however, that I need to duplicate the command mappings for every stage 😞
I'll probably find a cleaner solution though and post it here when I find it 🙂
Then maybe updating the instructions here could be worth it for people who run into a similar issue.
Cheers
Okay, so the following works for all my use-cases (running composer tasks during deploy but also separately):
# config/deploy.rb
stages.each do |stage|
after stage, :map_commands do
SSHKit.config.command_map[:composer] = "php #{shared_path.join('composer.phar')}"
end
end
This defers the command mapping until all the stage variables, in particular :deploy_to
, have been initialized with their final values.
Should this be mentioned in the description for the composer:install_executable
task or what would be the best place for it?
I am also wondering whether this would be relevant for the general Capistrano FAQs or some place similar @capistrano?
In hindsight it makes a lot of sense, but initially I didn't think too much about the order in which the general deploy config, stage config and command mappings are initialized. I guess others might run into this too.
Thank you all for these super-helpful tools 🙇
An (more involved) alternative could also be for Capistrano to provide a complete wrapper around the SSHKit command map, which might look like the following:
# Define a command mapping with lazy initialization
command :composer, -> { "php #{shared_path.join('composer.phar'}" }
# Read command mappings
commands[:composer]
# => 'php /var/www/…'
Not sure about how exactly this could be tied into SSHKit though or whether that would just remain on the Capistrano layer:
task :example do
on roles(:all) do
execute commands[:composer], '--version'
# or (as before)
execute :composer, '--version'
end
end
Hey there, thanks for creating this gem 🙇
I've run into an issue when following the instructions in the README as the
shared_path
is not necessarily set correctly when you define the command mapping in the top-level scope.Instead, what worked for me was to defer the mapping until after
deploy:starting
, where we can be sure theshared_path
is initialized to the correct value:Maybe it'd make sense to update the README and
composer:install_executable
task description?