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 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