shuttle-deploy 0.2.0.beta1 → 0.2.0.beta2
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.
- checksums.yaml +8 -8
- data/README.md +82 -14
- data/lib/shuttle/deploy.rb +1 -33
- data/lib/shuttle/deployment/nodejs.rb +1 -1
- data/lib/shuttle/deployment/php.rb +1 -1
- data/lib/shuttle/deployment/rails.rb +1 -1
- data/lib/shuttle/deployment/ruby.rb +1 -1
- data/lib/shuttle/deployment/static.rb +1 -1
- data/lib/shuttle/errors.rb +2 -2
- data/lib/shuttle/path_helpers.rb +39 -0
- data/lib/shuttle/{tasks.rb → strategy.rb} +15 -14
- data/lib/shuttle/target.rb +2 -2
- data/lib/shuttle/version.rb +1 -1
- data/lib/shuttle.rb +16 -15
- data/spec/spec_helper.rb +3 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODM5ZTBlNTBhMjQ3OGVhYzVjMGUyN2M5YzY2OGYxOTdmMTM3OWViOQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjYxYzQyYzY2Y2U5OWQ3MzMyNGU1MTM5ZDgxZDQzMzFhZDUwNTUwMw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDc0MzdhNWMxNmRkZThiYWE2OGU1NmM5YmI5ZjRmMmYwZTQ0NTZlMzJjNmE3
|
10
|
+
MGRhNzNkMzFjODk1MjhhMWMxNzMxMjUwODk2N2MyZTE0YmI4OGUyZDdmNzhh
|
11
|
+
YzQ0NWQ4M2Q3ZDY4YWIzNjdlY2JlOTFlZDJkNWU0NjFhZGJlZjc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODYzNTI5MDJiNzdjODZkZmIxMzgyM2M4M2JlYzAzNmJlYjMwMTkzZjFjMzE1
|
14
|
+
YmRlOTg0NWU1NzIzZjZhMTZlYjIxYzQxODA1YTQ5NTE4M2RlNjAzYWE5MmQ5
|
15
|
+
MWE1MDMzOTczMzNlMjkwMzFkOGZiZDI4MjNlYWI1NWQ0NGIwNjU=
|
data/README.md
CHANGED
@@ -8,7 +8,13 @@ Operations are performed on SSH connection with target server.
|
|
8
8
|
|
9
9
|
## Install
|
10
10
|
|
11
|
-
|
11
|
+
Install from Rubygems:
|
12
|
+
|
13
|
+
```
|
14
|
+
gem install shuttle-deploy
|
15
|
+
```
|
16
|
+
|
17
|
+
Or install manually (clone repo first):
|
12
18
|
|
13
19
|
```
|
14
20
|
rake install
|
@@ -42,16 +48,15 @@ Shared directory structure:
|
|
42
48
|
|
43
49
|
## Process
|
44
50
|
|
45
|
-
Deployment flow
|
51
|
+
Deployment flow consists of steps:
|
46
52
|
|
47
|
-
-
|
48
|
-
- Prepare application structure
|
49
|
-
- Clone
|
50
|
-
-
|
51
|
-
-
|
52
|
-
-
|
53
|
-
-
|
54
|
-
- Clean up old releases (default count: 5)
|
53
|
+
- Connect to remote server
|
54
|
+
- Prepare application structure (releases, shared dirs, etc)
|
55
|
+
- Clone or update git/svn repository code from specified branch
|
56
|
+
- Create a new release and checkout application code
|
57
|
+
- Perform strategy-defined tasks
|
58
|
+
- Make new release current
|
59
|
+
- Cleanup old releases
|
55
60
|
|
56
61
|
## Strategies
|
57
62
|
|
@@ -71,7 +76,6 @@ Example configuration:
|
|
71
76
|
```yaml
|
72
77
|
app:
|
73
78
|
name: my-application
|
74
|
-
strategy: static
|
75
79
|
git: git@github.com:my-site.git
|
76
80
|
|
77
81
|
target:
|
@@ -81,11 +85,55 @@ target:
|
|
81
85
|
deploy_to: /home/deployer/www
|
82
86
|
```
|
83
87
|
|
84
|
-
###
|
88
|
+
### WordPress Strategy
|
85
89
|
|
86
90
|
This strategy is designed to deploy wordpress sites developed as a separate theme.
|
87
91
|
It requires `subversion` installed on the server (will be automatically installed).
|
88
92
|
|
93
|
+
### Rails Strategy
|
94
|
+
|
95
|
+
Rails deployment strategy will deploy your basic application: install dependencies,
|
96
|
+
migrate database, precompile assets and start web server. Most of the steps are automatic.
|
97
|
+
|
98
|
+
Define strategy first:
|
99
|
+
|
100
|
+
```yml
|
101
|
+
app:
|
102
|
+
name: myapp
|
103
|
+
strategy: rails
|
104
|
+
```
|
105
|
+
|
106
|
+
Then add a separate section:
|
107
|
+
|
108
|
+
```yml
|
109
|
+
rails:
|
110
|
+
environment: production
|
111
|
+
precompile_assets: true
|
112
|
+
start_server: true
|
113
|
+
```
|
114
|
+
|
115
|
+
If using `start_server`, shuttle will try to start thin server.
|
116
|
+
You can modify settings for thin:
|
117
|
+
|
118
|
+
```yml
|
119
|
+
thin:
|
120
|
+
host: 127.0.0.1
|
121
|
+
port: 9000
|
122
|
+
servers: 5
|
123
|
+
```
|
124
|
+
|
125
|
+
You can also use `foreman` to run application:
|
126
|
+
|
127
|
+
```yml
|
128
|
+
rails:
|
129
|
+
start_server: false
|
130
|
+
|
131
|
+
hooks:
|
132
|
+
before_link_release:
|
133
|
+
- "sudo bundle exec foreman export upstart /etc/init -a $DEPLOY_APP -u $DEPLOY_USER -p 9000 -l $DEPLOY_SHARED_PATH/log"
|
134
|
+
- "sudo start $DEPLOY_APP || sudo restart $DEPLOY_APP"
|
135
|
+
```
|
136
|
+
|
89
137
|
## Deployment Config
|
90
138
|
|
91
139
|
Deployment config has a few main sections: `app` and `target`.
|
@@ -158,6 +206,27 @@ targets:
|
|
158
206
|
deploy_to: /home/staging/myapp
|
159
207
|
```
|
160
208
|
|
209
|
+
### Deployment environment
|
210
|
+
|
211
|
+
During deployment shuttle sets a few environment variables:
|
212
|
+
|
213
|
+
- `DEPLOY_APP` - Application name
|
214
|
+
- `DEPLOY_USER` - Current deployment user
|
215
|
+
- `DEPLOY_PATH` - Path to application releases
|
216
|
+
- `DEPLOY_RELEASE` - New release number
|
217
|
+
- `DEPLOY_RELEASE_PATH` - Path to currently executing release
|
218
|
+
- `DEPLOY_CURRENT_PATH` - Path to current release (symlinked)
|
219
|
+
- `DEPLOY_SHARED_PATH` - Path to shared resources
|
220
|
+
- `DEPLOY_SCM_PATH` - Path to code repository
|
221
|
+
|
222
|
+
These could be used in hooks. Example:
|
223
|
+
|
224
|
+
```
|
225
|
+
hooks:
|
226
|
+
before_link_release:
|
227
|
+
- "cp $DEPLOY_SHARED_PATH/myconfig $DEPLOY_RELEASE_PATH/myconfig"
|
228
|
+
```
|
229
|
+
|
161
230
|
## Usage
|
162
231
|
|
163
232
|
To execute a new deploy, simply type (in your project folder):
|
@@ -177,7 +246,6 @@ Shuttle v0.2.0
|
|
177
246
|
-----> Using branch 'master'
|
178
247
|
-----> Linking release
|
179
248
|
-----> Release v35 has been deployed
|
180
|
-
-----> Cleaning up old releases: 1
|
181
249
|
|
182
250
|
Execution time: 2s
|
183
251
|
```
|
@@ -227,4 +295,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
227
295
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
228
296
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
229
297
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
230
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
298
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/shuttle/deploy.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Shuttle
|
2
2
|
class Deploy
|
3
|
-
include Shuttle::Tasks
|
4
3
|
include Shuttle::Helpers
|
4
|
+
include Shuttle::PathHelpers
|
5
5
|
|
6
6
|
attr_reader :ssh
|
7
7
|
attr_reader :target
|
@@ -22,37 +22,5 @@ module Shuttle
|
|
22
22
|
@version = 1
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
26
|
-
def deploy_path(path=nil)
|
27
|
-
[target.deploy_to, path].compact.join('/')
|
28
|
-
end
|
29
|
-
|
30
|
-
def shared_path(path=nil)
|
31
|
-
[deploy_path, 'shared', path].compact.join('/')
|
32
|
-
end
|
33
|
-
|
34
|
-
def current_path(path=nil)
|
35
|
-
[deploy_path, 'current', path].compact.join('/')
|
36
|
-
end
|
37
|
-
|
38
|
-
def version_path
|
39
|
-
deploy_path('version')
|
40
|
-
end
|
41
|
-
|
42
|
-
def release_path(path=nil)
|
43
|
-
[deploy_path, 'releases', version, path].compact.join('/')
|
44
|
-
end
|
45
|
-
|
46
|
-
def scm_path
|
47
|
-
deploy_path('scm')
|
48
|
-
end
|
49
|
-
|
50
|
-
def deploy
|
51
|
-
setup
|
52
|
-
update_code
|
53
|
-
checkout_code
|
54
|
-
link_release
|
55
|
-
cleanup_releases
|
56
|
-
end
|
57
25
|
end
|
58
26
|
end
|
data/lib/shuttle/errors.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Shuttle
|
2
|
+
module PathHelpers
|
3
|
+
# Get deployment root path, everything is based from here
|
4
|
+
# @return [String]
|
5
|
+
def deploy_path(path=nil)
|
6
|
+
[target.deploy_to, path].compact.join('/')
|
7
|
+
end
|
8
|
+
|
9
|
+
# Get shared path between releases
|
10
|
+
# @return [String]
|
11
|
+
def shared_path(path=nil)
|
12
|
+
[deploy_path, 'shared', path].compact.join('/')
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get path to currently used release
|
16
|
+
# @return [String]
|
17
|
+
def release_path(path=nil)
|
18
|
+
[deploy_path, 'releases', version, path].compact.join('/')
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get current release (symlinked) path
|
22
|
+
# @return [String]
|
23
|
+
def current_path(path=nil)
|
24
|
+
[deploy_path, 'current', path].compact.join('/')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get path to release version file
|
28
|
+
# @return [String]
|
29
|
+
def version_path
|
30
|
+
deploy_path('version')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get path to where repository code is stored
|
34
|
+
# @return [String]
|
35
|
+
def scm_path
|
36
|
+
deploy_path('scm')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
module Shuttle
|
4
|
-
|
4
|
+
class Strategy < Shuttle::Deploy
|
5
5
|
def setup
|
6
6
|
log "Preparing application structure"
|
7
7
|
|
@@ -9,7 +9,6 @@ module Shuttle
|
|
9
9
|
|
10
10
|
ssh.run "mkdir -p #{deploy_path}"
|
11
11
|
ssh.run "mkdir -p #{deploy_path('releases')}"
|
12
|
-
ssh.run "mkdir -p #{deploy_path('backups')}"
|
13
12
|
ssh.run "mkdir -p #{deploy_path('shared')}"
|
14
13
|
ssh.run "mkdir -p #{shared_path('tmp')}"
|
15
14
|
ssh.run "mkdir -p #{shared_path('pids')}"
|
@@ -26,10 +25,6 @@ module Shuttle
|
|
26
25
|
cleanup_releases
|
27
26
|
end
|
28
27
|
|
29
|
-
def keep_releases
|
30
|
-
config.app.keep_releases || 10
|
31
|
-
end
|
32
|
-
|
33
28
|
def update_code
|
34
29
|
if config.app.svn
|
35
30
|
return update_code_svn
|
@@ -153,8 +148,8 @@ module Shuttle
|
|
153
148
|
|
154
149
|
log "Release v#{version} has been deployed"
|
155
150
|
|
156
|
-
# Execute after link_release hook
|
157
|
-
execute_hook(:after_link_release)
|
151
|
+
# Execute after link_release hook, allow failures here
|
152
|
+
execute_hook(:after_link_release, true)
|
158
153
|
end
|
159
154
|
|
160
155
|
def write_lock
|
@@ -182,7 +177,7 @@ module Shuttle
|
|
182
177
|
num = Integer(count) - Integer(keep_releases)
|
183
178
|
|
184
179
|
if num > 0
|
185
|
-
log "Cleaning up old releases: #{num}"
|
180
|
+
log "Cleaning up old releases: #{num}" if num > 1
|
186
181
|
|
187
182
|
ssh.run("remove=$((count > #{keep_releases} ? count - #{keep_releases} : 0))")
|
188
183
|
ssh.run("ls -1d [0-9]* | sort -rn | tail -n $remove | xargs rm -rf {}")
|
@@ -208,9 +203,11 @@ module Shuttle
|
|
208
203
|
|
209
204
|
def export_environment
|
210
205
|
ssh.export_hash(
|
206
|
+
'DEPLOY_APP' => config.app.name,
|
211
207
|
'DEPLOY_APPLICATION' => config.app.name,
|
212
208
|
'DEPLOY_USER' => target.user,
|
213
209
|
'DEPLOY_PATH' => deploy_path,
|
210
|
+
'DEPLOY_RELEASE' => version,
|
214
211
|
'DEPLOY_RELEASE_PATH' => release_path,
|
215
212
|
'DEPLOY_CURRENT_PATH' => current_path,
|
216
213
|
'DEPLOY_SHARED_PATH' => shared_path,
|
@@ -226,9 +223,9 @@ module Shuttle
|
|
226
223
|
end
|
227
224
|
end
|
228
225
|
|
229
|
-
def execute_hook(name)
|
226
|
+
def execute_hook(name, allow_failures=false)
|
230
227
|
if config.hooks && config.hooks[name]
|
231
|
-
execute_commands(config.hooks[name])
|
228
|
+
execute_commands(config.hooks[name], allow_failures)
|
232
229
|
end
|
233
230
|
end
|
234
231
|
|
@@ -240,12 +237,16 @@ module Shuttle
|
|
240
237
|
exec("ssh #{target.user}@#{target.host}")
|
241
238
|
end
|
242
239
|
|
240
|
+
def keep_releases
|
241
|
+
config.app.keep_releases || 10
|
242
|
+
end
|
243
|
+
|
243
244
|
def changes_at?(path)
|
244
245
|
result = ssh.run(%{diff -r #{current_path}/#{path} #{release_path}/#{path} 2>/dev/null})
|
245
246
|
result.success? ? false : true
|
246
247
|
end
|
247
248
|
|
248
|
-
def execute_commands(commands=[])
|
249
|
+
def execute_commands(commands=[], allow_failures=false)
|
249
250
|
commands.flatten.compact.uniq.each do |cmd|
|
250
251
|
log %{Executing "#{cmd.strip}"}
|
251
252
|
command = cmd
|
@@ -253,7 +254,7 @@ module Shuttle
|
|
253
254
|
|
254
255
|
result = ssh.run(command)
|
255
256
|
|
256
|
-
if result.failure?
|
257
|
+
if result.failure? && allow_failures == false
|
257
258
|
error "Failed: #{result.output}"
|
258
259
|
else
|
259
260
|
stream_output(result.output)
|
@@ -261,4 +262,4 @@ module Shuttle
|
|
261
262
|
end
|
262
263
|
end
|
263
264
|
end
|
264
|
-
end
|
265
|
+
end
|
data/lib/shuttle/target.rb
CHANGED
@@ -15,8 +15,8 @@ module Shuttle
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def validate!
|
18
|
-
raise Shuttle::ConfigError, "Host required"
|
19
|
-
raise Shuttle::ConfigError, "User required"
|
18
|
+
raise Shuttle::ConfigError, "Host required" if host.nil?
|
19
|
+
raise Shuttle::ConfigError, "User required" if user.nil?
|
20
20
|
raise Shuttle::ConfigError, "Deploy path required" if deploy_to.nil?
|
21
21
|
end
|
22
22
|
end
|
data/lib/shuttle/version.rb
CHANGED
data/lib/shuttle.rb
CHANGED
@@ -13,23 +13,24 @@ require 'shuttle/version'
|
|
13
13
|
require 'shuttle/errors'
|
14
14
|
|
15
15
|
module Shuttle
|
16
|
-
autoload :Session,
|
17
|
-
autoload :Runner,
|
18
|
-
autoload :Deploy,
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
16
|
+
autoload :Session, 'shuttle/session'
|
17
|
+
autoload :Runner, 'shuttle/runner'
|
18
|
+
autoload :Deploy, 'shuttle/deploy'
|
19
|
+
autoload :Target, 'shuttle/target'
|
20
|
+
autoload :Helpers, 'shuttle/helpers'
|
21
|
+
autoload :PathHelpers, 'shuttle/path_helpers'
|
22
|
+
autoload :Strategy, 'shuttle/strategy'
|
22
23
|
|
23
|
-
autoload :Static,
|
24
|
-
autoload :Php,
|
25
|
-
autoload :Wordpress,
|
26
|
-
autoload :Ruby,
|
27
|
-
autoload :Rails,
|
28
|
-
autoload :Nodejs,
|
24
|
+
autoload :Static, 'shuttle/deployment/static'
|
25
|
+
autoload :Php, 'shuttle/deployment/php'
|
26
|
+
autoload :Wordpress, 'shuttle/deployment/wordpress'
|
27
|
+
autoload :Ruby, 'shuttle/deployment/ruby'
|
28
|
+
autoload :Rails, 'shuttle/deployment/rails'
|
29
|
+
autoload :Nodejs, 'shuttle/deployment/nodejs'
|
29
30
|
|
30
31
|
module Support
|
31
|
-
autoload :Bundler,
|
32
|
-
autoload :Foreman,
|
33
|
-
autoload :Thin,
|
32
|
+
autoload :Bundler, 'shuttle/support/bundler'
|
33
|
+
autoload :Foreman, 'shuttle/support/foreman'
|
34
|
+
autoload :Thin, 'shuttle/support/thin'
|
34
35
|
end
|
35
36
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shuttle-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0.
|
4
|
+
version: 0.2.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Sosedoff
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -184,13 +184,14 @@ files:
|
|
184
184
|
- lib/shuttle/deployment/wordpress/vip.rb
|
185
185
|
- lib/shuttle/errors.rb
|
186
186
|
- lib/shuttle/helpers.rb
|
187
|
+
- lib/shuttle/path_helpers.rb
|
187
188
|
- lib/shuttle/runner.rb
|
188
189
|
- lib/shuttle/session.rb
|
190
|
+
- lib/shuttle/strategy.rb
|
189
191
|
- lib/shuttle/support/bundler.rb
|
190
192
|
- lib/shuttle/support/foreman.rb
|
191
193
|
- lib/shuttle/support/thin.rb
|
192
194
|
- lib/shuttle/target.rb
|
193
|
-
- lib/shuttle/tasks.rb
|
194
195
|
- lib/shuttle/version.rb
|
195
196
|
- shuttle-deploy.gemspec
|
196
197
|
- spec/deploy_spec.rb
|