dpl-releases 1.9.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44e70cc91d21e963c4aeb3f8e1db0bea45fae7b8
4
+ data.tar.gz: 933d5352e2199ee2cc1659d830aee46e5e85f651
5
+ SHA512:
6
+ metadata.gz: e967a9c342b0fab62d6ac5d1587885ec2d6c5b45fbc7204f18582c5d607076e1a52ecec595d15efc71f811189559a47b57aa5d579782980d3f69a3d856c4f0d4
7
+ data.tar.gz: 1fe1bb7d81f066a76baceb071b1b2f52c81c1cee051ae26304314d7df6e10405fd4da53fbaddf6e9862842a5be830f55fabd7312526993d080d72d47b74adc81
@@ -0,0 +1,3 @@
1
+ require './gemspec_helper'
2
+
3
+ gemspec_for 'releases', [['octokit', '~> 4.6.2'], ['mime-types', '~> 2.0']]
@@ -0,0 +1,134 @@
1
+ require 'octokit'
2
+ require 'mime-types'
3
+
4
+ module DPL
5
+ class Provider
6
+ class Releases < Provider
7
+ require 'pathname'
8
+
9
+ def travis_tag
10
+ # Check if $TRAVIS_TAG is unset or set but empty
11
+ if context.env.fetch('TRAVIS_TAG','') == ''
12
+ nil
13
+ else
14
+ context.env['TRAVIS_TAG']
15
+ end
16
+ end
17
+
18
+ def get_tag
19
+ if travis_tag.nil?
20
+ @tag ||= `git describe --tags --exact-match 2>/dev/null`.chomp
21
+ else
22
+ @tag ||= travis_tag
23
+ end
24
+ end
25
+
26
+ def api
27
+ if options[:user] and options[:password]
28
+ @api ||= Octokit::Client.new(:login => options[:user], :password => options[:password])
29
+ else
30
+ @api ||= Octokit::Client.new(:access_token => option(:api_key))
31
+ end
32
+ end
33
+
34
+ def slug
35
+ options.fetch(:repo) { context.env['TRAVIS_REPO_SLUG'] }
36
+ end
37
+
38
+ def releases
39
+ @releases ||= api.releases(slug)
40
+ end
41
+
42
+ def user
43
+ @user ||= api.user
44
+ end
45
+
46
+ def files
47
+ if options[:file_glob]
48
+ Array(options[:file]).map do |glob|
49
+ Dir.glob(glob)
50
+ end.flatten
51
+ else
52
+ Array(options[:file])
53
+ end
54
+ end
55
+
56
+ def needs_key?
57
+ false
58
+ end
59
+
60
+ def check_app
61
+ log "Deploying to repo: #{slug}"
62
+
63
+ context.shell 'git fetch --tags' if travis_tag.nil?
64
+ log "Current tag is: #{get_tag}"
65
+ end
66
+
67
+ def setup_auth
68
+ user.login
69
+ end
70
+
71
+ def check_auth
72
+ setup_auth
73
+
74
+ unless api.scopes.include? 'public_repo' or api.scopes.include? 'repo'
75
+ raise Error, "Dpl does not have permission to upload assets. Make sure your token contains the repo or public_repo scope."
76
+ end
77
+
78
+ log "Logged in as #{user.name}"
79
+ end
80
+
81
+ def push_app
82
+ tag_matched = false
83
+ release_url = nil
84
+
85
+ if options[:release_number]
86
+ tag_matched = true
87
+ release_url = "https://api.github.com/repos/" + slug + "/releases/" + options[:release_number]
88
+ else
89
+ releases.each do |release|
90
+ if release.tag_name == get_tag
91
+ release_url = release.rels[:self].href
92
+ tag_matched = true
93
+ end
94
+ end
95
+ end
96
+
97
+ #If for some reason GitHub hasn't already created a release for the tag, create one
98
+ if tag_matched == false
99
+ release_url = api.create_release(slug, get_tag, options.merge({:draft => true})).rels[:self].href
100
+ end
101
+
102
+ files.each do |file|
103
+ existing_url = nil
104
+ filename = Pathname.new(file).basename.to_s
105
+ api.release(release_url).rels[:assets].get.data.each do |existing_file|
106
+ if existing_file.name == filename
107
+ existing_url = existing_file.url
108
+ end
109
+ end
110
+ if !existing_url
111
+ upload_file(file, filename, release_url)
112
+ elsif existing_url && options[:overwrite]
113
+ log "#{filename} already exists, overwriting."
114
+ api.delete_release_asset(existing_url)
115
+ upload_file(file, filename, release_url)
116
+ else
117
+ log "#{filename} already exists, skipping."
118
+ end
119
+ end
120
+
121
+ api.update_release(release_url, {:draft => false}.merge(options))
122
+ end
123
+
124
+ def upload_file(file, filename, release_url)
125
+ content_type = MIME::Types.type_for(file).first.to_s
126
+ if content_type.empty?
127
+ # Specify the default content type, as it is required by GitHub
128
+ content_type = "application/octet-stream"
129
+ end
130
+ api.upload_asset(release_url, file, {:name => filename, :content_type => content_type})
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,303 @@
1
+ require 'spec_helper'
2
+ require 'dpl/provider/releases'
3
+ require 'octokit'
4
+
5
+ describe DPL::Provider::Releases do
6
+ subject :provider do
7
+ described_class.new(DummyContext.new, :api_key => '0123445789qwertyuiop0123445789qwertyuiop', :file => 'blah.txt')
8
+ end
9
+
10
+ describe "#travis_tag" do
11
+ example "When $TRAVIS_TAG is nil" do
12
+ provider.context.env['TRAVIS_TAG'] = nil
13
+
14
+ expect(provider.travis_tag).to eq(nil)
15
+ end
16
+
17
+ example "When $TRAVIS_TAG if set but empty" do
18
+ provider.context.env['TRAVIS_TAG'] = nil
19
+
20
+ expect(provider.travis_tag).to eq(nil)
21
+ end
22
+
23
+ example "When $TRAVIS_TAG if set" do
24
+ provider.context.env['TRAVIS_TAG'] = "foo"
25
+
26
+ expect(provider.travis_tag).to eq("foo")
27
+ end
28
+ end
29
+
30
+ describe "#api" do
31
+ example "With API key" do
32
+ api = double(:api)
33
+ expect(::Octokit::Client).to receive(:new).with(:access_token => '0123445789qwertyuiop0123445789qwertyuiop').and_return(api)
34
+ expect(provider.api).to eq(api)
35
+ end
36
+
37
+ example "With username and password" do
38
+ api = double(:api)
39
+ provider.options.update(:user => 'foo')
40
+ provider.options.update(:password => 'bar')
41
+
42
+ expect(::Octokit::Client).to receive(:new).with(:login => 'foo', :password => 'bar').and_return(api)
43
+ expect(provider.api).to eq(api)
44
+ end
45
+ end
46
+
47
+ describe "#releases" do
48
+ example "With ENV Slug" do
49
+ allow(provider).to receive(:slug).and_return("foo/bar")
50
+
51
+ expect(provider.api).to receive(:releases).with("foo/bar")
52
+ provider.releases
53
+ end
54
+
55
+ example "With repo option" do
56
+ provider.options.update(:repo => 'bar/foo')
57
+
58
+ expect(provider.api).to receive(:releases).with('bar/foo')
59
+ provider.releases
60
+ end
61
+ end
62
+
63
+ describe "#files" do
64
+ example "without file globbing and a single file" do
65
+ expect(provider.files).to eq(['blah.txt'])
66
+ end
67
+
68
+ example "without file globbing and multiple files" do
69
+ provider.options.update(:file => ['foo.txt', 'bar.txt'])
70
+ expect(provider.files).to eq(['foo.txt', 'bar.txt'])
71
+ end
72
+
73
+ example "with file globbing and a single glob" do
74
+ provider.options.update(:file_glob => true)
75
+ provider.options.update(:file => 'bl*.txt')
76
+ expect(::Dir).to receive(:glob).with('bl*.txt').and_return(['blah.txt'])
77
+ expect(provider.files).to eq(['blah.txt'])
78
+ end
79
+
80
+ example "with file globbing and multiple globs" do
81
+ provider.options.update(:file_glob => true)
82
+ provider.options.update(:file => ['f*.txt', 'b*.txt'])
83
+ expect(::Dir).to receive(:glob).with('f*.txt').and_return(['foo.txt'])
84
+ expect(::Dir).to receive(:glob).with('b*.txt').and_return(['bar.txt'])
85
+ expect(provider.files).to eq(['foo.txt', 'bar.txt'])
86
+ end
87
+ end
88
+
89
+ describe "#needs_key?" do
90
+ example do
91
+ expect(provider.needs_key?).to eq(false)
92
+ end
93
+ end
94
+
95
+ describe "#check_app" do
96
+ example "Without $TRAVIS_TAG" do
97
+ allow(provider).to receive(:travis_tag).and_return(nil)
98
+ allow(provider).to receive(:slug).and_return("foo/bar")
99
+ allow(provider).to receive(:get_tag).and_return("foo")
100
+
101
+ expect(provider.context).to receive(:shell).with("git fetch --tags")
102
+ expect(provider).to receive(:log).with("Deploying to repo: foo/bar")
103
+ expect(provider).to receive(:log).with("Current tag is: foo")
104
+
105
+ provider.check_app
106
+ end
107
+
108
+ example "With $TRAVIS_TAG" do
109
+ allow(provider).to receive(:travis_tag).and_return("bar")
110
+ allow(provider).to receive(:slug).and_return("foo/bar")
111
+
112
+ expect(provider.context).not_to receive(:shell).with("git fetch --tags")
113
+ expect(provider).to receive(:log).with("Deploying to repo: foo/bar")
114
+ expect(provider).to receive(:log).with("Current tag is: bar")
115
+
116
+ provider.check_app
117
+ end
118
+ end
119
+
120
+ describe "#get_tag" do
121
+ example "Without $TRAVIS_TAG" do
122
+ allow(provider).to receive(:travis_tag).and_return(nil)
123
+ allow(provider).to receive(:`).and_return("bar")
124
+
125
+ expect(provider.get_tag).to eq("bar")
126
+ end
127
+
128
+ example "With $TRAVIS_TAG" do
129
+ allow(provider).to receive(:travis_tag).and_return("foo")
130
+
131
+ expect(provider.get_tag).to eq("foo")
132
+ end
133
+ end
134
+
135
+ describe "#check_auth" do
136
+ example "With proper permissions" do
137
+ allow_message_expectations_on_nil
138
+ allow(provider).to receive(:user)
139
+ allow(provider).to receive(:setup_auth)
140
+ expect(provider.api).to receive(:scopes).and_return(["public_repo"])
141
+ expect(provider.user).to receive(:name).and_return("foo")
142
+ expect(provider).to receive(:log).with("Logged in as foo")
143
+ provider.check_auth
144
+ end
145
+
146
+ example "With improper permissions" do
147
+ allow_message_expectations_on_nil
148
+ allow(provider).to receive(:user)
149
+ allow(provider).to receive(:setup_auth)
150
+ expect(provider.api).to receive(:scopes).exactly(2).times.and_return([])
151
+ expect { provider.check_auth }.to raise_error(DPL::Error)
152
+ end
153
+ end
154
+
155
+ describe "#push_app" do
156
+ example "When Release Exists but has no Files" do
157
+ allow_message_expectations_on_nil
158
+
159
+ provider.options.update(:file => ["test/foo.bar", "bar.txt"])
160
+
161
+ allow(provider).to receive(:releases).and_return([""])
162
+ allow(provider).to receive(:get_tag).and_return("v0.0.0")
163
+
164
+ provider.releases.map do |release|
165
+ allow(release).to receive(:tag_name).and_return("v0.0.0")
166
+ allow(release).to receive(:rels).and_return({:self => nil})
167
+ allow(release.rels[:self]).to receive(:href)
168
+ end
169
+
170
+ allow(provider.api).to receive(:release)
171
+ allow(provider.api.release).to receive(:rels).and_return({:assets => nil})
172
+ allow(provider.api.release.rels[:assets]).to receive(:get).and_return({:data => [""]})
173
+ allow(provider.api.release.rels[:assets].get).to receive(:data).and_return([])
174
+
175
+ expect(provider.api).to receive(:upload_asset).with(anything, "test/foo.bar", {:name=>"foo.bar", :content_type=>"application/octet-stream"})
176
+ expect(provider.api).to receive(:upload_asset).with(anything, "bar.txt", {:name=>"bar.txt", :content_type=>"text/plain"})
177
+ expect(provider.api).to receive(:update_release).with(anything, hash_including(:draft => false))
178
+
179
+ provider.push_app
180
+ end
181
+
182
+ example "When Release Exists and has Files" do
183
+ allow_message_expectations_on_nil
184
+
185
+ provider.options.update(:file => ["test/foo.bar", "bar.txt"])
186
+
187
+ allow(provider).to receive(:releases).and_return([""])
188
+ allow(provider).to receive(:get_tag).and_return("v0.0.0")
189
+
190
+ provider.releases.map do |release|
191
+ allow(release).to receive(:tag_name).and_return("v0.0.0")
192
+ allow(release).to receive(:rels).and_return({:self => nil})
193
+ allow(release.rels[:self]).to receive(:href)
194
+ end
195
+
196
+ allow(provider.api).to receive(:release)
197
+ allow(provider.api.release).to receive(:rels).and_return({:assets => nil})
198
+ allow(provider.api.release.rels[:assets]).to receive(:get).and_return({:data => [""]})
199
+ allow(provider.api.release.rels[:assets].get).to receive(:data).and_return([double(:name => "foo.bar", :url => 'foo-bar-url'), double(:name => "foo.foo", :url => 'foo-foo-url')])
200
+
201
+ expect(provider.api).to receive(:upload_asset).with(anything, "bar.txt", {:name=>"bar.txt", :content_type=>"text/plain"})
202
+ expect(provider).to receive(:log).with("foo.bar already exists, skipping.")
203
+ expect(provider.api).to receive(:update_release).with(anything, hash_including(:draft => false))
204
+
205
+ provider.push_app
206
+ end
207
+
208
+ example "When Release Exists and has Files but overwrite flag is true" do
209
+ allow_message_expectations_on_nil
210
+
211
+ provider.options.update(:file => ["exists.txt"])
212
+ provider.options.update(:overwrite => true)
213
+
214
+ allow(provider).to receive(:releases).and_return([""])
215
+ allow(provider).to receive(:get_tag).and_return("v0.0.0")
216
+
217
+ provider.releases.map do |release|
218
+ allow(release).to receive(:tag_name).and_return("v0.0.0")
219
+ allow(release).to receive(:rels).and_return({:self => nil})
220
+ allow(release.rels[:self]).to receive(:href)
221
+ end
222
+
223
+ allow(provider.api).to receive(:release)
224
+ allow(provider.api.release).to receive(:rels).and_return({:assets => nil})
225
+ allow(provider.api.release.rels[:assets]).to receive(:get).and_return({:data => [""]})
226
+ allow(provider.api.release.rels[:assets].get).to receive(:data).and_return([double(:name => "exists.txt", :url => "release-url")])
227
+
228
+ expect(provider.api).to receive(:delete_release_asset).with("release-url").and_return(true)
229
+ expect(provider.api).to receive(:upload_asset).with(anything, "exists.txt", {:name=>"exists.txt", :content_type=>"text/plain"})
230
+ expect(provider.api).to receive(:update_release).with(anything, hash_including(:draft => false))
231
+
232
+ provider.push_app
233
+ end
234
+
235
+ example "When Release Doesn't Exist" do
236
+ allow_message_expectations_on_nil
237
+
238
+ provider.options.update(:file => ["test/foo.bar", "bar.txt"])
239
+
240
+ allow(provider).to receive(:releases).and_return([""])
241
+
242
+ provider.releases.map do |release|
243
+ allow(release).to receive(:tag_name).and_return("foo")
244
+ allow(release).to receive(:rels).and_return({:self => nil})
245
+ allow(release.rels[:self]).to receive(:href)
246
+ end
247
+
248
+ allow(provider.api).to receive(:create_release)
249
+ allow(provider.api.create_release).to receive(:rels).and_return({:self => nil})
250
+ allow(provider.api.create_release.rels[:slef]).to receive(:href)
251
+
252
+ allow(provider.api).to receive(:release)
253
+ allow(provider.api.release).to receive(:rels).and_return({:assets => nil})
254
+ allow(provider.api.release.rels[:assets]).to receive(:get).and_return({:data => nil})
255
+ allow(provider.api.release.rels[:assets].get).to receive(:data).and_return([])
256
+
257
+ expect(provider.api).to receive(:upload_asset).with(anything, "test/foo.bar", {:name=>"foo.bar", :content_type=>"application/octet-stream"})
258
+ expect(provider.api).to receive(:upload_asset).with(anything, "bar.txt", {:name=>"bar.txt", :content_type=>"text/plain"})
259
+ expect(provider.api).to receive(:update_release).with(anything, hash_including(:draft => false))
260
+
261
+ provider.push_app
262
+ end
263
+
264
+ example "With Release Number" do
265
+ allow_message_expectations_on_nil
266
+
267
+ provider.options.update(:file => ["bar.txt"])
268
+ provider.options.update(:release_number => "1234")
269
+
270
+ allow(provider).to receive(:slug).and_return("foo/bar")
271
+
272
+ allow(provider.api).to receive(:release)
273
+ allow(provider.api.release).to receive(:rels).and_return({:assets => nil})
274
+ allow(provider.api.release.rels[:assets]).to receive(:get).and_return({:data => nil})
275
+ allow(provider.api.release.rels[:assets].get).to receive(:data).and_return([])
276
+
277
+ expect(provider.api).to receive(:upload_asset).with("https://api.github.com/repos/foo/bar/releases/1234", "bar.txt", {:name=>"bar.txt", :content_type=>"text/plain"})
278
+ expect(provider.api).to receive(:update_release).with(anything, hash_including(:draft => false))
279
+
280
+ provider.push_app
281
+ end
282
+
283
+ example "When draft is true" do
284
+ allow_message_expectations_on_nil
285
+
286
+ provider.options.update(:file => ["bar.txt"])
287
+ provider.options.update(:release_number => "1234")
288
+ provider.options.update(:draft => true)
289
+
290
+ allow(provider).to receive(:slug).and_return("foo/bar")
291
+
292
+ allow(provider.api).to receive(:release)
293
+ allow(provider.api.release).to receive(:rels).and_return({:assets => nil})
294
+ allow(provider.api.release.rels[:assets]).to receive(:get).and_return({:data => nil})
295
+ allow(provider.api.release.rels[:assets].get).to receive(:data).and_return([])
296
+
297
+ expect(provider.api).to receive(:upload_asset).with("https://api.github.com/repos/foo/bar/releases/1234", "bar.txt", {:name=>"bar.txt", :content_type=>"text/plain"})
298
+ expect(provider.api).to receive(:update_release).with(anything, hash_including(:draft => true))
299
+
300
+ provider.push_app
301
+ end
302
+ end
303
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dpl-releases
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Haase
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dpl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.9.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.9.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: octokit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 4.6.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 4.6.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: mime-types
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-its
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: json_pure
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tins
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: coveralls
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: highline
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: deploy tool abstraction for clients
154
+ email: konstantin.mailinglists@googlemail.com
155
+ executables: []
156
+ extensions: []
157
+ extra_rdoc_files: []
158
+ files:
159
+ - dpl-releases.gemspec
160
+ - lib/dpl/provider/releases.rb
161
+ - spec/provider/releases_spec.rb
162
+ homepage: https://github.com/travis-ci/dpl
163
+ licenses:
164
+ - MIT
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '2.2'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 2.6.13
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: deploy tool
186
+ test_files:
187
+ - spec/provider/releases_spec.rb