fulmar 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -0
- data/lib/fulmar/domain/model/application.rb +8 -8
- data/lib/fulmar/domain/model/configuration.rb +4 -4
- data/lib/fulmar/domain/service/config_test_service.rb +2 -2
- data/lib/fulmar/domain/service/config_tests/hosts.rb +3 -3
- data/lib/fulmar/domain/service/config_tests/misc.rb +1 -2
- data/lib/fulmar/domain/service/config_tests/paths.rb +2 -2
- data/lib/fulmar/domain/service/config_tests/project.rb +6 -3
- data/lib/fulmar/domain/service/file_sync_service.rb +1 -1
- data/lib/fulmar/domain/service/helper/common_helper.rb +1 -1
- data/lib/fulmar/domain/service/plugin_service.rb +2 -2
- data/lib/fulmar/domain/service/template_rendering_service.rb +2 -2
- data/lib/fulmar/infrastructure/model/transfer/base.rb +4 -4
- data/lib/fulmar/infrastructure/model/transfer/rsync.rb +1 -1
- data/lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb +26 -19
- data/lib/fulmar/infrastructure/service/ssh_config_service.rb +9 -15
- data/lib/fulmar/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a8c600aba68edc3253bda3a138e56d76b38a283
|
4
|
+
data.tar.gz: 82c43b52167c6b2b478bf75b25a28697d72316d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2738a4ead46f2ea844230efb8466d78c97150396eac1f1f7d74f7064c60f2e2532b69cf724b6212e247094fc839652397cf5575605af24acb893dc1ca387b1ef
|
7
|
+
data.tar.gz: 8295d787803f53c9e6d470ae1d4259f576f5bd20abdefc2e327cd3ca76c7faa4813d531301ef1f34e11b3b6151b2254d1d92cadffb2c697b5805252a3a313e84
|
data/README.md
CHANGED
@@ -292,6 +292,34 @@ before calling file_sync.publish to create the symlink (current => releases/2015
|
|
292
292
|
As you probably figured out, your webserver uses the "current" symlink to get the base directory of your web
|
293
293
|
application. Here, you would point it to /tmp/current/public or something like that.
|
294
294
|
|
295
|
+
### Custom versioning
|
296
|
+
|
297
|
+
When deploying via Gitlab CI, the current branch or tag is available in the environment variable `CI_COMMIT_REF_NAME`. You very likely want to use tags here and set something like
|
298
|
+
|
299
|
+
```yaml
|
300
|
+
only:
|
301
|
+
- /^live_\d+\.\d+.\d+/
|
302
|
+
```
|
303
|
+
|
304
|
+
in your .gitlab-ci.yaml. This way, whenever you tag something with e.g. "live_1.2.0" and push it, a deployment will trigger. Fulmar can be configured to read the content of an environment variable and use that as
|
305
|
+
the version name. So you can add `version_name` to your config and set it to the gitlab env variable:
|
306
|
+
|
307
|
+
```yaml
|
308
|
+
environments:
|
309
|
+
all:
|
310
|
+
local_path: .
|
311
|
+
my_server:
|
312
|
+
files:
|
313
|
+
hostname: my-ssh-server
|
314
|
+
remote_path: /tmp
|
315
|
+
type: rsync_with_versions
|
316
|
+
shared:
|
317
|
+
- data
|
318
|
+
version_name: CI_COMMIT_REF_NAME
|
319
|
+
```
|
320
|
+
|
321
|
+
This way, fulmar will call the release "live_1.2.0" instead of the current timestamp.
|
322
|
+
|
295
323
|
### Configuration templates
|
296
324
|
|
297
325
|
Sometimes you need different versions of files on your different environments. An exmaple might be the .htaccess file.
|
@@ -8,7 +8,7 @@ module Fulmar
|
|
8
8
|
class Application < Rake::Application
|
9
9
|
def initialize
|
10
10
|
super
|
11
|
-
@rakefiles = %w
|
11
|
+
@rakefiles = %w[fulmarfile Fulmarfile fulmarfile.rb Fulmarfile.rb]
|
12
12
|
end
|
13
13
|
|
14
14
|
def name
|
@@ -71,13 +71,13 @@ module Fulmar
|
|
71
71
|
end
|
72
72
|
]
|
73
73
|
options << [
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
'--debug',
|
75
|
+
nil,
|
76
|
+
'Run in debug mode.',
|
77
|
+
lambda do |_value|
|
78
|
+
configuration = Fulmar::Domain::Service::ConfigurationService.instance
|
79
|
+
configuration.debug = true
|
80
|
+
end
|
81
81
|
]
|
82
82
|
options
|
83
83
|
end
|
@@ -29,8 +29,8 @@ module Fulmar
|
|
29
29
|
if ready?
|
30
30
|
@data[:environments][@environment][@target][id] = value
|
31
31
|
else
|
32
|
-
|
33
|
-
|
32
|
+
raise 'Environment or target not set. Please set both variables via configuration.environment = \'xxx\' / '\
|
33
|
+
'configuration.target = \'yyy\''
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -50,8 +50,8 @@ module Fulmar
|
|
50
50
|
# Checks if environment and target are set
|
51
51
|
def ready?
|
52
52
|
return false if @environment.nil? || @target.nil?
|
53
|
-
|
54
|
-
|
53
|
+
raise 'Environment is invalid' if @data[:environments][@environment].nil?
|
54
|
+
raise 'Target is invalid' if @data[:environments][@environment][@target].nil?
|
55
55
|
true
|
56
56
|
end
|
57
57
|
|
@@ -14,11 +14,11 @@ module Fulmar
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def target_test(name, &block)
|
17
|
-
@tests[name] =
|
17
|
+
@tests[name] = proc do
|
18
18
|
results = []
|
19
19
|
@config.each do |env, target, _data|
|
20
20
|
@config.set env, target
|
21
|
-
result =
|
21
|
+
result = yield(@config)
|
22
22
|
if result
|
23
23
|
result[:message] = "in [#{env}:#{target}]: #{result[:message]}"
|
24
24
|
results << result
|
@@ -2,7 +2,7 @@ target_test 'hostname is set' do |config|
|
|
2
2
|
if config[:hostname].blank? && !config[:host].blank?
|
3
3
|
next {
|
4
4
|
severity: :warning,
|
5
|
-
message: "config has a host (#{[:host]}) but is missing a hostname"
|
5
|
+
message: "config has a host (#{config[:host]}) but is missing a hostname"
|
6
6
|
}
|
7
7
|
end
|
8
8
|
end
|
@@ -16,8 +16,8 @@ target_test 'hostnames in ssh config' do |config|
|
|
16
16
|
end
|
17
17
|
|
18
18
|
target_test 'required hostnames' do |config|
|
19
|
-
types = %i
|
19
|
+
types = %i[rsync rsync_with_version maria]
|
20
20
|
if types.include?(config[:type]) && config[:hostname].blank?
|
21
|
-
next {severity: :error, message: "config requires a hostname (#{config[:hostname]})"}
|
21
|
+
next { severity: :error, message: "config requires a hostname (#{config[:hostname]})" }
|
22
22
|
end
|
23
23
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
relevant_options = [
|
2
|
-
:ssh_config, :type]
|
1
|
+
relevant_options = %i[rsync local_path remote_path host hostname shared templates ssh_config type]
|
3
2
|
relevant_options.each do |option|
|
4
3
|
target_test "empty configuration settings #{option}" do |config|
|
5
4
|
if config.key?(option) && config[option].nil?
|
@@ -8,8 +8,8 @@ target_test 'local path exists' do |config|
|
|
8
8
|
end
|
9
9
|
|
10
10
|
target_test 'remote_path is set' do |config|
|
11
|
-
types = %w
|
11
|
+
types = %w[rsync rsync_with_version]
|
12
12
|
if types.include?(config[:type]) && config[:remote_path].blank?
|
13
|
-
next {severity: :error, message: 'config is missing a remote path for rsync'}
|
13
|
+
next { severity: :error, message: 'config is missing a remote path for rsync' }
|
14
14
|
end
|
15
15
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
global_test 'project name is set' do |config|
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
if config.project.name.blank?
|
3
|
+
next {
|
4
|
+
severity: :warning,
|
5
|
+
message: 'Project name is not set (must be short, no spaces)'
|
6
|
+
}
|
7
|
+
end
|
5
8
|
end
|
@@ -17,7 +17,7 @@ module Fulmar
|
|
17
17
|
else
|
18
18
|
help = config[:type] == '' ? 'Add a "type: " field to your deployment yaml file. ' : ''
|
19
19
|
transfer_model = nil
|
20
|
-
|
20
|
+
raise "Transfer type '#{config[:type]}' is not valid. #{help}Valid values are: rsync, rsync_with_versions."
|
21
21
|
end
|
22
22
|
|
23
23
|
transfer_model
|
@@ -58,7 +58,7 @@ module Fulmar
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def storage
|
61
|
-
|
61
|
+
raise 'You need to set an environment and a target first' unless config.ready?
|
62
62
|
@storage ||= {}
|
63
63
|
@storage[config.environment] ||= {}
|
64
64
|
@storage[config.environment][config.target] ||= {}
|
@@ -17,8 +17,8 @@ module Fulmar
|
|
17
17
|
config = ConfigurationService.instance.configuration
|
18
18
|
|
19
19
|
if config.plugins.class == Array
|
20
|
-
|
21
|
-
|
20
|
+
raise 'Plugin list must not be an array. Have a look at https://github.com/CORE4/fulmar#plugins for ' +
|
21
|
+
'more information'
|
22
22
|
end
|
23
23
|
|
24
24
|
config.plugins.each_pair do |name, plugin_config|
|
@@ -22,8 +22,8 @@ module Fulmar
|
|
22
22
|
|
23
23
|
def template_path(template_file)
|
24
24
|
template = "#{@config[:local_path]}/#{template_file}"
|
25
|
-
|
26
|
-
|
25
|
+
raise "Template filenames must end in .erb - '#{template}' does not" unless template[-4, 4] == '.erb'
|
26
|
+
raise "Cannot render missing config file '#{template}'" unless File.exist? template
|
27
27
|
template
|
28
28
|
end
|
29
29
|
end
|
@@ -13,7 +13,7 @@ module Fulmar
|
|
13
13
|
remote_path: nil,
|
14
14
|
local_path: '.',
|
15
15
|
type: :rsync_with_versions
|
16
|
-
}
|
16
|
+
}.freeze
|
17
17
|
|
18
18
|
attr_accessor :config
|
19
19
|
|
@@ -31,9 +31,9 @@ module Fulmar
|
|
31
31
|
|
32
32
|
# Test the supplied config for required parameters
|
33
33
|
def test_config
|
34
|
-
required = [
|
35
|
-
required.each { |key|
|
36
|
-
|
34
|
+
required = %i[host remote_path local_path]
|
35
|
+
required.each { |key| raise "Configuration is missing required setting '#{key}'." if @config.blank? }
|
36
|
+
raise ':remote_path must be absolute' if @config[:remote_path][0, 1] != '/'
|
37
37
|
end
|
38
38
|
|
39
39
|
def prepare
|
@@ -27,7 +27,7 @@ module Fulmar
|
|
27
27
|
@config[:rsync][:exclude_file] = @config[:local_path] + '/.rsyncignore'
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
raise 'Hostname not set. Cannot initialize sync.' if @config[:hostname].nil? || @config[:hostname].empty?
|
31
31
|
|
32
32
|
super(@config)
|
33
33
|
end
|
@@ -12,8 +12,8 @@ module Fulmar
|
|
12
12
|
# Every deployment results in a new directory in the releases directory with the deployment time as
|
13
13
|
# the folder name. A symlink 'current' points to this new directory after publish() is called.
|
14
14
|
class RsyncWithVersions < Base
|
15
|
-
TIME_FOLDER = '%Y-%m-%d_%H%M%S'
|
16
|
-
TIME_READABLE = '%Y-%m-%d %H:%M:%S'
|
15
|
+
TIME_FOLDER = '%Y-%m-%d_%H%M%S'.freeze
|
16
|
+
TIME_READABLE = '%Y-%m-%d %H:%M:%S'.freeze
|
17
17
|
|
18
18
|
DEFAULT_CONFIG = {
|
19
19
|
temp_dir: 'temp',
|
@@ -28,8 +28,9 @@ module Fulmar
|
|
28
28
|
},
|
29
29
|
symlinks: {},
|
30
30
|
limit_releases: 5,
|
31
|
+
version_name: Time.now.strftime('%Y-%m-%d_%H%M%S'),
|
31
32
|
shared: []
|
32
|
-
}
|
33
|
+
}.freeze
|
33
34
|
|
34
35
|
# @param [Fulmar::Domain::Service::ConfigurationService] config
|
35
36
|
def initialize(config)
|
@@ -40,8 +41,6 @@ module Fulmar
|
|
40
41
|
if @config[:rsync][:exclude_file].blank? && File.exist?(@config[:local_path] + '/.rsyncignore')
|
41
42
|
@config[:rsync][:exclude_file] = @config[:local_path] + '/.rsyncignore'
|
42
43
|
end
|
43
|
-
|
44
|
-
@release_time = Time.now
|
45
44
|
end
|
46
45
|
|
47
46
|
# Ensures all needed services are set up
|
@@ -49,6 +48,10 @@ module Fulmar
|
|
49
48
|
super
|
50
49
|
@remote_shell = Fulmar::Shell.new @config[:remote_path], @config.ssh_user_and_host
|
51
50
|
@remote_shell.debug = @config[:debug]
|
51
|
+
|
52
|
+
if /^[A-Z][A-Z0-9\-_]+$/ =~ @config[:version_name]
|
53
|
+
@config[:version_name] = ENV[@config[:version_name]].split('/').last
|
54
|
+
end
|
52
55
|
end
|
53
56
|
|
54
57
|
# Copy the files via rsync to the release_path on the remote machine
|
@@ -56,10 +59,10 @@ module Fulmar
|
|
56
59
|
def transfer
|
57
60
|
prepare unless @prepared
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
raise 'Deployment failed when trying to prepare remote directories for sync.' unless create_paths
|
63
|
+
raise 'Deployment failed. Cannot sync files.' unless @local_shell.run(rsync_command)
|
64
|
+
raise 'Deployment failed when trying to move file from temporary upload dir.' unless copy_temp_to_release
|
65
|
+
raise 'Deployment failed when creating symlinks for shared folders' unless add_shared
|
63
66
|
end
|
64
67
|
|
65
68
|
# Publishes the current release (i.e. sets the 'current' symlink)
|
@@ -78,7 +81,7 @@ module Fulmar
|
|
78
81
|
# Gets the currently generated release directory
|
79
82
|
# @return [String] the release directory
|
80
83
|
def release_dir
|
81
|
-
@config[:releases_dir] + '/' + @
|
84
|
+
@config[:releases_dir] + '/' + @config[:version_name]
|
82
85
|
end
|
83
86
|
|
84
87
|
# Lists the existing releases on the remote machine
|
@@ -86,13 +89,17 @@ module Fulmar
|
|
86
89
|
# @return [Array] list of dirs or dates/times
|
87
90
|
def list_releases(plain = true)
|
88
91
|
prepare unless @prepared
|
89
|
-
@remote_shell.run "ls -
|
90
|
-
list = @remote_shell.last_output
|
92
|
+
@remote_shell.run "ls -1tr '#{@config[:releases_dir]}'"
|
93
|
+
list = @remote_shell.last_output
|
91
94
|
return list if plain
|
92
95
|
|
93
96
|
current = current_release
|
94
97
|
list.collect do |item|
|
95
|
-
|
98
|
+
if item =~ /^\d{4}-\d{2}-\d{2}_\d{6}/
|
99
|
+
Time.strptime(item, TIME_FOLDER).strftime(TIME_READABLE) + (item == current ? ' *' : '')
|
100
|
+
else
|
101
|
+
item + (item == current ? ' *' : '')
|
102
|
+
end
|
96
103
|
end
|
97
104
|
end
|
98
105
|
|
@@ -101,7 +108,7 @@ module Fulmar
|
|
101
108
|
def cleanup
|
102
109
|
limit = @config[:limit_releases].to_i
|
103
110
|
return true unless limit > 0
|
104
|
-
releases = list_releases
|
111
|
+
releases = list_releases
|
105
112
|
return true if releases.length <= limit
|
106
113
|
obsolete_dirs = releases[0, releases.length - limit].collect { |dir| "\"#{@config[:releases_dir]}/#{dir}\"" }
|
107
114
|
@remote_shell.run "rm -fr #{obsolete_dirs.join(' ')}"
|
@@ -124,7 +131,7 @@ module Fulmar
|
|
124
131
|
return false if release.nil?
|
125
132
|
|
126
133
|
# Convenience: Allow more readable version string from output
|
127
|
-
if release
|
134
|
+
if release =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/
|
128
135
|
release = Time.strptime(item, TIME_READABLE).strftime(TIME_FOLDER)
|
129
136
|
end
|
130
137
|
|
@@ -136,15 +143,15 @@ module Fulmar
|
|
136
143
|
def last_release
|
137
144
|
list = list_releases
|
138
145
|
current = current_release
|
139
|
-
current_index = list.index(current)
|
140
|
-
|
146
|
+
current_index = list.index(current).to_i
|
147
|
+
current_index.zero? ? nil : list[current_index - 1]
|
141
148
|
end
|
142
149
|
|
143
150
|
# Creates all necessary paths on the remote machine
|
144
151
|
# @return [true, false] success
|
145
152
|
def create_paths
|
146
153
|
paths = [@config[:releases_dir], @config[:temp_dir], @config[:shared_dir]]
|
147
|
-
@remote_shell.run
|
154
|
+
@remote_shell.run(paths.collect { |path| "mkdir -p '#{@config[:remote_path]}/#{path}'" })
|
148
155
|
end
|
149
156
|
|
150
157
|
def rsync_excludes
|
@@ -156,7 +163,7 @@ module Fulmar
|
|
156
163
|
# Builds the rsync command
|
157
164
|
# @return [String] the command
|
158
165
|
def rsync_command
|
159
|
-
options = %w
|
166
|
+
options = %w[-rl --delete-excluded]
|
160
167
|
options << rsync_excludes if rsync_excludes
|
161
168
|
options << "--exclude-from='#{@config[:rsync][:exclude_file]}'" if @config[:rsync][:exclude_file]
|
162
169
|
options << "--chown='#{@config[:rsync][:chown]}'" if @config[:rsync][:chown]
|
@@ -8,8 +8,8 @@ module Fulmar
|
|
8
8
|
module Service
|
9
9
|
# Adds entries to the ssh config and checks for existing ones
|
10
10
|
class SSHConfigService
|
11
|
-
DEFAULT_CONFIG_FILE = "#{ENV['HOME']}/.ssh/config"
|
12
|
-
DEFAULT_KNOWN_HOSTS_FILE = "#{ENV['HOME']}/.ssh/known_hosts"
|
11
|
+
DEFAULT_CONFIG_FILE = "#{ENV['HOME']}/.ssh/config".freeze
|
12
|
+
DEFAULT_KNOWN_HOSTS_FILE = "#{ENV['HOME']}/.ssh/known_hosts".freeze
|
13
13
|
|
14
14
|
attr_accessor :config_file, :known_host_file, :quiet
|
15
15
|
|
@@ -55,7 +55,7 @@ module Fulmar
|
|
55
55
|
input_file = File.open(@known_hosts_file, 'r')
|
56
56
|
output_file = File.open(@known_hosts_file + '.temp', 'w')
|
57
57
|
while (line = input_file.gets)
|
58
|
-
output_file.puts(line) unless /^\[?#{hostname.gsub('.', '\\.')}(?:\]:\d+)?[ ,]
|
58
|
+
output_file.puts(line) unless /^\[?#{hostname.gsub('.', '\\.')}(?:\]:\d+)?[ ,]/ =~ line
|
59
59
|
end
|
60
60
|
input_file.close
|
61
61
|
output_file.close
|
@@ -77,7 +77,7 @@ module Fulmar
|
|
77
77
|
def host_exists?(hostname)
|
78
78
|
config_file = File.open(@config_file, 'r')
|
79
79
|
while (line = config_file.gets)
|
80
|
-
if /\s*Host #{hostname.gsub('.', '\\.')}\s
|
80
|
+
if /\s*Host #{hostname.gsub('.', '\\.')}\s*$/ =~ line
|
81
81
|
config_file.close
|
82
82
|
return true
|
83
83
|
end
|
@@ -91,7 +91,7 @@ module Fulmar
|
|
91
91
|
puts "Adding host #{hostname}..." if @config[:debug]
|
92
92
|
config_file = File.open(@config_file, 'a')
|
93
93
|
|
94
|
-
unless ssh_config[:IdentityFile].blank?
|
94
|
+
unless ssh_config[:IdentityFile].blank? || ssh_config[:IdentityFile][0, 1] == '/'
|
95
95
|
ssh_config[:IdentityFile] = @config.base_path + '/' + ssh_config[:IdentityFile]
|
96
96
|
end
|
97
97
|
|
@@ -108,7 +108,7 @@ module Fulmar
|
|
108
108
|
protected
|
109
109
|
|
110
110
|
def host_entry(hostname, ssh_config = {})
|
111
|
-
unless ssh_config[:IdentityFile].blank?
|
111
|
+
unless ssh_config[:IdentityFile].blank? || ssh_config[:IdentityFile][0, 1] == '/'
|
112
112
|
ssh_config[:IdentityFile] = @config.base_path + '/' + ssh_config[:IdentityFile]
|
113
113
|
end
|
114
114
|
|
@@ -142,9 +142,7 @@ module Fulmar
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def remove_trailing_newlines(data)
|
145
|
-
while !data.empty? && data.last.strip.empty?
|
146
|
-
data.pop
|
147
|
-
end
|
145
|
+
data.pop while !data.empty? && data.last.strip.empty?
|
148
146
|
data
|
149
147
|
end
|
150
148
|
|
@@ -155,9 +153,7 @@ module Fulmar
|
|
155
153
|
if line.strip[0] == '#'
|
156
154
|
cache << line
|
157
155
|
else
|
158
|
-
if /^Host\s#{hostname}
|
159
|
-
return remove_trailing_newlines(before)
|
160
|
-
end
|
156
|
+
return remove_trailing_newlines(before) if /^Host\s#{hostname}$/ =~ line.strip
|
161
157
|
before += cache
|
162
158
|
cache = []
|
163
159
|
before << line
|
@@ -178,9 +174,7 @@ module Fulmar
|
|
178
174
|
if line.strip[0] == '#'
|
179
175
|
cache << line
|
180
176
|
else
|
181
|
-
if /^Host\s
|
182
|
-
write = true
|
183
|
-
end
|
177
|
+
write = true if /^Host\s/ =~ line.strip
|
184
178
|
if write
|
185
179
|
after += cache
|
186
180
|
after << line
|
data/lib/fulmar/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fulmar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Siegl
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-09-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
181
|
version: '0'
|
182
182
|
requirements: []
|
183
183
|
rubyforge_project:
|
184
|
-
rubygems_version: 2.6.
|
184
|
+
rubygems_version: 2.6.13
|
185
185
|
signing_key:
|
186
186
|
specification_version: 4
|
187
187
|
summary: A deployment task manager.
|