module Astrovan module Deploy # Deploy an application to the remote servers. # # Options: # * +application+ - a name for the application. If not provided, the application name is taken from the last component of the path to the source repository. # * +deploy_to+ - the path of the directory for application deployment. Defaults to '/u/apps/:application' # # If a block is provided, the block is run to deploy the application in the specified environment. # # If no block is provided, a default deployment recipe is applied. The default recipe is: # * create the deployment, release and shared directories # * update the application from the repository into the release directory # * symlink to the current application # # Due to differences in application environments, no provision is made to restart the application in the default # recipe. def deploy(repository, options = {}) original_environment = self.environment.dup self.repository = repository self.application = application = options[:application] || self.application || File.basename(URI.parse(repository).path.split('/').last,".git") self.deploy_to = deploy_to = options[:deploy_to] || self.deploy_to || "/u/apps/#{application}" self.shared_path = shared_path = File.join(deploy_to, 'shared') self.shared_repository = shared_repository = File.join(shared_path, "#{application}.git") self.release_name = release_name = Time.now.utc.strftime("%Y%m%d%H%M%S") self.releases_path = releases_path = File.join(deploy_to, 'releases') self.release_path = release_path = File.join(releases_path, release_name) self.env = options[:env] || self.env self.rakefile = options[:rakefile] || self.rakefile if block_given? yield else # TODO: consider moving directory setup outside of update dirs = [deploy_to, releases_path, shared_path] # TODO: these shared children are rails specific... come up with another plan # shared_children = %w(system log pids) # dirs += shared_children.map { |d| File.join(shared_path, d) } mkdir(dirs, options) update options end rescue => e # TODO: rollback # rollback raise ensure self.environment.replace original_environment end end end