jenkins_api_client 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3897dc16888185c70f0fe4c10ebe276926d993fd
4
- data.tar.gz: aa5e4de611aebea6b1cce304b30f518b7804219a
3
+ metadata.gz: f4bc7855c7d74b4542c7a98175b2319f92c5b667
4
+ data.tar.gz: 6ab8636c67ef0e24a747ebcc413547138ba0b3e1
5
5
  SHA512:
6
- metadata.gz: 9d9f39b820ddbc284a1c28aeae2268b3bc4116869e89bf84f6c604305c869f8005f1754c0264d2f6f8bfec0e424bf599b6c9dfe20adab709279b884fb66e5867
7
- data.tar.gz: 9fbde3bbdb855aa297968da8153ebd7ffc16d1b9eeefa914aa2be69315a83969f4c8f30829b87ce5a5096ccdd36756157cc123c1e8152cda76dd8e4e7834c982
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.Load_file(File.expand_path(
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 302 if
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 == 302
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 == 302
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
 
@@ -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.1 ruby lib
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.1"
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-07-16"
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",
@@ -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
@@ -94,7 +94,7 @@ module JenkinsApi
94
94
  response_json = @client.api_get_request("/queue")
95
95
  details = {}
96
96
  response_json["items"].each do |item|
97
- details = item if item["task"]["name"]
97
+ details = item if item["task"]["name"] == task_name
98
98
  end
99
99
  details
100
100
  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.info "GET #{@jenkins_path}/"
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.info "GET #{to_get}"
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.info "POST #{url_prefix}"
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.info "GET #{url_prefix}/config.xml"
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.info "POST #{url_prefix}"
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
- builder.to_xml
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 [Integer] HTTP response code (per prev. behavior) (NO TIMEOUT SPECIFIED)
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
- # Best-guess build-id
776
- # This is only used if we go the old-way below... but we can use this number to detect if multiple
777
- # builds were queued
778
- current_build_id = get_current_build_number(job_name)
779
- expected_build_id = current_build_id > 0 ? current_build_id + 1 : 1
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,11 @@
1
+ module JenkinsApi
2
+ class Client
3
+ module PluginSettings
4
+ class Base
5
+ def configure
6
+ raise InvalidType, 'Object must inherit from JenkinsApi::Client::PluginSettings::Base and override configure method'
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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 = 0
28
+ MINOR = 1
29
29
  # Tiny version of the gem used for patches
30
- TINY = 1
30
+ TINY = 0
31
31
  # Used for pre-releases
32
32
  PRE = nil
33
33
  # Version String of Jenkins API Client.
@@ -3,7 +3,7 @@ class FakeResponse
3
3
 
4
4
  def initialize(code=200, body='eww, a body', header={})
5
5
  @body = body
6
- @code = code
6
+ @code = code.to_s
7
7
  @header = header
8
8
  end
9
9
  end
@@ -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.1
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-07-16 00:00:00.000000000 Z
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