Module: Capistrano::FastDeploy::Integration

Defined in:
lib/capistrano/fast_deploy/integration.rb

Class Method Summary collapse

Class Method Details

.load_into(capistrano_config) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/capistrano/fast_deploy/integration.rb', line 6

def self.load_into(capistrano_config)
  capistrano_config.load do
    set(:latest_release)  { fetch(:current_path) }
    set(:release_path)    { fetch(:current_path) }
    set(:current_release) { fetch(:current_path) }

    set(:releases_path) { fetch(:current_path) }

    set(:current_revision)  { capture("cd #{current_path}; git rev-parse --short HEAD").strip }
    set(:latest_revision)   { capture("cd #{current_path}; git rev-parse --short HEAD").strip }
    set(:previous_revision) { capture("cd #{current_path}; git rev-parse --short HEAD@{1}").strip }

    set :mapped_shared_children, { } unless defined?(mapped_shared_children)

    namespace :deploy do
      def git_reset(ref)
        update_command = []

        update_command << "cd #{deploy_to}"
        # Fix up symlinked current folder
        update_command << 'RELEASE=`readlink current`; if [ "$RELEASE" ]; then rm -rf current; mv "$RELEASE" "current"; fi'
        # Git clone if it hasn't happened already
        update_command << "if [ ! -d \"#{current_path}/.git\" ]; then git clone -q #{repository} #{current_path}; fi"

        update_command << "cd #{current_path}"
        # Fetch and reset
        update_command << ["git fetch -q origin && git reset --hard #{ref}"]
        # Write the revision file
        update_command << "git rev-parse --verify HEAD > #{current_path}/REVISION"
        run update_command.join(' && ')
      end

      desc "Update the deployed code."
      task :update_code, :except => { :no_release => true } do
        git_reset(branch)

        on_rollback do
          git_reset("HEAD@{1}")
          finalize_update
          rollback.cleanup
        end

        finalize_update
      end

      desc "This is a no-op when fast_deploy is in use"
      task :create_symlink do
      end

      desc "This is a no-op when fast_deploy is in use"
      task :cleanup do
      end

      task :finalize_update, :except => { :no_release => true } do
        commands = []
        commands << "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)

        # mkdir -p is making sure that the directories are there for some SCM's that don't
        # save empty folders
        shared_children.map do |d|
          if (d.rindex('/')) then
            commands << "rm -rf #{latest_release}/#{d} && mkdir -p #{latest_release}/#{d.slice(0..(d.rindex('/')))}"
          else
            commands << "rm -rf #{latest_release}/#{d}"
          end
          commands << "ln -s #{shared_path}/#{d.split('/').last} #{latest_release}/#{d}"
        end

        mapped_shared_children.map do |src, dest|
          commands << "rm -rf #{latest_release}/#{dest}"
          commands << "ln -s #{shared_path}/#{src} #{latest_release}/#{dest}"
        end

        run commands.join(" && ")

        if fetch(:normalize_asset_timestamps, true)
          stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
          asset_paths = fetch(:public_children, %w(images stylesheets javascripts)).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
          run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
        end
      end

      namespace :rollback do
        desc "Moves the repo back to the previous version of HEAD"
        task :repo, :except => { :no_release => true } do
          set :branch, "HEAD@{1}"
          deploy.default
        end

        desc "Rewrite reflog so HEAD@{1} will continue to point to at the next previous release."
        task :cleanup, :except => { :no_release => true } do
          run "cd #{current_path}; git reflog delete --rewrite HEAD@{1}; git reflog delete --rewrite HEAD@{1}"
        end

        desc "Rolls back to the previously deployed version."
        task :default do
          rollback.repo
          rollback.cleanup
        end
      end
    end
  end
end