sunraise 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
File without changes
data/bin/sunraise ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rainbow'
5
+
6
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'config')
7
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'deployer')
8
+
9
+ include SunRaise::PubConf
10
+
11
+
12
+ if File.expand_path(__FILE__) == File.expand_path(File.join(Dir.pwd, 'sunraise'))
13
+ puts "Run it from you app folder, containing sunraise file with deploy instructions"
14
+ exit
15
+ end
16
+
17
+ unless File.file?(File.join Dir.pwd, 'sunraise')
18
+ puts "No sunraise file found at #{Dir.pwd}"
19
+ exit
20
+ end
21
+
22
+
23
+ at_exit { SunRaise::Deployer.new.go! }
24
+
25
+
26
+ load File.join Dir.pwd, 'sunraise'
data/lib/config.rb ADDED
@@ -0,0 +1,97 @@
1
+ require 'singleton'
2
+ require 'optparse'
3
+
4
+ module SunRaise
5
+ # configurator class
6
+ class Config
7
+
8
+ include Singleton
9
+ attr_accessor :conf, :callbacks
10
+
11
+ class << self
12
+ attr_accessor :config_methods
13
+ end
14
+
15
+ @config_methods = [
16
+ :remote_host,
17
+ :remote_user,
18
+ :deploy_to,
19
+ :then_link_to,
20
+ :git_url,
21
+ :shared_dirs,
22
+ :linked_dirs,
23
+ :local_project_path,
24
+ :verbose,
25
+ :force,
26
+ :release,
27
+ :remake,
28
+ :test_rails_app,
29
+ :auto_migrate,
30
+ :help,
31
+ :destroy
32
+ ]
33
+
34
+ @config_methods.each do |method_name|
35
+ define_method method_name do |value|
36
+ value.strip! if value.class == String
37
+ @conf[method_name] = value
38
+ end
39
+ end
40
+
41
+ def initialize
42
+ @callbacks = {:after => ''}
43
+ @conf = {
44
+ :verbose => false,
45
+ :local_project_path => '.',
46
+ :release => true,
47
+ :test_rails_app => true,
48
+ :auto_migrate => true,
49
+ :help => false
50
+ }
51
+
52
+ cl_options
53
+ end
54
+
55
+ def cl_options
56
+ OptionParser.new do |opts|
57
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |verbose|
58
+ @conf[:verbose] = verbose
59
+ end
60
+
61
+ opts.on("-f", "--[no-]force", "Deploy even there are no new commits") do |force|
62
+ @conf[:force] = force
63
+ end
64
+
65
+ opts.on("-n", "--no-reelase", "Do not replace 'current' dir and start test server") do |no_release|
66
+ @conf[:release] = !no_release
67
+ end
68
+
69
+ opts.on("--remake", "Delete current deploy and make initial deploy") do |remake|
70
+ @conf[:remake] = remake
71
+ end
72
+
73
+ opts.on("-d", "--destroy", "Delete current deploy and make initial deploy") do |destroy|
74
+ @conf[:destroy] = destroy
75
+ end
76
+
77
+ opts.on("-h", "--help", "Show this help") do |help|
78
+ @conf[:help] = true
79
+ puts opts
80
+ end
81
+ end.parse!
82
+ end
83
+
84
+ end
85
+
86
+ module PubConf
87
+ SunRaise::Config.config_methods.each do |method_name|
88
+ define_method method_name do |value|
89
+ SunRaise::Config.instance.send method_name, value
90
+ end
91
+ end
92
+
93
+ def after_deploy &block
94
+ SunRaise::Config.instance.callbacks[:after] = block
95
+ end
96
+ end
97
+ end
data/lib/deployer.rb ADDED
@@ -0,0 +1,197 @@
1
+ begin
2
+ require 'rubygems'
3
+ gem 'net-ssh', ">= 2.0.10"
4
+ rescue LoadError, NameError
5
+ end
6
+
7
+ require 'net/ssh'
8
+
9
+ module SunRaise
10
+ # working horse
11
+ class Deployer
12
+
13
+ def go!
14
+ return if conf[:help]
15
+ return destroy_existen! if conf[:destroy]
16
+ if !conf[:remake] && initiated?
17
+ update
18
+ else
19
+ init_deploy
20
+ end
21
+
22
+ callbacks :after
23
+
24
+ puts "SSH OUT: \n" + @ssh_out.join("\n") if conf[:verbose]
25
+ end
26
+
27
+ def init_deploy
28
+ destroy_existen! if conf[:remake]
29
+ log_ok "initial deploy.."
30
+ ssh_exec [
31
+ "mkdir -p #{deploy_path}",
32
+ "cd #{deploy_path}",
33
+ "mkdir -p log shared tmp",
34
+ "git clone #{conf[:git_url]} current"
35
+ ]
36
+ log_ok "Created dir and cloned repo"
37
+
38
+ test_rails_app! 'current' if conf[:test_rails_app]
39
+ auto_migrate! 'current' if conf[:auto_migrate]
40
+
41
+ log_ok "Made new dirs and cloned repo"
42
+ make_links 'current'
43
+ end
44
+
45
+ def update
46
+
47
+ last_commit = ssh_exec ["cd #{current_path}", "git log -1 --pretty=format:\"%H\""]
48
+ last_repo_commit = (`cd #{conf[:local_project_path]} && git ls-remote #{conf[:git_url]}`).split("\t").first
49
+
50
+ if !conf[:force] && last_commit.strip == last_repo_commit.strip
51
+ log_ok "Nothing to update"
52
+ return
53
+ end
54
+
55
+ new_commits = (`cd #{conf[:local_project_path]} && git log #{last_commit}..HEAD --pretty=format:"%s"`).split("\n")
56
+
57
+ log_ok "New commits: \n #{new_commits.join "\n "}"
58
+ @new_dir = "pre_release"
59
+
60
+ ssh_exec [
61
+ "cd #{deploy_path}",
62
+ "rm #{@new_dir} .git_temp previous2 current2 -rf", # if previous deploy was crashed
63
+ "mv current/.git .git_temp", # moving repo dir
64
+ "cp current #{@new_dir}", # clone sitedir without .git
65
+ "mv .git_temp #{@new_dir}/.git", # move git in pre_release folder
66
+ "cd #{@new_dir}",
67
+ "git pull origin master"
68
+ ]
69
+ log_ok "Forked, git updated"
70
+
71
+ make_links @new_dir
72
+
73
+ test_rails_app! @new_dir if conf[:test_rails_app]
74
+ auto_migrate! @new_dir if conf[:auto_migrate]
75
+
76
+ release! if conf[:release]
77
+ end
78
+
79
+ def release!
80
+ ssh_exec [
81
+ "cd #{deploy_path}", # folder magic :) old current => previous, pre_release => current
82
+ "mv current current2",
83
+ "mv #{@new_dir} current",
84
+ "if [ -d previous ]; then mv previous previous2 -f; fi",
85
+ "mv current2 previous"
86
+ ]
87
+ log_ok "Released!"
88
+ end
89
+
90
+ private
91
+ def ssh_exec command
92
+ command = command.join " && " if command.is_a? Array
93
+ puts ">>>>".color(:cyan) + " #{command}" if conf[:verbose]
94
+ @ssh_ist ||= Net::SSH.start conf[:remote_host], conf[:remote_user]
95
+ @ssh_out ||= []
96
+ @ssh_out << @ssh_ist.exec!(command)
97
+ @ssh_out.last
98
+ end
99
+
100
+ def make_links dist_dir
101
+ links = []
102
+ conf[:shared_dirs].each do |dir|
103
+ links << "rm #{dir} -rf"
104
+ links << "mkdir ../shared/#{dir} -p"
105
+ links << "ln -s ../shared/#{dir} #{dir}"
106
+ end
107
+
108
+ conf[:linked_dirs].each do |dir|
109
+ links << "rm #{dir} -rf"
110
+ links << "mkdir ../#{dir} -p"
111
+ links << "ln -s ../#{dir} #{dir}"
112
+ end
113
+
114
+ ssh_exec ["cd #{File.join deploy_path, dist_dir}"] + links
115
+ @ssh_out.each {|m| puts m}
116
+ log_ok "Made links"
117
+ end
118
+
119
+ def initiated?
120
+ ssh_exec "cd #{current_path}"
121
+ last_msg = @ssh_out.pop
122
+ !(last_msg && last_msg =~ /No such file or directory/)
123
+ end
124
+
125
+ def destroy_existen!
126
+ log_ok "Removing existen deploy dir"
127
+ ssh_exec "rm #{deploy_path} -rf"
128
+ end
129
+
130
+ def test_rails_app! dir
131
+ @app_about ||= rails_app_about dir
132
+ if !@app_about.index('Application root')
133
+ if !@app_about.index('Database schema version')
134
+ log_error "Rails app test fail"
135
+ else
136
+ log_error "Rails app test: Database didn't configurated"
137
+ end
138
+ puts @app_about
139
+ log_error "Deploy aborted, use " + "ssh #{conf[:remote_user]}@#{conf[:remote_host]}".italic + " to fix it"
140
+ exit
141
+ else
142
+ log_ok "Rails app successfully tested"
143
+ end
144
+ end
145
+
146
+ def auto_migrate! dir
147
+ @app_about ||= rails_app_about dir
148
+ matches = @app_about.match(/Database schema version\s+ ([0-9]+)/)
149
+ remote_magration_version = matches && matches.size > 0 && matches[1] || 0
150
+ local_about = `#{File.join conf[:local_project_path], 'script', 'about'}`
151
+ local_migration_version = local_about.match(/Database schema version\s+ ([0-9]+)/)[1]
152
+ if remote_magration_version == local_migration_version
153
+ msg_ok "No new migrations"
154
+ else
155
+ log_ok "Rinning rake db:migrate"
156
+ puts ssh_exec ["cd #{File.join deploy_path, dir}", "rake db:migrate RAILS_ENV=production"] # run migrations
157
+ end
158
+ end
159
+
160
+ def rails_app_about dir
161
+ ssh_exec "RAILS_ENV=production " + File.join(deploy_path, dir, 'script', 'about') # run script/about
162
+ end
163
+
164
+ def conf
165
+ SunRaise::Config.instance.conf
166
+ end
167
+
168
+ def callbacks name
169
+ c = SunRaise::Config.instance.callbacks
170
+
171
+ if c[name].class == Proc
172
+ instance_eval &c[name]
173
+ end
174
+ end
175
+
176
+ def current_path
177
+ File.join conf[:deploy_to], 'current'
178
+ end
179
+
180
+ def deploy_path
181
+ conf[:deploy_to]
182
+ end
183
+
184
+ def app_path
185
+ File.join deploy_path, (conf[:release] ? 'current' : 'pre_release' )
186
+ end
187
+
188
+ def log_ok msg
189
+ puts ":: ".color(:green) + "#{msg}".bright
190
+ end
191
+
192
+ def log_error msg
193
+ puts "!! ".bright.color(:red) + "#{msg}".bright
194
+ end
195
+
196
+ end
197
+ end
data/sunraise.example ADDED
@@ -0,0 +1,12 @@
1
+ remote_host 'twews.com'
2
+ remote_user 'root'
3
+
4
+ git_url 'git://github.com/Paxa/sunraise_test_app.git'
5
+
6
+ deploy_to '/tmp/deploy/suntest'
7
+ then_link_to '/tmp/www/suntest'
8
+
9
+ shared_dirs ['lib']
10
+ linked_dirs ['logs', 'tmp']
11
+
12
+ local_project_path "/home/paxa/Dropbox/sunraise/test/suntest"
data/sunraise.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "sunraise"
3
+ s.version = "0.1.1"
4
+ s.summary = "Super-fast and simple rails deployment."
5
+ s.description = "Super-fast and simple rails deployment"
6
+ s.author = "Pavel Evstigneev"
7
+ s.email = "pavel.evst@gmail.com"
8
+ s.homepage = "http://github.com/Paxa/sunraise"
9
+ s.has_rdoc = false
10
+ s.executables = ["sunraise"]
11
+ s.rubyforge_project = "sunraise"
12
+ s.files = [ "bin/sunraise", "lib/config.rb", "lib/deployer.rb", "README.md", "sunraise.gemspec", 'sunraise.example']
13
+
14
+ if s.respond_to? :specification_version then
15
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
16
+ s.specification_version = 3
17
+
18
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
19
+ s.add_development_dependency(%q<rainbow>, [">= 1.0.4"])
20
+ else
21
+ s.add_dependency(%q<rainbow>, [">= 1.0.4"])
22
+ end
23
+ else
24
+ s.add_dependency(%q<rainbow>, [">= 1.0.4"])
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sunraise
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Pavel Evstigneev
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-09 00:00:00 +03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rainbow
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 0
30
+ - 4
31
+ version: 1.0.4
32
+ type: :development
33
+ version_requirements: *id001
34
+ description: Super-fast and simple rails deployment
35
+ email: pavel.evst@gmail.com
36
+ executables:
37
+ - sunraise
38
+ extensions: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ files:
43
+ - bin/sunraise
44
+ - lib/config.rb
45
+ - lib/deployer.rb
46
+ - README.md
47
+ - sunraise.gemspec
48
+ - sunraise.example
49
+ has_rdoc: true
50
+ homepage: http://github.com/Paxa/sunraise
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ requirements: []
73
+
74
+ rubyforge_project: sunraise
75
+ rubygems_version: 1.3.6
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Super-fast and simple rails deployment.
79
+ test_files: []
80
+