middleman-deploy 0.1.4 → 0.2.0
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 +4 -4
- data/README.md +54 -5
- data/USAGE +56 -0
- data/lib/middleman-deploy/commands.rb +29 -230
- data/lib/middleman-deploy/extension.rb +4 -3
- data/lib/middleman-deploy/methods.rb +5 -0
- data/lib/middleman-deploy/methods/base.rb +19 -0
- data/lib/middleman-deploy/methods/ftp.rb +102 -0
- data/lib/middleman-deploy/methods/git.rb +19 -0
- data/lib/middleman-deploy/methods/rsync.rb +38 -0
- data/lib/middleman-deploy/methods/sftp.rb +65 -0
- data/lib/middleman-deploy/pkg-info.rb +1 -1
- data/lib/middleman-deploy/strategies.rb +3 -0
- data/lib/middleman-deploy/strategies/git/base.rb +48 -0
- data/lib/middleman-deploy/strategies/git/force_push.rb +54 -0
- data/lib/middleman-deploy/strategies/git/submodule.rb +44 -0
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da79aac3ca5caa2323d02e0a26fcf478318df56d
|
4
|
+
data.tar.gz: 9782924347f997ec71632b730e7ccf8558226b05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: edba921810aa5506b74b9772e730def32db3671fd8cdd3e9843b31ba26577318bb78f736d3aeeb441402870c0c717c5b7a0207db1e8532a77697462adf8acfe2
|
7
|
+
data.tar.gz: 5d1c7d977bcf5e4cadc20596b42a67debf2c59fe50beeadaeb28234a6964f27257f815abf72f41476bf5b6a71a6a68c55c00ae33779bc9ea6455a2214ef39bbf
|
data/README.md
CHANGED
@@ -50,7 +50,7 @@ activate :deploy do |deploy|
|
|
50
50
|
# deploy.user = "tvaughan" # no default
|
51
51
|
# deploy.port = 5309 # ssh port, default: 22
|
52
52
|
# deploy.clean = true # remove orphaned files on remote host, default: false
|
53
|
-
# deploy.flags = "-rltgoDvzO --no-p --del
|
53
|
+
# deploy.flags = "-rltgoDvzO --no-p --del" # add custom flags, default: -avz
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
@@ -63,8 +63,9 @@ following to `config.rb`:
|
|
63
63
|
activate :deploy do |deploy|
|
64
64
|
deploy.method = :git
|
65
65
|
# Optional Settings
|
66
|
-
# deploy.remote
|
67
|
-
# deploy.branch
|
66
|
+
# deploy.remote = "custom-remote" # remote name or git url, default: origin
|
67
|
+
# deploy.branch = "custom-branch" # default: gh-pages
|
68
|
+
# deploy.strategy = :submodule # commit strategy: can be :force_push or :submodule, default: :force_push
|
68
69
|
end
|
69
70
|
```
|
70
71
|
|
@@ -72,8 +73,12 @@ If you use a remote name, you must first add it using `git remote add`. Run
|
|
72
73
|
`git remote -v` to see a list of possible remote names. If you use a git url,
|
73
74
|
it must end with '.git'.
|
74
75
|
|
75
|
-
Afterwards, the `build` directory will become a git repo.
|
76
|
-
|
76
|
+
Afterwards, the `build` directory will become a git repo.
|
77
|
+
|
78
|
+
If you use the force push strategy, this branch will be created on the remote if
|
79
|
+
it doesn't already exist.
|
80
|
+
But if you use the submodule strategy, you must first initialize build folder as
|
81
|
+
a submodule. See `git submodule add` documentation.
|
77
82
|
|
78
83
|
### FTP
|
79
84
|
|
@@ -97,6 +102,7 @@ Activate the extension by adding the following to `config.rb`:
|
|
97
102
|
activate :deploy do |deploy|
|
98
103
|
deploy.method = :sftp
|
99
104
|
deploy.host = "sftp.example.com"
|
105
|
+
deploy.port = 22
|
100
106
|
deploy.path = "/srv/www/site"
|
101
107
|
# Optional Settings
|
102
108
|
# deploy.user = "tvaughan" # no default
|
@@ -104,6 +110,49 @@ activate :deploy do |deploy|
|
|
104
110
|
end
|
105
111
|
```
|
106
112
|
|
113
|
+
### Multiple Environments
|
114
|
+
|
115
|
+
Deploy your site to more than one configuration using environment variables.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
# config.rb
|
119
|
+
case ENV['TARGET'].to_s.downcase
|
120
|
+
when 'production'
|
121
|
+
activate :deploy do |deploy|
|
122
|
+
deploy.method = :rsync
|
123
|
+
deploy.host = "www.example.com"
|
124
|
+
deploy.path = "/srv/www/production-site"
|
125
|
+
end
|
126
|
+
else
|
127
|
+
activate :deploy do |deploy|
|
128
|
+
deploy.method = :rsync
|
129
|
+
deploy.host = "staging.example.com"
|
130
|
+
deploy.path = "/srv/www/staging-site"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
```
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
# Rakefile
|
137
|
+
namespace :deploy do
|
138
|
+
def deploy(env)
|
139
|
+
puts "Deploying to #{env}"
|
140
|
+
exec "TARGET=#{env} bundle exec middleman deploy"
|
141
|
+
end
|
142
|
+
|
143
|
+
task :staging do
|
144
|
+
deploy :staging
|
145
|
+
end
|
146
|
+
|
147
|
+
task :production do
|
148
|
+
deploy :production
|
149
|
+
end
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
$ rake deploy:staging
|
154
|
+
$ rake deploy:production
|
155
|
+
|
107
156
|
## Breaking Changes
|
108
157
|
|
109
158
|
* `v0.1.0`
|
data/USAGE
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
You should follow one of the four examples below to setup the deploy
|
2
|
+
extension in config.rb.
|
3
|
+
|
4
|
+
# To deploy the build directory to a remote host via rsync:
|
5
|
+
activate :deploy do |deploy|
|
6
|
+
deploy.method = :rsync
|
7
|
+
# host and path *must* be set
|
8
|
+
deploy.host = "www.example.com"
|
9
|
+
deploy.path = "/srv/www/site"
|
10
|
+
# user is optional (no default)
|
11
|
+
deploy.user = "tvaughan"
|
12
|
+
# port is optional (default is 22)
|
13
|
+
deploy.port = 5309
|
14
|
+
# clean is optional (default is false)
|
15
|
+
deploy.clean = true
|
16
|
+
# flags is optional (default is -avze)
|
17
|
+
deploy.flags = "-rltgoDvzO --no-p --del -e"
|
18
|
+
end
|
19
|
+
|
20
|
+
# To deploy to a remote branch via git (e.g. gh-pages on github):
|
21
|
+
activate :deploy do |deploy|
|
22
|
+
deploy.method = :git
|
23
|
+
# remote is optional (default is "origin")
|
24
|
+
# run `git remote -v` to see a list of possible remotes
|
25
|
+
deploy.remote = "some-other-remote-name"
|
26
|
+
|
27
|
+
# branch is optional (default is "gh-pages")
|
28
|
+
# run `git branch -a` to see a list of possible branches
|
29
|
+
deploy.branch = "some-other-branch-name"
|
30
|
+
|
31
|
+
# strategy is optional (default is :force_push)
|
32
|
+
deploy.strategy = :submodule
|
33
|
+
end
|
34
|
+
|
35
|
+
# To deploy the build directory to a remote host via ftp:
|
36
|
+
activate :deploy do |deploy|
|
37
|
+
deploy.method = :ftp
|
38
|
+
# host, user, passwword and path *must* be set
|
39
|
+
deploy.host = "ftp.example.com"
|
40
|
+
deploy.path = "/srv/www/site"
|
41
|
+
deploy.user = "tvaughan"
|
42
|
+
deploy.password = "secret"
|
43
|
+
end
|
44
|
+
|
45
|
+
# To deploy the build directory to a remote host via sftp:
|
46
|
+
activate :deploy do |deploy|
|
47
|
+
deploy.method = :sftp
|
48
|
+
# host, user, passwword and path *must* be set
|
49
|
+
deploy.host = "sftp.example.com"
|
50
|
+
deploy.port = 22
|
51
|
+
deploy.path = "/srv/www/site"
|
52
|
+
# user is optional (no default)
|
53
|
+
deploy.user = "tvaughan"
|
54
|
+
# password is optional (no default)
|
55
|
+
deploy.password = "secret"
|
56
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require "middleman-core/cli"
|
2
2
|
|
3
3
|
require "middleman-deploy/extension"
|
4
|
+
require "middleman-deploy/methods"
|
5
|
+
require "middleman-deploy/strategies"
|
4
6
|
require "middleman-deploy/pkg-info"
|
5
7
|
|
6
8
|
module Middleman
|
@@ -21,274 +23,71 @@ module Middleman
|
|
21
23
|
|
22
24
|
desc "deploy [options]", Middleman::Deploy::TAGLINE
|
23
25
|
method_option "build_before",
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
:type => :boolean,
|
27
|
+
:aliases => "-b",
|
28
|
+
:desc => "Run `middleman build` before the deploy step"
|
28
29
|
def deploy
|
29
|
-
|
30
|
-
|
31
|
-
else
|
32
|
-
build_before = self.deploy_options.build_before
|
33
|
-
end
|
34
|
-
if build_before
|
35
|
-
# http://forum.middlemanapp.com/t/problem-with-the-build-task-in-an-extension
|
36
|
-
run("middleman build") || exit(1)
|
37
|
-
end
|
38
|
-
send("deploy_#{self.deploy_options.method}")
|
30
|
+
build_before(options)
|
31
|
+
process
|
39
32
|
end
|
40
33
|
|
41
34
|
protected
|
42
35
|
|
43
|
-
def
|
44
|
-
|
36
|
+
def build_before(options={})
|
37
|
+
build_enabled = options.fetch('build_before', self.deploy_options.build_before)
|
45
38
|
|
46
|
-
|
47
|
-
|
39
|
+
if build_enabled
|
40
|
+
# http://forum.middlemanapp.com/t/problem-with-the-build-task-in-an-extension
|
41
|
+
run('middleman build') || exit(1)
|
42
|
+
end
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# host and path *must* be set
|
53
|
-
deploy.host = "www.example.com"
|
54
|
-
deploy.path = "/srv/www/site"
|
55
|
-
# user is optional (no default)
|
56
|
-
deploy.user = "tvaughan"
|
57
|
-
# port is optional (default is 22)
|
58
|
-
deploy.port = 5309
|
59
|
-
# clean is optional (default is false)
|
60
|
-
deploy.clean = true
|
61
|
-
# flags is optional (default is -avze)
|
62
|
-
deploy.flags = "-rltgoDvzO --no-p --del -e"
|
63
|
-
end
|
45
|
+
def print_usage_and_die(message)
|
46
|
+
usage_path = File.join(File.dirname(__FILE__), '..', '..', 'USAGE')
|
47
|
+
usage_message = File.read(usage_path)
|
64
48
|
|
65
|
-
|
66
|
-
|
67
|
-
deploy.method = :git
|
68
|
-
# remote is optional (default is "origin")
|
69
|
-
# run `git remote -v` to see a list of possible remotes
|
70
|
-
deploy.remote = "some-other-remote-name"
|
71
|
-
# branch is optional (default is "gh-pages")
|
72
|
-
# run `git branch -a` to see a list of possible branches
|
73
|
-
deploy.branch = "some-other-branch-name"
|
74
|
-
end
|
49
|
+
raise Error, "ERROR: #{message}\n#{usage_message}"
|
50
|
+
end
|
75
51
|
|
76
|
-
|
77
|
-
|
78
|
-
deploy.method = :ftp
|
79
|
-
# host, user, passwword and path *must* be set
|
80
|
-
deploy.host = "ftp.example.com"
|
81
|
-
deploy.path = "/srv/www/site"
|
82
|
-
deploy.user = "tvaughan"
|
83
|
-
deploy.password = "secret"
|
84
|
-
end
|
52
|
+
def process
|
53
|
+
server_instance = ::Middleman::Application.server.inst
|
85
54
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
# host, user, passwword and path *must* be set
|
90
|
-
deploy.host = "sftp.example.com"
|
91
|
-
deploy.path = "/srv/www/site"
|
92
|
-
# user is optional (no default)
|
93
|
-
deploy.user = "tvaughan"
|
94
|
-
# password is optional (no default)
|
95
|
-
deploy.password = "secret"
|
96
|
-
end
|
97
|
-
EOF
|
98
|
-
end
|
55
|
+
camelized_method = self.deploy_options.method.to_s.split('_').map { |word| word.capitalize}.join
|
56
|
+
method_class_name = "Middleman::Deploy::Methods::#{camelized_method}"
|
57
|
+
method_instance = method_class_name.constantize.new(server_instance, self.deploy_options)
|
99
58
|
|
100
|
-
|
101
|
-
::Middleman::Application.server.inst
|
59
|
+
method_instance.process
|
102
60
|
end
|
103
61
|
|
104
62
|
def deploy_options
|
105
63
|
options = nil
|
106
64
|
|
107
65
|
begin
|
108
|
-
options = inst.options
|
66
|
+
options = ::Middleman::Application.server.inst.options
|
109
67
|
rescue NoMethodError
|
110
68
|
print_usage_and_die "You need to activate the deploy extension in config.rb."
|
111
69
|
end
|
112
70
|
|
113
|
-
|
71
|
+
unless options.method
|
114
72
|
print_usage_and_die "The deploy extension requires you to set a method."
|
115
73
|
end
|
116
74
|
|
117
75
|
case options.method
|
118
76
|
when :rsync, :sftp
|
119
|
-
|
77
|
+
unless options.host && options.path
|
120
78
|
print_usage_and_die "The #{options.method} method requires host and path to be set."
|
121
79
|
end
|
122
80
|
when :ftp
|
123
|
-
|
81
|
+
unless options.host && options.user && options.password && options.path
|
124
82
|
print_usage_and_die "The ftp deploy method requires host, path, user, and password to be set."
|
125
83
|
end
|
126
84
|
end
|
127
85
|
|
128
86
|
options
|
129
87
|
end
|
130
|
-
|
131
|
-
def deploy_rsync
|
132
|
-
host = self.deploy_options.host
|
133
|
-
port = self.deploy_options.port
|
134
|
-
path = self.deploy_options.path
|
135
|
-
|
136
|
-
# Append "@" to user if provided.
|
137
|
-
user = self.deploy_options.user
|
138
|
-
user = "#{user}@" if user && !user.empty?
|
139
|
-
|
140
|
-
dest_url = "#{user}#{host}:#{path}"
|
141
|
-
|
142
|
-
puts "## Deploying via rsync to #{dest_url} port=#{port}"
|
143
|
-
|
144
|
-
flags = !self.deploy_options.flags ? '-avze' : self.deploy_options.flags
|
145
|
-
|
146
|
-
command = "rsync " + flags + " '" + "ssh -p #{port}" + "' #{self.inst.build_dir}/ #{dest_url}"
|
147
|
-
|
148
|
-
if self.deploy_options.clean
|
149
|
-
command += " --delete"
|
150
|
-
end
|
151
|
-
|
152
|
-
run command
|
153
|
-
end
|
154
|
-
|
155
|
-
def deploy_git
|
156
|
-
remote = self.deploy_options.remote
|
157
|
-
branch = self.deploy_options.branch
|
158
|
-
|
159
|
-
puts "## Deploying via git to remote=\"#{remote}\" and branch=\"#{branch}\""
|
160
|
-
|
161
|
-
#check if remote is not a git url
|
162
|
-
unless remote =~ /\.git$/
|
163
|
-
remote = `git config --get remote.#{remote}.url`.chop
|
164
|
-
end
|
165
|
-
|
166
|
-
#if the remote name doesn't exist in the main repo
|
167
|
-
if remote == ''
|
168
|
-
puts "Can't deploy! Please add a remote with the name '#{self.deploy_options.remote}' to your repo."
|
169
|
-
exit
|
170
|
-
end
|
171
|
-
|
172
|
-
Dir.chdir(self.inst.build_dir) do
|
173
|
-
unless File.exists?('.git')
|
174
|
-
`git init`
|
175
|
-
`git remote add origin #{remote}`
|
176
|
-
else
|
177
|
-
#check if the remote repo has changed
|
178
|
-
unless remote == `git config --get remote.origin.url`.chop
|
179
|
-
`git remote rm origin`
|
180
|
-
`git remote add origin #{remote}`
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
#if there is a branch with that name, switch to it, otherwise create a new one and switch to it
|
185
|
-
if `git branch`.split("\n").any? { |b| b =~ /#{branch}/i }
|
186
|
-
`git checkout #{branch}`
|
187
|
-
else
|
188
|
-
`git checkout -b #{branch}`
|
189
|
-
end
|
190
|
-
|
191
|
-
`git add -A`
|
192
|
-
# '"message"' double quotes to fix windows issue
|
193
|
-
`git commit --allow-empty -am '"Automated commit at #{Time.now.utc} by #{Middleman::Deploy::PACKAGE} #{Middleman::Deploy::VERSION}"'`
|
194
|
-
`git push -f origin #{branch}`
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def deploy_ftp
|
199
|
-
require 'net/ftp'
|
200
|
-
require 'ptools'
|
201
|
-
|
202
|
-
host = self.deploy_options.host
|
203
|
-
user = self.deploy_options.user
|
204
|
-
pass = self.deploy_options.password
|
205
|
-
path = self.deploy_options.path
|
206
|
-
|
207
|
-
puts "## Deploying via ftp to #{user}@#{host}:#{path}"
|
208
|
-
|
209
|
-
ftp = Net::FTP.new(host)
|
210
|
-
ftp.login(user, pass)
|
211
|
-
ftp.chdir(path)
|
212
|
-
ftp.passive = true
|
213
|
-
|
214
|
-
Dir.chdir(self.inst.build_dir) do
|
215
|
-
files = Dir.glob('**/*', File::FNM_DOTMATCH)
|
216
|
-
files.reject { |a| a =~ Regexp.new('\.$') }.each do |f|
|
217
|
-
if File.directory?(f)
|
218
|
-
begin
|
219
|
-
ftp.mkdir(f)
|
220
|
-
puts "Created directory #{f}"
|
221
|
-
rescue
|
222
|
-
end
|
223
|
-
else
|
224
|
-
begin
|
225
|
-
if File.binary?(f)
|
226
|
-
ftp.putbinaryfile(f, f)
|
227
|
-
else
|
228
|
-
ftp.puttextfile(f, f)
|
229
|
-
end
|
230
|
-
rescue Exception => e
|
231
|
-
reply = e.message
|
232
|
-
err_code = reply[0,3].to_i
|
233
|
-
if err_code == 550
|
234
|
-
if File.binary?(f)
|
235
|
-
ftp.putbinaryfile(f, f)
|
236
|
-
else
|
237
|
-
ftp.puttextfile(f, f)
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
puts "Copied #{f}"
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
ftp.close
|
246
|
-
end
|
247
|
-
|
248
|
-
def deploy_sftp
|
249
|
-
require 'net/sftp'
|
250
|
-
require 'ptools'
|
251
|
-
|
252
|
-
host = self.deploy_options.host
|
253
|
-
user = self.deploy_options.user
|
254
|
-
pass = self.deploy_options.password
|
255
|
-
path = self.deploy_options.path
|
256
|
-
|
257
|
-
puts "## Deploying via sftp to #{user}@#{host}:#{path}"
|
258
|
-
|
259
|
-
# `nil` is a valid value for user and/or pass.
|
260
|
-
Net::SFTP.start(host, user, :password => pass) do |sftp|
|
261
|
-
sftp.mkdir(path)
|
262
|
-
Dir.chdir(self.inst.build_dir) do
|
263
|
-
files = Dir.glob('**/*', File::FNM_DOTMATCH)
|
264
|
-
files.reject { |a| a =~ Regexp.new('\.$') }.each do |f|
|
265
|
-
if File.directory?(f)
|
266
|
-
begin
|
267
|
-
sftp.mkdir("#{path}/#{f}")
|
268
|
-
puts "Created directory #{f}"
|
269
|
-
rescue
|
270
|
-
end
|
271
|
-
else
|
272
|
-
begin
|
273
|
-
sftp.upload(f, "#{path}/#{f}")
|
274
|
-
rescue Exception => e
|
275
|
-
reply = e.message
|
276
|
-
err_code = reply[0,3].to_i
|
277
|
-
if err_code == 550
|
278
|
-
sftp.upload(f, "#{path}/#{f}")
|
279
|
-
end
|
280
|
-
end
|
281
|
-
puts "Copied #{f}"
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
88
|
end
|
289
89
|
|
290
90
|
# Alias "d" to "deploy"
|
291
91
|
Base.map({ "d" => "deploy" })
|
292
|
-
|
293
92
|
end
|
294
93
|
end
|
@@ -5,7 +5,7 @@ require "middleman-core"
|
|
5
5
|
module Middleman
|
6
6
|
module Deploy
|
7
7
|
|
8
|
-
class Options < Struct.new(:whatisthis, :method, :host, :port, :user, :password, :path, :clean, :remote, :branch, :build_before, :flags); end
|
8
|
+
class Options < Struct.new(:whatisthis, :method, :host, :port, :user, :password, :path, :clean, :remote, :branch, :strategy, :build_before, :flags); end
|
9
9
|
|
10
10
|
class << self
|
11
11
|
|
@@ -22,8 +22,9 @@ module Middleman
|
|
22
22
|
options.clean ||= false
|
23
23
|
|
24
24
|
# Default options for the git method.
|
25
|
-
options.remote
|
26
|
-
options.branch
|
25
|
+
options.remote ||= "origin"
|
26
|
+
options.branch ||= "gh-pages"
|
27
|
+
options.strategy ||= :force_push
|
27
28
|
|
28
29
|
options.build_before ||= false
|
29
30
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Deploy
|
3
|
+
module Methods
|
4
|
+
class Base
|
5
|
+
attr_reader :options, :server_instance
|
6
|
+
|
7
|
+
def initialize(server_instance, options={})
|
8
|
+
@options = options
|
9
|
+
@server_instance = server_instance
|
10
|
+
end
|
11
|
+
|
12
|
+
def process
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'net/ftp'
|
2
|
+
require 'ptools'
|
3
|
+
|
4
|
+
module Middleman
|
5
|
+
module Deploy
|
6
|
+
module Methods
|
7
|
+
class Ftp < Base
|
8
|
+
|
9
|
+
attr_reader :host, :pass, :path,:user
|
10
|
+
|
11
|
+
def initialize(server_instance, options={})
|
12
|
+
super(server_instance, options)
|
13
|
+
|
14
|
+
@host = self.options.host
|
15
|
+
@user = self.options.user
|
16
|
+
@pass = self.options.password
|
17
|
+
@path = self.options.path
|
18
|
+
@port = self.options.port
|
19
|
+
end
|
20
|
+
|
21
|
+
def process
|
22
|
+
puts "## Deploying via ftp to #{self.user}@#{self.host}:#{self.path}"
|
23
|
+
|
24
|
+
ftp = open_connection
|
25
|
+
|
26
|
+
Dir.chdir(self.server_instance.build_dir) do
|
27
|
+
filtered_files.each do |filename|
|
28
|
+
if File.directory?(filename)
|
29
|
+
upload_directory(ftp, filename)
|
30
|
+
elsif File.binary?(filename)
|
31
|
+
upload_binary(ftp, filename)
|
32
|
+
else
|
33
|
+
upload_file(ftp, filename)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
ftp.close
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def filtered_files
|
44
|
+
files = Dir.glob('**/*', File::FNM_DOTMATCH)
|
45
|
+
|
46
|
+
files.reject { |filename| filename =~ Regexp.new('\.$') }
|
47
|
+
end
|
48
|
+
|
49
|
+
def handle_exception(exception, ftp, filename)
|
50
|
+
reply = exception.message
|
51
|
+
err_code = reply[0,3].to_i
|
52
|
+
|
53
|
+
if err_code == 550
|
54
|
+
if File.binary?(filename)
|
55
|
+
ftp.putbinaryfile(filename, filename)
|
56
|
+
else
|
57
|
+
ftp.puttextfile(filename, filename)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def open_connection
|
63
|
+
ftp = Net::FTP.new(self.host)
|
64
|
+
ftp.login(self.user, self.pass)
|
65
|
+
ftp.chdir(self.path)
|
66
|
+
ftp.passive = true
|
67
|
+
|
68
|
+
ftp
|
69
|
+
end
|
70
|
+
|
71
|
+
def upload_binary(ftp, filename)
|
72
|
+
begin
|
73
|
+
ftp.putbinaryfile(filename, filename)
|
74
|
+
rescue Exception => exception
|
75
|
+
handle_exception(exception, ftp, filename)
|
76
|
+
end
|
77
|
+
|
78
|
+
puts "Copied #{filename}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def upload_directory(ftp, filename)
|
82
|
+
begin
|
83
|
+
ftp.mkdir(filename)
|
84
|
+
puts "Created directory #{filename}"
|
85
|
+
rescue
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def upload_file(ftp, filename)
|
90
|
+
begin
|
91
|
+
ftp.puttextfile(filename, filename)
|
92
|
+
rescue Exception => exception
|
93
|
+
handle_exception(exception, ftp, filename)
|
94
|
+
end
|
95
|
+
|
96
|
+
puts "Copied #{filename}"
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Deploy
|
3
|
+
module Methods
|
4
|
+
class Git < Base
|
5
|
+
|
6
|
+
def process
|
7
|
+
puts "## Deploying via git to remote=\"#{self.options.remote}\" and branch=\"#{self.options.branch}\""
|
8
|
+
|
9
|
+
camelized_strategy = self.options.strategy.to_s.split('_').map { |word| word.capitalize}.join
|
10
|
+
strategy_class_name = "Middleman::Deploy::Strategies::Git::#{camelized_strategy}"
|
11
|
+
strategy_instance = strategy_class_name.constantize.new(self.server_instance.build_dir, self.options.remote, self.options.branch)
|
12
|
+
|
13
|
+
strategy_instance.process
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Deploy
|
3
|
+
module Methods
|
4
|
+
class Rsync < Base
|
5
|
+
|
6
|
+
attr_reader :clean, :flags, :host, :path, :port, :user
|
7
|
+
|
8
|
+
def initialize(server_instance, options={})
|
9
|
+
super(server_instance, options)
|
10
|
+
|
11
|
+
@clean = self.options.clean
|
12
|
+
@flags = self.options.flags
|
13
|
+
@host = self.options.host
|
14
|
+
@path = self.options.path
|
15
|
+
@port = self.options.port
|
16
|
+
@user = self.options.user
|
17
|
+
end
|
18
|
+
|
19
|
+
def process
|
20
|
+
# Append "@" to user if provided.
|
21
|
+
user = "#{self.user}@" if self.user && !self.user.empty?
|
22
|
+
|
23
|
+
dest_url = "#{user}#{self.host}:#{self.path}"
|
24
|
+
flags = self.flags || '-avz'
|
25
|
+
command = "rsync #{flags} '-e ssh -p #{self.port}' #{self.server_instance.build_dir}/ #{dest_url}"
|
26
|
+
|
27
|
+
if self.clean
|
28
|
+
command += " --delete"
|
29
|
+
end
|
30
|
+
|
31
|
+
puts "## Deploying via rsync to #{dest_url} port=#{self.port}"
|
32
|
+
run command
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'net/sftp'
|
2
|
+
require 'ptools'
|
3
|
+
|
4
|
+
module Middleman
|
5
|
+
module Deploy
|
6
|
+
module Methods
|
7
|
+
class Sftp < Ftp
|
8
|
+
|
9
|
+
def process
|
10
|
+
puts "## Deploying via sftp to #{self.user}@#{self.host}:#{path}"
|
11
|
+
|
12
|
+
# `nil` is a valid value for user and/or pass.
|
13
|
+
Net::SFTP.start(self.host, self.user, :password => self.pass, :port => self.port) do |sftp|
|
14
|
+
sftp.mkdir(self.path)
|
15
|
+
|
16
|
+
Dir.chdir(self.server_instance.build_dir) do
|
17
|
+
filtered_files.each do |filename|
|
18
|
+
if File.directory?(filename)
|
19
|
+
upload_directory(sftp, filename)
|
20
|
+
else
|
21
|
+
upload_file(sftp, filename)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def handle_exception(exception)
|
31
|
+
reply = exception.message
|
32
|
+
err_code = reply[0,3].to_i
|
33
|
+
|
34
|
+
if err_code == 550
|
35
|
+
sftp.upload(filename, file_path)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def upload_directory(sftp, filename)
|
40
|
+
file_path = "#{self.path}/#{filename}"
|
41
|
+
|
42
|
+
begin
|
43
|
+
sftp.mkdir(file_path)
|
44
|
+
puts "Created directory #{filename}"
|
45
|
+
rescue
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def upload_file(sftp, filename)
|
50
|
+
file_path = "#{self.path}/#{filename}"
|
51
|
+
|
52
|
+
begin
|
53
|
+
sftp.upload(filename, file_path)
|
54
|
+
rescue Exception => exception
|
55
|
+
handle_exception(exception, file_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "Copied #{filename}"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Deploy
|
3
|
+
module Strategies
|
4
|
+
module Git
|
5
|
+
class Base
|
6
|
+
attr_accessor :branch, :build_dir, :remote
|
7
|
+
|
8
|
+
def initialize(build_dir, remote, branch)
|
9
|
+
self.branch = branch
|
10
|
+
self.build_dir = build_dir
|
11
|
+
self.remote = remote
|
12
|
+
end
|
13
|
+
|
14
|
+
def process
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def add_signature_to_commit_message(base_message)
|
21
|
+
signature = "#{Middleman::Deploy::PACKAGE} #{Middleman::Deploy::VERSION}"
|
22
|
+
time = "#{Time.now.utc}"
|
23
|
+
|
24
|
+
"#{base_message} at #{time} by #{signature}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def checkout_branch
|
28
|
+
# if there is a branch with that name, switch to it, otherwise create a new one and switch to it
|
29
|
+
if `git branch`.split("\n").any? { |b| b =~ /#{self.branch}/i }
|
30
|
+
`git checkout #{self.branch}`
|
31
|
+
else
|
32
|
+
`git checkout -b #{self.branch}`
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def commit_branch(options='')
|
37
|
+
message = add_signature_to_commit_message('Automated commit')
|
38
|
+
|
39
|
+
`git add -A`
|
40
|
+
`git commit --allow-empty -am "#{message}"`
|
41
|
+
`git push #{options} origin #{self.branch}`
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Deploy
|
3
|
+
module Strategies
|
4
|
+
module Git
|
5
|
+
class ForcePush < Base
|
6
|
+
|
7
|
+
def process
|
8
|
+
Dir.chdir(self.build_dir) do
|
9
|
+
add_remote_url
|
10
|
+
checkout_branch
|
11
|
+
commit_branch('-f')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def add_remote_url
|
18
|
+
url = get_remote_url
|
19
|
+
|
20
|
+
unless File.exists?('.git')
|
21
|
+
`git init`
|
22
|
+
`git remote add origin #{url}`
|
23
|
+
else
|
24
|
+
# check if the remote repo has changed
|
25
|
+
unless url == `git config --get remote.origin.url`.chop
|
26
|
+
`git remote rm origin`
|
27
|
+
`git remote add origin #{url}`
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_remote_url
|
33
|
+
remote = self.remote
|
34
|
+
url = remote
|
35
|
+
|
36
|
+
# check if remote is not a git url
|
37
|
+
unless remote =~ /\.git$/
|
38
|
+
url = `git config --get remote.#{url}.url`.chop
|
39
|
+
end
|
40
|
+
|
41
|
+
# if the remote name doesn't exist in the main repo
|
42
|
+
if url == ''
|
43
|
+
puts "Can't deploy! Please add a remote with the name '#{remote}' to your repo."
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
|
47
|
+
url
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Deploy
|
3
|
+
module Strategies
|
4
|
+
module Git
|
5
|
+
class Submodule < Base
|
6
|
+
|
7
|
+
def process
|
8
|
+
Dir.chdir(self.build_dir) do
|
9
|
+
checkout_branch
|
10
|
+
pull_submodule
|
11
|
+
commit_branch
|
12
|
+
end
|
13
|
+
|
14
|
+
commit_submodule
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def commit_submodule
|
20
|
+
current_branch = `git rev-parse --abbrev-ref HEAD`
|
21
|
+
message = add_signature_to_commit_message('Deployed')
|
22
|
+
|
23
|
+
`git add #{self.build_dir}`
|
24
|
+
`git commit --allow-empty -m "#{message}"`
|
25
|
+
`git push origin #{current_branch}`
|
26
|
+
end
|
27
|
+
|
28
|
+
def pull_submodule
|
29
|
+
`git fetch`
|
30
|
+
`git stash`
|
31
|
+
`git rebase #{self.remote}/#{self.branch}`
|
32
|
+
`git stash pop`
|
33
|
+
|
34
|
+
if $?.exitstatus == 1
|
35
|
+
puts "Can't deploy! Please resolve conflicts. Then process to manual commit and push on #{self.branch} branch."
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Vaughan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: middleman-core
|
@@ -65,11 +65,22 @@ files:
|
|
65
65
|
- Gemfile
|
66
66
|
- README.md
|
67
67
|
- Rakefile
|
68
|
+
- USAGE
|
68
69
|
- features/support/env.rb
|
69
70
|
- lib/middleman-deploy.rb
|
70
71
|
- lib/middleman-deploy/commands.rb
|
71
72
|
- lib/middleman-deploy/extension.rb
|
73
|
+
- lib/middleman-deploy/methods.rb
|
74
|
+
- lib/middleman-deploy/methods/base.rb
|
75
|
+
- lib/middleman-deploy/methods/ftp.rb
|
76
|
+
- lib/middleman-deploy/methods/git.rb
|
77
|
+
- lib/middleman-deploy/methods/rsync.rb
|
78
|
+
- lib/middleman-deploy/methods/sftp.rb
|
72
79
|
- lib/middleman-deploy/pkg-info.rb
|
80
|
+
- lib/middleman-deploy/strategies.rb
|
81
|
+
- lib/middleman-deploy/strategies/git/base.rb
|
82
|
+
- lib/middleman-deploy/strategies/git/force_push.rb
|
83
|
+
- lib/middleman-deploy/strategies/git/submodule.rb
|
73
84
|
- lib/middleman_extension.rb
|
74
85
|
- middleman-deploy.gemspec
|
75
86
|
homepage: http://github.com/tvaughan/middleman-deploy
|