jenkins_api_client 1.0.1 → 1.1.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/CHANGELOG.md +21 -1
- data/README.md +87 -5
- data/jenkins_api_client.gemspec +8 -3
- data/lib/jenkins_api_client.rb +12 -0
- data/lib/jenkins_api_client/build_queue.rb +1 -1
- data/lib/jenkins_api_client/client.rb +24 -5
- data/lib/jenkins_api_client/job.rb +50 -8
- data/lib/jenkins_api_client/plugin_settings/base.rb +11 -0
- data/lib/jenkins_api_client/plugin_settings/collection.rb +39 -0
- data/lib/jenkins_api_client/plugin_settings/hipchat.rb +53 -0
- data/lib/jenkins_api_client/version.rb +2 -2
- data/spec/unit_tests/fake_http_response.rb +1 -1
- data/spec/unit_tests/job_spec.rb +47 -7
- data/spec/unit_tests/plugin_settings/colllection_spec.rb +62 -0
- data/spec/unit_tests/plugin_settings/hipchat_spec.rb +44 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4bc7855c7d74b4542c7a98175b2319f92c5b667
|
4
|
+
data.tar.gz: 6ab8636c67ef0e24a747ebcc413547138ba0b3e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83a8e6835f8ba2c6de4b151b95a8ccc3f798abe0a808d4b448fd7e1ef16239f6b2ee7eedc0a89eeeba9e6866b7c92aac007e98e7599fb4f1417188948b4cf83a
|
7
|
+
data.tar.gz: c1e08e48ad162f2d7e9ae1d647cb96b24655d2f7bbe7f77527416e6eb8d4095d3199e3589cc214af7016c8f869a378e6b6f45cbd1d11ea502a23b9284563aa75
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,16 @@ CHANGELOG
|
|
4
4
|
upcoming
|
5
5
|
--------
|
6
6
|
|
7
|
+
v1.1.0 [05-NOV-2014]
|
8
|
+
----------------------
|
9
|
+
* [#145][] Fix `BuildQueue#get_details` to compare against task_name. Credit: [@notruthless][]
|
10
|
+
* [#149][] Lower log level of GET/POST messages emitted by Client to DEBUG. Credit: [@scotje][]
|
11
|
+
* [#151][] Add ability to configure credentialId for git. Credit: [@hubert][]
|
12
|
+
* [#153][] Feature/extract plugins. Credit: [@hubert][]
|
13
|
+
* [#147][] Added ability to get current build artifact. Credit: [@joelneubert][]
|
14
|
+
* [#148][] Make `Client::Job#build` only request current build number if `build_start_timeout` option is passed.
|
15
|
+
Credit: [@scotje][]
|
16
|
+
|
7
17
|
v1.0.1 [16-JUL-2014]
|
8
18
|
----------------------
|
9
19
|
* Add `charset=UTF-8` along with content_type when posting data to Jenkins.
|
@@ -269,6 +279,12 @@ v0.0.1 [15-OCT-2012]
|
|
269
279
|
[#136]: https://github.com/arangamani/jenkins_api_client/issues/136
|
270
280
|
[#140]: https://github.com/arangamani/jenkins_api_client/issues/140
|
271
281
|
[#141]: https://github.com/arangamani/jenkins_api_client/issues/141
|
282
|
+
[#145]: https://github.com/arangamani/jenkins_api_client/issues/145
|
283
|
+
[#147]: https://github.com/arangamani/jenkins_api_client/issues/147
|
284
|
+
[#148]: https://github.com/arangamani/jenkins_api_client/issues/148
|
285
|
+
[#149]: https://github.com/arangamani/jenkins_api_client/issues/149
|
286
|
+
[#151]: https://github.com/arangamani/jenkins_api_client/issues/151
|
287
|
+
[#153]: https://github.com/arangamani/jenkins_api_client/issues/153
|
272
288
|
[@Loa]: https://github.com/Loa
|
273
289
|
[@Niarfe]: https://github.com/Niarfe
|
274
290
|
[@bobbrez]: https://github.com/bobbrez
|
@@ -281,15 +297,19 @@ v0.0.1 [15-OCT-2012]
|
|
281
297
|
[@dkerwin]: https://github.com/dkerwin
|
282
298
|
[@dougforpres]: https://github.com/dougforpres
|
283
299
|
[@drnic]: https://github.com/drnic
|
300
|
+
[@hubert]: https://github.com/hubert
|
301
|
+
[@joelneubert]: https://github.com/joelneubert
|
284
302
|
[@kevinhcross]: https://github.com/kevinhcross
|
285
303
|
[@lheinlen-os]: https://github.com/lheinlen-os
|
286
304
|
[@madisp]: https://github.com/madisp
|
287
305
|
[@mattrose]: https://github.com/mattrose
|
288
306
|
[@missedone]: https://github.com/missedone
|
289
307
|
[@n-rodriguez]: https://github.com/n-rodriguez
|
308
|
+
[@notruthless]: https://github.com/notruthless
|
290
309
|
[@riywo]: https://github.com/riywo
|
291
310
|
[@rubytester]: https://github.com/rubytester
|
311
|
+
[@scotje]: https://github.com/scotje
|
292
312
|
[@spikegrobstein]: https://github.com/spikegrobstein
|
293
313
|
[@sunaot]: https://github.com/sunaot
|
294
314
|
[@tjhanley]: https://github.com/tjhanley
|
295
|
-
[@woodbusy]: https://github.com/woodbusy
|
315
|
+
[@woodbusy]: https://github.com/woodbusy
|
data/README.md
CHANGED
@@ -107,7 +107,7 @@ The following example passes the YAML file contents. An example yaml file is
|
|
107
107
|
located in <tt>config/login.yml.example</tt>.
|
108
108
|
|
109
109
|
```ruby
|
110
|
-
@client = JenkinsApi::Client.new(YAML.
|
110
|
+
@client = JenkinsApi::Client.new(YAML.load_file(File.expand_path(
|
111
111
|
"~/.jenkins_api_client/login.yml", __FILE__)))
|
112
112
|
# The following call lists all jobs
|
113
113
|
puts @client.job.list_all
|
@@ -138,10 +138,11 @@ jobs = @client.job.list(jobs_to_filter)
|
|
138
138
|
initial_jobs = @client.job.chain(jobs, 'success', ["all"])
|
139
139
|
|
140
140
|
# Now that we have the initial job(s) we can build them
|
141
|
-
# The build function returns a code from the API which should be
|
142
|
-
# the build was successful
|
141
|
+
# The build function returns a code from the API which should be 201 if
|
142
|
+
# the build was successful, for Jenkins >= v1.519
|
143
|
+
# For versions older than v1.519, the success code is 302.
|
143
144
|
code = @client.job.build(initial_jobs[0])
|
144
|
-
raise "Could not build the job specified" unless code ==
|
145
|
+
raise "Could not build the job specified" unless code == '201'
|
145
146
|
```
|
146
147
|
|
147
148
|
In the above example, you might have noticed that the chain method returns an
|
@@ -179,10 +180,90 @@ initial_jobs = @client.job.chain(jobs, 'failure', ["failure", "unstable"], 3)
|
|
179
180
|
# We will receive three jobs as a result and we can build them all
|
180
181
|
initial_jobs.each do |job|
|
181
182
|
code = @client.job.build(job)
|
182
|
-
raise "Unable to build job: #{job}" unless code ==
|
183
|
+
raise "Unable to build job: #{job}" unless code == '201'
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
### Configuring plugins
|
188
|
+
|
189
|
+
Given the abundance of plugins for Jenkins, we now provide a extensible way to
|
190
|
+
setup jobs and configure their plugins. Right now, the gem ships with the hipchat
|
191
|
+
plugin, with more plugins to follow in the future.
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
hipchat_settings = JenkinsApi::Client::PluginSettings::Hipchat.new({
|
195
|
+
:room => '10000',
|
196
|
+
:start_notification => true,
|
197
|
+
:notify_success => true,
|
198
|
+
:notify_aborted => true,
|
199
|
+
:notify_not_built => true,
|
200
|
+
:notify_unstable => true,
|
201
|
+
:notify_failure => true,
|
202
|
+
:notify_back_to_normal => true,
|
203
|
+
})
|
204
|
+
|
205
|
+
client = JenkinsApi::Client.new(
|
206
|
+
server_url: jenkins_server,
|
207
|
+
username: username,
|
208
|
+
password: password
|
209
|
+
)
|
210
|
+
|
211
|
+
# NOTE: plugins can be splatted so if you had another plugin it could be passed
|
212
|
+
# to the new call below as another arg after hipchat
|
213
|
+
job = JenkinsApi::Client::Job.new(client, hipchat)
|
214
|
+
|
215
|
+
```
|
216
|
+
|
217
|
+
Writing your own plugins is also straightforward. Inherit from the
|
218
|
+
JenkinsApi::Client::PluginSettings::Base class and override the configure method.
|
219
|
+
Jenkins jobs are configured using xml so you just nee to figure out where in the
|
220
|
+
configuration to hook in your plugin settings.
|
221
|
+
|
222
|
+
Here is an example of a plugin written to configure a job for workspace cleanup.
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
module JenkinsApi
|
226
|
+
class Client
|
227
|
+
module PluginSettings
|
228
|
+
class WorkspaceCleanup < Base
|
229
|
+
|
230
|
+
# @option params [Boolean] :delete_dirs (false)
|
231
|
+
# whether to also apply pattern on directories
|
232
|
+
# @option params [String] :cleanup_parameters
|
233
|
+
# @option params [String] :external_delete
|
234
|
+
def initialize(params={})
|
235
|
+
@params = params
|
236
|
+
end
|
237
|
+
|
238
|
+
# Create or Update a job with params given as a hash instead of the xml
|
239
|
+
# This gives some flexibility for creating/updating simple jobs so the
|
240
|
+
# user doesn't have to learn about handling xml.
|
241
|
+
#
|
242
|
+
# @param xml_doc [Nokogiri::XML::Document] xml document to be updated with
|
243
|
+
# the plugin configuration
|
244
|
+
#
|
245
|
+
# @return [Nokogiri::XML::Document]
|
246
|
+
def configure(xml_doc)
|
247
|
+
xml_doc.tap do |doc|
|
248
|
+
Nokogiri::XML::Builder.with(doc.at('buildWrappers')) do |build_wrappers|
|
249
|
+
build_wrappers.send('hudson.plugins.ws__cleanup.PreBuildCleanup') do |x|
|
250
|
+
x.deleteDirs @params.fetch(:delete_dirs) { false }
|
251
|
+
x.cleanupParameter @params.fetch(:cleanup_parameter) { '' }
|
252
|
+
x.externalDelete @params.fetch(:external_delete) { '' }
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
183
260
|
end
|
184
261
|
```
|
185
262
|
|
263
|
+
Currently, the skype plugin is still configured directly on the jenkins job. This will
|
264
|
+
likely be extracted into its own plugin in the near future, but we will maintain
|
265
|
+
backwards compatibility until after an official deprecation period.
|
266
|
+
|
186
267
|
### Waiting for a build to start/Getting the build number
|
187
268
|
Newer versions of Jenkins (starting with the 1.519 build) make it easier for
|
188
269
|
an application to determine the build number for a 'build' request. (previously
|
@@ -208,6 +289,7 @@ caveats:
|
|
208
289
|
##### New (v >= 1.519)
|
209
290
|
* All options work, and build number is accurately determined from queue
|
210
291
|
info.
|
292
|
+
* The build trigger success code is now 201 (Created). Previously it was 302.
|
211
293
|
|
212
294
|
#### Initiating a build and returning the build_number
|
213
295
|
|
data/jenkins_api_client.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: jenkins_api_client 1.0
|
5
|
+
# stub: jenkins_api_client 1.1.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "jenkins_api_client"
|
9
|
-
s.version = "1.0
|
9
|
+
s.version = "1.1.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Kannan Manickam"]
|
14
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-11-05"
|
15
15
|
s.description = "\nThis is a simple and easy-to-use Jenkins Api client with features focused on\nautomating Job configuration programaticaly and so forth"
|
16
16
|
s.email = ["arangamani.kannan@gmail.com"]
|
17
17
|
s.executables = ["jenkinscli"]
|
@@ -43,6 +43,9 @@ Gem::Specification.new do |s|
|
|
43
43
|
"lib/jenkins_api_client/job.rb",
|
44
44
|
"lib/jenkins_api_client/node.rb",
|
45
45
|
"lib/jenkins_api_client/plugin_manager.rb",
|
46
|
+
"lib/jenkins_api_client/plugin_settings/base.rb",
|
47
|
+
"lib/jenkins_api_client/plugin_settings/collection.rb",
|
48
|
+
"lib/jenkins_api_client/plugin_settings/hipchat.rb",
|
46
49
|
"lib/jenkins_api_client/system.rb",
|
47
50
|
"lib/jenkins_api_client/urihelper.rb",
|
48
51
|
"lib/jenkins_api_client/user.rb",
|
@@ -68,6 +71,8 @@ Gem::Specification.new do |s|
|
|
68
71
|
"spec/unit_tests/fixtures/files/updatable_plugins.json",
|
69
72
|
"spec/unit_tests/job_spec.rb",
|
70
73
|
"spec/unit_tests/node_spec.rb",
|
74
|
+
"spec/unit_tests/plugin_settings/colllection_spec.rb",
|
75
|
+
"spec/unit_tests/plugin_settings/hipchat_spec.rb",
|
71
76
|
"spec/unit_tests/plugin_spec.rb",
|
72
77
|
"spec/unit_tests/spec_helper.rb",
|
73
78
|
"spec/unit_tests/system_spec.rb",
|
data/lib/jenkins_api_client.rb
CHANGED
@@ -36,3 +36,15 @@ require 'jenkins_api_client/cli/base'
|
|
36
36
|
require 'jenkins_api_client/cli/job'
|
37
37
|
require 'jenkins_api_client/cli/node'
|
38
38
|
require 'jenkins_api_client/cli/system'
|
39
|
+
|
40
|
+
module JenkinsApi
|
41
|
+
class Client
|
42
|
+
module PluginSettings
|
43
|
+
class InvalidType < Exception; end
|
44
|
+
|
45
|
+
autoload :Base, 'jenkins_api_client/plugin_settings/base'
|
46
|
+
autoload :Hipchat, 'jenkins_api_client/plugin_settings/hipchat'
|
47
|
+
autoload :Collection, 'jenkins_api_client/plugin_settings/collection'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -249,6 +249,25 @@ module JenkinsApi
|
|
249
249
|
" @http_read_timeout=#{@http_read_timeout.inspect}>"
|
250
250
|
end
|
251
251
|
|
252
|
+
# Connects to the server and downloads artifacts to a specified location
|
253
|
+
#
|
254
|
+
# @param [String] job_name
|
255
|
+
# @param [String] filename location to save artifact
|
256
|
+
#
|
257
|
+
def get_artifact(job_name,filename)
|
258
|
+
@artifact = job.find_artifact(job_name)
|
259
|
+
uri = URI.parse(@artifact)
|
260
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
261
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
262
|
+
http.use_ssl = true
|
263
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
264
|
+
request.basic_auth(@username, @password)
|
265
|
+
response = http.request(request)
|
266
|
+
File.write(File.expand_path(filename), response.body) if response.code == "200"
|
267
|
+
rescue
|
268
|
+
raise "Response was not 200"
|
269
|
+
end
|
270
|
+
|
252
271
|
# Connects to the Jenkins server, sends the specified request and returns
|
253
272
|
# the response.
|
254
273
|
#
|
@@ -303,7 +322,7 @@ module JenkinsApi
|
|
303
322
|
# @return [Net::HTTP::Response] Response from Jenkins for "/"
|
304
323
|
#
|
305
324
|
def get_root
|
306
|
-
@logger.
|
325
|
+
@logger.debug "GET #{@jenkins_path}/"
|
307
326
|
request = Net::HTTP::Get.new("#{@jenkins_path}/")
|
308
327
|
make_http_request(request)
|
309
328
|
end
|
@@ -328,7 +347,7 @@ module JenkinsApi
|
|
328
347
|
to_get = "#{url_prefix}#{url_suffix}"
|
329
348
|
end
|
330
349
|
request = Net::HTTP::Get.new(to_get)
|
331
|
-
@logger.
|
350
|
+
@logger.debug "GET #{to_get}"
|
332
351
|
response = make_http_request(request)
|
333
352
|
if raw_response
|
334
353
|
handle_exception(response, "raw")
|
@@ -352,7 +371,7 @@ module JenkinsApi
|
|
352
371
|
# Added form_data default {} instead of nil to help with proxies
|
353
372
|
# that barf with empty post
|
354
373
|
request = Net::HTTP::Post.new("#{@jenkins_path}#{url_prefix}")
|
355
|
-
@logger.
|
374
|
+
@logger.debug "POST #{url_prefix}"
|
356
375
|
if @crumbs_enabled
|
357
376
|
request[@crumb["crumbRequestField"]] = @crumb["crumb"]
|
358
377
|
end
|
@@ -390,7 +409,7 @@ module JenkinsApi
|
|
390
409
|
#
|
391
410
|
def get_config(url_prefix)
|
392
411
|
request = Net::HTTP::Get.new("#{@jenkins_path}#{url_prefix}/config.xml")
|
393
|
-
@logger.
|
412
|
+
@logger.debug "GET #{url_prefix}/config.xml"
|
394
413
|
response = make_http_request(request)
|
395
414
|
handle_exception(response, "body")
|
396
415
|
end
|
@@ -416,7 +435,7 @@ module JenkinsApi
|
|
416
435
|
refresh_crumbs
|
417
436
|
|
418
437
|
request = Net::HTTP::Post.new("#{@jenkins_path}#{url_prefix}")
|
419
|
-
@logger.
|
438
|
+
@logger.debug "POST #{url_prefix}"
|
420
439
|
request.body = data
|
421
440
|
request.content_type = content_type
|
422
441
|
if @crumbs_enabled
|
@@ -33,15 +33,36 @@ module JenkinsApi
|
|
33
33
|
# Version that jenkins started to include queued build info in build response
|
34
34
|
JENKINS_QUEUE_ID_SUPPORT_VERSION = '1.519'
|
35
35
|
|
36
|
+
attr_reader :plugin_collection
|
37
|
+
|
36
38
|
# Initialize the Job object and store the reference to Client object
|
37
39
|
#
|
38
40
|
# @param client [Client] the client object
|
39
41
|
#
|
40
42
|
# @return [Job] the job object
|
41
43
|
#
|
42
|
-
def initialize(client)
|
44
|
+
def initialize(client, *plugin_settings)
|
43
45
|
@client = client
|
44
46
|
@logger = @client.logger
|
47
|
+
@plugin_collection = JenkinsApi::Client::PluginSettings::Collection.new(*plugin_settings)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Add a plugin to be included in job's xml configureation
|
51
|
+
#
|
52
|
+
# @param plugin [Jenkins::Api::Client::PluginSettings::Base]
|
53
|
+
#
|
54
|
+
# @return [JenkinsApi::Client::PluginSettings::Collection] the job object
|
55
|
+
def add_plugin(plugin)
|
56
|
+
plugin_collection.add(plugin)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Remove a plugin to be included in job's xml configureation
|
60
|
+
#
|
61
|
+
# @param plugin [Jenkins::Api::Client::PluginSettings::Base]
|
62
|
+
#
|
63
|
+
# @return [JenkinsApi::Client::PluginSettings::Collection] the job object
|
64
|
+
def remove_plugin(plugin)
|
65
|
+
plugin_collection.remove(plugin)
|
45
66
|
end
|
46
67
|
|
47
68
|
# Return a string representation of the object
|
@@ -118,6 +139,8 @@ module JenkinsApi
|
|
118
139
|
# the type of source control. Supported providers: git, svn, and cvs
|
119
140
|
# @option params [String] :scm_url
|
120
141
|
# the remote url for the selected scm provider
|
142
|
+
# @option params [String] :scm_credentials_id
|
143
|
+
# the id of the credentials to use for authenticating with scm. Only for "git"
|
121
144
|
# @option params [String] :scm_module
|
122
145
|
# the module to download. Only for use with "cvs" scm provider
|
123
146
|
# @option params [String] :scm_branch (master)
|
@@ -329,7 +352,9 @@ module JenkinsApi
|
|
329
352
|
xml.buildWrappers
|
330
353
|
end
|
331
354
|
end
|
332
|
-
|
355
|
+
|
356
|
+
xml_doc = Nokogiri::XML(builder.to_xml)
|
357
|
+
plugin_collection.configure(xml_doc).to_xml
|
333
358
|
end
|
334
359
|
|
335
360
|
|
@@ -757,7 +782,7 @@ module JenkinsApi
|
|
757
782
|
# this method (build) exits. Default: nil
|
758
783
|
#
|
759
784
|
# @return [Integer] build number, or nil if not started (IF TIMEOUT SPECIFIED)
|
760
|
-
# @return [
|
785
|
+
# @return [String] HTTP response code (per prev. behavior) (NO TIMEOUT SPECIFIED)
|
761
786
|
#
|
762
787
|
def build(job_name, params={}, opts = {})
|
763
788
|
if opts.nil? || opts.class.is_a?(FalseClass)
|
@@ -772,11 +797,13 @@ module JenkinsApi
|
|
772
797
|
msg << " with parameters: #{params.inspect}" unless params.empty?
|
773
798
|
@logger.info msg
|
774
799
|
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
800
|
+
if (opts['build_start_timeout'] || 0) > 0
|
801
|
+
# Best-guess build-id
|
802
|
+
# This is only used if we go the old-way below... but we can use this number to detect if multiple
|
803
|
+
# builds were queued
|
804
|
+
current_build_id = get_current_build_number(job_name)
|
805
|
+
expected_build_id = current_build_id > 0 ? current_build_id + 1 : 1
|
806
|
+
end
|
780
807
|
|
781
808
|
if (params.nil? or params.empty?)
|
782
809
|
response = @client.api_post_request("/job/#{path_encode job_name}/build",
|
@@ -1425,6 +1452,20 @@ module JenkinsApi
|
|
1425
1452
|
result
|
1426
1453
|
end
|
1427
1454
|
|
1455
|
+
#A Method to find artifacts path from the Current Build
|
1456
|
+
#
|
1457
|
+
# @param [String] job_name
|
1458
|
+
#
|
1459
|
+
def find_artifact(job_name)
|
1460
|
+
current_build_number = get_current_build_number(job_name)
|
1461
|
+
job_path = "job/#{path_encode job_name}/"
|
1462
|
+
response_json = @client.api_get_request("/#{job_path}#{current_build_number}")
|
1463
|
+
relative_build_path = response_json['artifacts'][0]['relativePath']
|
1464
|
+
jenkins_path = response_json['url']
|
1465
|
+
artifact_path = URI.escape("#{jenkins_path}artifact/#{relative_build_path}")
|
1466
|
+
return artifact_path
|
1467
|
+
end
|
1468
|
+
|
1428
1469
|
private
|
1429
1470
|
|
1430
1471
|
# Obtains the threshold params used by jenkins in the XML file
|
@@ -1517,6 +1558,7 @@ module JenkinsApi
|
|
1517
1558
|
xml.send("hudson.plugins.git.UserRemoteConfig") {
|
1518
1559
|
xml.name
|
1519
1560
|
xml.refspec
|
1561
|
+
xml.credentialsId "#{params[:scm_credentials_id]}"
|
1520
1562
|
xml.url "#{params[:scm_url]}"
|
1521
1563
|
}
|
1522
1564
|
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module JenkinsApi
|
4
|
+
class Client
|
5
|
+
module PluginSettings
|
6
|
+
class Collection
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegator :@plugin_settings, :size
|
10
|
+
|
11
|
+
def initialize(*plugin_settings)
|
12
|
+
raise JenkinsApi::Client::PluginSettings::InvalidType unless plugin_settings.all? { |p| p.is_a?(JenkinsApi::Client::PluginSettings::Base) }
|
13
|
+
@plugin_settings = plugin_settings
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(plugin)
|
17
|
+
raise JenkinsApi::Client::PluginSettings::InvalidType unless plugin.is_a?(JenkinsApi::Client::PluginSettings::Base)
|
18
|
+
tap do |x|
|
19
|
+
if @plugin_settings.none? { |p| p.class == plugin.class }
|
20
|
+
@plugin_settings << plugin
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove(plugin)
|
26
|
+
tap do |x|
|
27
|
+
@plugin_settings.delete_if { |p| p.class == plugin.class }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def configure(xml_doc)
|
32
|
+
xml_doc.tap do |x|
|
33
|
+
@plugin_settings.each { |p| p.configure(x) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module JenkinsApi
|
2
|
+
class Client
|
3
|
+
module PluginSettings
|
4
|
+
class Hipchat < Base
|
5
|
+
|
6
|
+
# @option params [String] :room
|
7
|
+
# id of the room
|
8
|
+
# @option params [Boolean] :start_notification (false)
|
9
|
+
# whether to notify room when build starts
|
10
|
+
# @option params [Boolean] :notify_success (false)
|
11
|
+
# whether to notify room when build succeeds
|
12
|
+
# @option params [Boolean] :notify_aborted (false)
|
13
|
+
# whether to notify room when build aborts
|
14
|
+
# @option params [Boolean] :notify_not_built (false)
|
15
|
+
# whether to notify room when job could not be build
|
16
|
+
# @option params [String] :notify_unstable
|
17
|
+
# whether to notify room when job becomes unstable
|
18
|
+
# @option params [String] :notify_failure
|
19
|
+
# whether to notify room when job fails
|
20
|
+
# @option params [String] :notify_back_to_normal
|
21
|
+
# whether to notify room when job becomes stable
|
22
|
+
#
|
23
|
+
def initialize(params={})
|
24
|
+
@params = params
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create or Update a job with params given as a hash instead of the xml
|
28
|
+
# This gives some flexibility for creating/updating simple jobs so the
|
29
|
+
# user doesn't have to learn about handling xml.
|
30
|
+
#
|
31
|
+
# @param params [Hash] parameters to create a freestyle project
|
32
|
+
#
|
33
|
+
# @return [Nokogiri::XML::Document]
|
34
|
+
def configure(xml_doc)
|
35
|
+
xml_doc.tap do |doc|
|
36
|
+
Nokogiri::XML::Builder.with(doc.at('properties')) do |properties|
|
37
|
+
properties.send('jenkins.plugins.hipchat.HipChatNotifier_-HipChatJobProperty') do |x|
|
38
|
+
x.room @params.fetch(:room) { '' }
|
39
|
+
x.startNotification @params.fetch(:start_notification) { false }
|
40
|
+
x.notifySuccess @params.fetch(:notify_success) { false }
|
41
|
+
x.notifyAborted @params.fetch(:notify_aborted) { false }
|
42
|
+
x.notifyNotBuilt @params.fetch(:notify_not_built) { false }
|
43
|
+
x.notifyUnstable @params.fetch(:notify_unstable) { false }
|
44
|
+
x.notifyFailure @params.fetch(:notify_failure) { false }
|
45
|
+
x.notifyBackToNormal @params.fetch(:notify_back_to_normal) { false }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -25,9 +25,9 @@ module JenkinsApi
|
|
25
25
|
# Major version of the gem
|
26
26
|
MAJOR = 1
|
27
27
|
# Minor version of the gem
|
28
|
-
MINOR =
|
28
|
+
MINOR = 1
|
29
29
|
# Tiny version of the gem used for patches
|
30
|
-
TINY =
|
30
|
+
TINY = 0
|
31
31
|
# Used for pre-releases
|
32
32
|
PRE = nil
|
33
33
|
# Version String of Jenkins API Client.
|
data/spec/unit_tests/job_spec.rb
CHANGED
@@ -85,7 +85,8 @@ describe JenkinsApi::Client::Job do
|
|
85
85
|
:name => "test_job_using_params_git",
|
86
86
|
:scm_provider => "git",
|
87
87
|
:scm_url => "git://github.com/arangamani/jenkins_api_client/git",
|
88
|
-
:scm_branch => "master"
|
88
|
+
:scm_branch => "master",
|
89
|
+
:scm_credentials_id => 'foobar'
|
89
90
|
}
|
90
91
|
@client.should_receive(:post_config)
|
91
92
|
@job.create_freestyle(params)
|
@@ -383,21 +384,17 @@ describe JenkinsApi::Client::Job do
|
|
383
384
|
describe "#build" do
|
384
385
|
# First tests confirm the build method works the same as it used to
|
385
386
|
it "accepts the job name and builds the job" do
|
386
|
-
@client.should_receive(:api_get_request).with(
|
387
|
-
"/job/test_job").and_return({})
|
388
387
|
@client.should_receive(:api_post_request).with(
|
389
388
|
"/job/test_job/build", {}, true).and_return(FakeResponse.new(302))
|
390
|
-
@job.build("test_job").should == 302
|
389
|
+
@job.build("test_job").should == '302'
|
391
390
|
end
|
392
391
|
it "accepts the job name with params and builds the job" do
|
393
|
-
@client.should_receive(:api_get_request).with(
|
394
|
-
"/job/test_job").and_return({})
|
395
392
|
@client.should_receive(:api_post_request).with(
|
396
393
|
"/job/test_job/buildWithParameters",
|
397
394
|
{:branch => 'feature/new-stuff'},
|
398
395
|
true
|
399
396
|
).and_return(FakeResponse.new(302))
|
400
|
-
@job.build("test_job", {:branch => 'feature/new-stuff'}).should == 302
|
397
|
+
@job.build("test_job", {:branch => 'feature/new-stuff'}).should == '302'
|
401
398
|
end
|
402
399
|
|
403
400
|
### OLD NON-QUEUE RESPONSE JENKINS ###
|
@@ -618,6 +615,49 @@ describe JenkinsApi::Client::Job do
|
|
618
615
|
@job.get_promotions("test_job").should == {'dev' => 42, 'stage' => nil}
|
619
616
|
end
|
620
617
|
end
|
618
|
+
|
619
|
+
describe '#scm_git' do
|
620
|
+
before do
|
621
|
+
@job.send(:scm_git, {scm_url: 'http://foo.bar', scm_credentials_id: 'foobar', scm_branch: 'master'}, xml_builder=Nokogiri::XML::Builder.new(:encoding => 'UTF-8'))
|
622
|
+
@xml_config = Nokogiri::XML(xml_builder.to_xml)
|
623
|
+
end
|
624
|
+
|
625
|
+
it 'adds scm_url to hudson.plugins.git.UserRemoteConfig userRemoteConfig url tag' do
|
626
|
+
expect(@xml_config.at_css('scm userRemoteConfigs url').content).to eql('http://foo.bar')
|
627
|
+
end
|
628
|
+
|
629
|
+
it 'adds scm_credentials_id to hudson.plugins.git.UserRemoteConfig userRemoteConfig credentialsId tag' do
|
630
|
+
expect(@xml_config.at_css('scm userRemoteConfigs credentialsId').content).to eql('foobar')
|
631
|
+
end
|
632
|
+
|
633
|
+
it 'adds branch to scm branches' do
|
634
|
+
expect(@xml_config.at_css('scm branches name').content).to eql('master')
|
635
|
+
end
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
describe '#build_freestyle_config' do
|
640
|
+
it 'calls configure on its plugin collection' do
|
641
|
+
expect(@job.plugin_collection).to receive(:configure).and_return(Nokogiri::XML::Document.new(''))
|
642
|
+
@job.build_freestyle_config(name: 'foobar')
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
context 'plugin settings' do
|
647
|
+
let(:plugin) { JenkinsApi::Client::PluginSettings::Base.new }
|
648
|
+
describe '#add_plugin' do
|
649
|
+
it 'calls add on @plugin_collection with given plugin setting' do
|
650
|
+
expect(@job.plugin_collection).to receive(:add).with(plugin)
|
651
|
+
@job.add_plugin(plugin)
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
describe '#remove_plugin' do
|
656
|
+
it 'calls remove on @plugin_collection with given plugin setting' do
|
657
|
+
expect(@job.plugin_collection).to receive(:remove).with(plugin)
|
658
|
+
@job.remove_plugin(plugin)
|
659
|
+
end
|
660
|
+
end
|
621
661
|
end
|
622
662
|
end
|
623
663
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe JenkinsApi::Client::PluginSettings::Collection do
|
4
|
+
let(:plugin_settings_collection) { JenkinsApi::Client::PluginSettings::Collection.new }
|
5
|
+
let(:plugin_setting) { JenkinsApi::Client::PluginSettings::Base.new }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
it 'raises a InvalidType exception if given anything that is not a plugin setting' do
|
9
|
+
expect { JenkinsApi::Client::PluginSettings::Collection.new(Object.new) }.to raise_error(JenkinsApi::Client::PluginSettings::InvalidType)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#add' do
|
14
|
+
context 'collection does not have member of given plugin setting' do
|
15
|
+
it 'adds the plugin to the collection' do
|
16
|
+
expect(plugin_settings_collection.add(plugin_setting).size).to eql(1)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'collection alreayd has member of same tyep as given plugin setting' do
|
21
|
+
it 'no-ops' do
|
22
|
+
plugin_settings_collection.add(plugin_setting)
|
23
|
+
expect(plugin_settings_collection.add(plugin_setting).size).to eql(1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'raises a InvalidType exception if a non plugin setting is added' do
|
28
|
+
expect { plugin_settings_collection.add(Object.new) }.to raise_error(JenkinsApi::Client::PluginSettings::InvalidType)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#remove' do
|
33
|
+
context 'collection does not have member of given plugin setting' do
|
34
|
+
it 'no-ops' do
|
35
|
+
expect(plugin_settings_collection.remove(plugin_setting).size).to eql(0)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'collection already has member of same type as given plugin setting' do
|
40
|
+
it 'removes item with same type as given plugin setting from the collection' do
|
41
|
+
plugin_settings_collection.add(plugin_setting)
|
42
|
+
expect(plugin_settings_collection.remove(plugin_setting).size).to eql(0)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#configure' do
|
48
|
+
context 'collection is empty' do
|
49
|
+
it 'no-ops' do
|
50
|
+
expect { plugin_settings_collection.configure(Nokogiri::XML::Document.new)}.to_not raise_error
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'collection has plugins' do
|
55
|
+
it 'calls configure on each of its plugin members' do
|
56
|
+
plugin_settings_collection.add(plugin_setting)
|
57
|
+
expect(plugin_setting).to receive(:configure).once
|
58
|
+
plugin_settings_collection.configure(Nokogiri::XML::Document.new)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe JenkinsApi::Client::PluginSettings::Hipchat do
|
4
|
+
describe '#configure' do
|
5
|
+
context 'given a Nokogiri::XML::Builder object' do
|
6
|
+
it 'adds hipchat configuration to the properties tag with default opts' do
|
7
|
+
hipchat_settings = JenkinsApi::Client::PluginSettings::Hipchat.new
|
8
|
+
hipchat_settings.configure(xml_doc=Nokogiri::XML("<?xml version=\"1.0\"?>\n<properties>\n</properties>\n"))
|
9
|
+
|
10
|
+
expect(xml_doc.at_css('properties room').content).to eql('')
|
11
|
+
expect(xml_doc.at_css('properties startNotification').content).to eql('false')
|
12
|
+
expect(xml_doc.at_css('properties notifySuccess').content).to eql('false')
|
13
|
+
expect(xml_doc.at_css('properties notifyAborted').content).to eql('false')
|
14
|
+
expect(xml_doc.at_css('properties notifyNotBuilt').content).to eql('false')
|
15
|
+
expect(xml_doc.at_css('properties notifyUnstable').content).to eql('false')
|
16
|
+
expect(xml_doc.at_css('properties notifyFailure').content).to eql('false')
|
17
|
+
expect(xml_doc.at_css('properties notifyBackToNormal').content).to eql('false')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'uses params if given' do
|
21
|
+
hipchat_settings = JenkinsApi::Client::PluginSettings::Hipchat.new({
|
22
|
+
:room => '10000',
|
23
|
+
:start_notification => true,
|
24
|
+
:notify_success => true,
|
25
|
+
:notify_aborted => true,
|
26
|
+
:notify_not_built => true,
|
27
|
+
:notify_unstable => true,
|
28
|
+
:notify_failure => true,
|
29
|
+
:notify_back_to_normal => true,
|
30
|
+
})
|
31
|
+
hipchat_settings.configure(xml_doc=Nokogiri::XML("<?xml version=\"1.0\"?>\n<properties>\n</properties>\n"))
|
32
|
+
|
33
|
+
expect(xml_doc.at_css('properties room').content).to eql('10000')
|
34
|
+
expect(xml_doc.at_css('properties startNotification').content).to eql('true')
|
35
|
+
expect(xml_doc.at_css('properties notifySuccess').content).to eql('true')
|
36
|
+
expect(xml_doc.at_css('properties notifyAborted').content).to eql('true')
|
37
|
+
expect(xml_doc.at_css('properties notifyNotBuilt').content).to eql('true')
|
38
|
+
expect(xml_doc.at_css('properties notifyUnstable').content).to eql('true')
|
39
|
+
expect(xml_doc.at_css('properties notifyFailure').content).to eql('true')
|
40
|
+
expect(xml_doc.at_css('properties notifyBackToNormal').content).to eql('true')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jenkins_api_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kannan Manickam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -216,6 +216,9 @@ files:
|
|
216
216
|
- lib/jenkins_api_client/job.rb
|
217
217
|
- lib/jenkins_api_client/node.rb
|
218
218
|
- lib/jenkins_api_client/plugin_manager.rb
|
219
|
+
- lib/jenkins_api_client/plugin_settings/base.rb
|
220
|
+
- lib/jenkins_api_client/plugin_settings/collection.rb
|
221
|
+
- lib/jenkins_api_client/plugin_settings/hipchat.rb
|
219
222
|
- lib/jenkins_api_client/system.rb
|
220
223
|
- lib/jenkins_api_client/urihelper.rb
|
221
224
|
- lib/jenkins_api_client/user.rb
|
@@ -241,6 +244,8 @@ files:
|
|
241
244
|
- spec/unit_tests/fixtures/files/updatable_plugins.json
|
242
245
|
- spec/unit_tests/job_spec.rb
|
243
246
|
- spec/unit_tests/node_spec.rb
|
247
|
+
- spec/unit_tests/plugin_settings/colllection_spec.rb
|
248
|
+
- spec/unit_tests/plugin_settings/hipchat_spec.rb
|
244
249
|
- spec/unit_tests/plugin_spec.rb
|
245
250
|
- spec/unit_tests/spec_helper.rb
|
246
251
|
- spec/unit_tests/system_spec.rb
|