jenkins_api_client 1.0.0.alpha.2 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -33,3 +33,6 @@ Gemfile.lock
33
33
  *.tmproj
34
34
  tmtags
35
35
  *.swp
36
+
37
+ # Skip the log file
38
+ jenkins_api_client.log
@@ -6,14 +6,14 @@ upcoming
6
6
 
7
7
  v0.14.1 [18-AUG-2013]
8
8
  ----------------------
9
- * Fixed a bug in Job#create_or_update method. Credit: @bobbrez
9
+ * Fixed a bug in Job#create_or_update method. Credit: [@bobbrez][]
10
10
 
11
11
  v0.14.0 [07-AUG-2013]
12
12
  ----------------------
13
13
  * Fixed a bug where a space was missing in the exec_cli method argument list.
14
- Credit: @missedone
14
+ Credit: [@missedone][]
15
15
  * Refactored create/update jobs by introducing create_or_update methods.
16
- Credit: @riywo
16
+ Credit: [@riywo][]
17
17
  * Enhancement to crumb processing - auto detect the change of crumb setting and
18
18
  do proper exception handling. Credit: dougforpress
19
19
  * Added a `User` class which will handle jenkins users related functions.
@@ -37,38 +37,37 @@ v0.13.0 [09-JUL-2013]
37
37
  queue for longer than the 'timeout' parameter. This timeout parameter can be
38
38
  set during the client initialization.
39
39
  * Improved documentation
40
- * Support for enabling/disabling jobs. Credit: @dieterdemeyer
41
- * Added functionality for copying jobs. Credit: @dieterdemeyer
40
+ * Support for enabling/disabling jobs. Credit: [@dieterdemeyer][]
41
+ * Added functionality for copying jobs. Credit: [@dieterdemeyer][]
42
42
  * Added functionality for wiping out the workspace of a job.
43
- Credit: @dieterdemeyer
44
- * Added functionality for listing jenkins users. Credit: @dieterdemeyer
43
+ Credit: [@dieterdemeyer][]
44
+ * Added functionality for listing jenkins users. Credit: [@dieterdemeyer][]
45
45
  * Fixed a bug where the exceptions where not thrown when using the
46
46
  `get_console_output` method.
47
47
  * Fixed a bug where the jenkins_path attribute was ignored when the server_url
48
- input argument is given. Credit: @woodbusy
48
+ input argument is given. Credit: [@woodbusy][]
49
49
  * support public/private key pair authentication for Jenkins CLI.
50
- Credit: @missedone
50
+ Credit: [@missedone][]
51
51
 
52
52
 
53
53
  v0.12.1 [25-JUN-2013]
54
54
  ----------------------
55
55
  * Fixed a bug where the SSL support was not working properly with Ruby
56
- 1.8.7/JRuby 1.6. Credit: @brettporter (For more info:
57
- https://github.com/arangamani/jenkins_api_client/pull/85)
56
+ 1.8.7/JRuby 1.6. (Pull [#85][]) Credit: [@brettporter][]
58
57
 
59
58
  v0.12.0 [18-JUN-2013]
60
59
  ----------------------
61
60
  * Authentication is now optional as not all Jenkins instances have
62
- authentication enabled by default. Credit: @dougforpres
61
+ authentication enabled by default. Credit: [@dougforpres][]
63
62
  * Ability to retrieve build details so that more than just (`lamp color`) is
64
- available. Credit: @dougforpres
63
+ available. Credit: [@dougforpres][]
65
64
  * Ability to retrieve build test-results for those builds that have them.
66
- Credit: @dougforpres
65
+ Credit: [@dougforpres][]
67
66
  * Option to follow any 301/302 responses. This allows POST to build to follow
68
- the redirect and end up with a 200 response. Credit: @dougforpres
67
+ the redirect and end up with a 200 response. Credit: [@dougforpres][]
69
68
  * Minor change to the POST requests handling where jenkins instances with a
70
69
  proxy returns 411 if no form data is specified. Fixed by sending an empty
71
- hash. Credit: @dougforpres
70
+ hash. Credit: [@dougforpres][]
72
71
  * As of Jenkins release 1.519, the job build returns a 201 code instead of 302.
73
72
  This was resulting in an exception and the exception handling is modified to
74
73
  handle this condition.
@@ -78,17 +77,17 @@ v0.12.0 [18-JUN-2013]
78
77
  v0.11.0 [09-JUN-2013]
79
78
  ----------------------
80
79
  * A new input argument `server_url` is supported which accepts the jenkins URL
81
- instead of IP address and Port. Credit: @dieterdemeyer
82
- * When renaming the job, preserve the job history. Credit: @rubytester
83
- * Various exception handling improvements. Credit: @drnic
80
+ instead of IP address and Port. Credit: [@dieterdemeyer][]
81
+ * When renaming the job, preserve the job history. Credit: [@rubytester][]
82
+ * Various exception handling improvements. Credit: [@drnic][]
84
83
 
85
84
  v0.10.0 [24-APR-2013]
86
85
  ----------------------
87
- * new function to execute jenkins CLI `cli_exec`. Credit: @missedone
88
- * Add ability to use http proxy. Credit: @woodbusy
89
- * prompt the user for credentials when using irb login script. @woodbusy
90
- * bugfix for job.console_output. Credit: @drnic
91
- * add ssl support. Credit: @madisp
86
+ * new function to execute jenkins CLI `cli_exec`. Credit: [@missedone][]
87
+ * Add ability to use http proxy. Credit: [@woodbusy][]
88
+ * prompt the user for credentials when using irb login script. [@woodbusy][]
89
+ * bugfix for job.console_output. Credit: [@drnic][]
90
+ * add ssl support. Credit: [@madisp][]
92
91
 
93
92
  v0.9.1 [01-APR-2013]
94
93
  ---------------------
@@ -101,18 +100,18 @@ v0.9.0 [10-MAR-2013]
101
100
  * Removed warnings from client.rb
102
101
  * Refactored and improved exception handling
103
102
  * A bug is fixed in client which allows only the valid params as options.
104
- Credit: @Niarfe
103
+ Credit: [@Niarfe][]
105
104
  * Added a timeout parameter for waiting for jenkins to become ready.
106
- Credit: @Niarfe
107
- * Added function to reload jenkins. Credit: @missedone
105
+ Credit: [@Niarfe][]
106
+ * Added function to reload jenkins. Credit: [@missedone][]
108
107
  * Fixed a bug where jenkins_path was missing in get_config and post_config.
109
- Credit: @cylol
108
+ Credit: [@cylol][]
110
109
  * Added capability to obtain jenkins version and other useful information
111
110
  * Added new tests for various cases, and other code improvements
112
111
 
113
112
  v0.8.1 [15-FEB-2013]
114
113
  ---------------------
115
- * Fixed a bug in creating view. Issue #42
114
+ * Fixed a bug in creating view. Issue [#42][]
116
115
 
117
116
  v0.8.0 [14-FEB-2013]
118
117
  ---------------------
@@ -120,16 +119,16 @@ v0.8.0 [14-FEB-2013]
120
119
  * Added rename feature for jobs
121
120
  * Added support for sending skype notification in job creation and on existing
122
121
  jobs
123
- * Added support for sending Jenkins root URL configuration. Credit: @kevinhcross
122
+ * Added support for sending Jenkins root URL configuration. Credit: [@kevinhcross][]
124
123
  * Added `delete_all!` methods for Job, View, and Node.
125
124
  * `get_eta` in BuildQueue will return "N/A" if the ETA is not given by Jenkins
126
125
  * Creating view accepts params Hash and more configuration through the API
127
- * Spaces are allowed in Job, Node, and View names. Credit: @kevinhcross
128
- * Support has been added to build a job with parameters. Credit: @tjhanley
126
+ * Spaces are allowed in Job, Node, and View names. Credit: [@kevinhcross][]
127
+ * Support has been added to build a job with parameters. Credit: [@tjhanley][]
129
128
 
130
129
  v0.7.3 [05-FEB-2013]
131
130
  ---------------------
132
- * Fixed #27 with a bug in create_view including extra character in the end of
131
+ * Fixed [#27][] with a bug in create_view including extra character in the end of
133
132
  the name
134
133
 
135
134
  v0.7.2 [02-FEB-2013]
@@ -138,7 +137,7 @@ v0.7.2 [02-FEB-2013]
138
137
 
139
138
  v0.7.1 [30-JAN-2013]
140
139
  ---------------------
141
- * Fixed a bug (Issue #23) to remove the usage of "\" in Job.
140
+ * Fixed a bug (Issue [#23][]) to remove the usage of "\" in Job.
142
141
 
143
142
  v0.7.0 [27-JAN-2013]
144
143
  ---------------------
@@ -149,7 +148,7 @@ v0.7.0 [27-JAN-2013]
149
148
  * Added support for notification_email option when setting up a job
150
149
  * Added support for CVS provider in SCM
151
150
  * Added `create_dump_slave` and `delete` methods in Node API
152
- * Added BuildQueue class which is accessible by `@client.queue` method
151
+ * Added BuildQueue class which is accessible by `[@client][].queue` method
153
152
  * Improvements in all over the code for performance and error handling
154
153
 
155
154
  v0.6.2 [13-JAN-2013]
@@ -220,3 +219,25 @@ v0.0.2 [16-OCT-2012]
220
219
  v0.0.1 [15-OCT-2012]
221
220
  ---------------------
222
221
  * Initial Release
222
+
223
+
224
+ <!--- The following link definition list is generated by PimpMyChangelog --->
225
+ [#23]: https://github.com/arangamani/jenkins_api_client/issues/23
226
+ [#27]: https://github.com/arangamani/jenkins_api_client/issues/27
227
+ [#42]: https://github.com/arangamani/jenkins_api_client/issues/42
228
+ [#85]: https://github.com/arangamani/jenkins_api_client/issues/85
229
+ [@Niarfe]: https://github.com/Niarfe
230
+ [@bobbrez]: https://github.com/bobbrez
231
+ [@brettporter]: https://github.com/brettporter
232
+ [@client]: https://github.com/client
233
+ [@cylol]: https://github.com/cylol
234
+ [@dieterdemeyer]: https://github.com/dieterdemeyer
235
+ [@dougforpres]: https://github.com/dougforpres
236
+ [@drnic]: https://github.com/drnic
237
+ [@kevinhcross]: https://github.com/kevinhcross
238
+ [@madisp]: https://github.com/madisp
239
+ [@missedone]: https://github.com/missedone
240
+ [@riywo]: https://github.com/riywo
241
+ [@rubytester]: https://github.com/rubytester
242
+ [@tjhanley]: https://github.com/tjhanley
243
+ [@woodbusy]: https://github.com/woodbusy
@@ -1,15 +1,3 @@
1
1
  Thank you very much to all who contributed to this project.
2
2
 
3
- * [Niarfe](https://github.com/Niarfe)
4
- * [dieterdemeyer](https://github.com/dieterdemeyer)
5
- * [kevinhcross](https://github.com/kevinhcross)
6
- * [drnic](https://github.com/drnic)
7
- * [woodbusy](https://github.com/woodbusy)
8
- * [missedone](https://github.com/missedone)
9
- * [cylol](https://github.com/cylol)
10
- * [madisp](https://github.com/madisp)
11
- * [rubytester](https://github.com/rubytester)
12
- * [dougforpres](https://github.com/dougforpres)
13
- * [brettporter](https://github.com/brettporter)
14
- * [riywo](https://github.com/riywo)
15
- * [bobbrez](https://github.com/bobbrez)
3
+ Please visit the [Contributors](https://github.com/arangamani/jenkins_api_client/graphs/contributors) page on Github.
data/README.md CHANGED
@@ -177,6 +177,87 @@ initial_jobs.each do |job|
177
177
  end
178
178
  ```
179
179
 
180
+ ### Waiting for a build to start/Getting the build number
181
+ Newer versions of Jenkins (starting with the 1.519 build) make it easier for
182
+ an application to determine the build number for a 'build' request. (previously
183
+ there would be a degree of guesswork involved). The new version actually
184
+ returns information allowing the jenkins_api_client to check the build queue
185
+ for the job and see if it has started yet (once it has started, the build-
186
+ number is available.
187
+
188
+ If you wish to take advantage of this hands-off approach, the build method
189
+ supports an additional 'opts' hash that lets you specify how long you wish to
190
+ wait for the build to start.
191
+
192
+ #### Old Jenkins vs New Jenkins (1.519+)
193
+
194
+ ##### Old (v < 1.519)
195
+ The 'opts' parameter will work with older versions of Jenkins with the following
196
+ caveats:
197
+ * The 'cancel_on_build_start_timeout' option has no effect
198
+ * The build_number is calculated by calling 'current_build_number' and adding
199
+ 1 before the build is started. This might break if there are multiple
200
+ entities running builds on the same job, or there are queued builds.
201
+
202
+ ##### New (v >= 1.519)
203
+ * All options work, and build number is accurately determined from queue
204
+ info.
205
+
206
+ #### Initiating a build and returning the build_number
207
+
208
+ ##### Minimum required
209
+ ```ruby
210
+ # Minimum options required
211
+ opts = {'build_start_timeout' => 30}
212
+ @client.job.build(job_name, job_params || {}, opts)
213
+ ```
214
+ This method will block for up to 30 seconds, while waiting for the build to
215
+ start. Instead of returning an http-status code, it will return the
216
+ build_number, or if the build has not started will raise 'Timeout::Error'
217
+ Note: to maintain legacy compatibility, passing 'true' will set the timeout
218
+ to the default timeout specified when creating the @client.
219
+
220
+ ##### Auto cancel the queued-build on timeout
221
+ ```ruby
222
+ # Wait for up to 30 seconds, attempt to cancel queued build
223
+ opts = {'build_start_timeout' => 30,
224
+ 'cancel_on_build_start_timeout' => true}
225
+ @client.job.build(job_name, job_params || {}, opts)
226
+ ```
227
+ This method will block for up to 30 seconds, while waiting for the build to
228
+ start. Instead of returning an http-status code, it will return the
229
+ build_number, or if the build has not started will raise 'Timeout::Error'.
230
+ Prior to raising the Timeout::Error, it will attempt to cancel the queued
231
+ build - thus preventing it from starting.
232
+
233
+ ##### Getting some feedback while you're waiting
234
+ The opts parameter supports two values that can be assigned proc objects
235
+ (which will be 'call'ed). Both are optional, and will only be called if
236
+ specified in opts.
237
+ These are initially intended to assist with logging progress.
238
+
239
+ * 'progress_proc' - called when job is initially queued, and periodically
240
+ thereafter.
241
+ * max_wait - the value of 'build_start_timeout'
242
+ * current_wait - how long we've been waiting so far
243
+ * poll_count - how many times we've polled the queue
244
+ * 'completion_proc' - called just prior to return/Timeout::Error
245
+ * build_number - the build number assigned (or nil if timeout)
246
+ * cancelled - whether the build was cancelled (true if 'new' Jenkins
247
+ and it was able to cancel the build, false otherwise)
248
+
249
+ To use a class method, just specify 'instance.method(:method_name)', or
250
+ use a proc or lambda
251
+
252
+ ```ruby
253
+ # Wait for up to 30 seconds, attempt to cancel queued build, progress
254
+ opts = {'build_start_timeout' => 30,
255
+ 'cancel_on_build_start_timeout' => true,
256
+ 'poll_interval' => 2, # 2 is actually the default :)
257
+ 'progress_proc' => lambda {|max,curr,count| ... },
258
+ 'completion_proc' => lambda {|build_number,cancelled| ... }}
259
+ @client.job.build(job_name, job_params || {}, opts)
260
+ ```
180
261
  ### Running Jenkins CLI
181
262
  To running [Jenkins CLI](https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI)
182
263
 
@@ -190,8 +271,9 @@ puts @client.exec_cli("version")
190
271
  ```
191
272
 
192
273
  * authentication with public/private key file
193
- remember to upload the public key to
194
- http://<Server IP>:<Server Port>/user/<Username>/configure
274
+ remember to upload the public key to:
275
+
276
+ `http://#{Server IP}:#{Server Port}/user/#{Username}/configure`
195
277
 
196
278
  ```ruby
197
279
  @client = JenkinsApi::Client.new(:server_ip => '127.0.0.1',
@@ -278,3 +360,7 @@ FEATURE REQUEST:
278
360
  If you use this gem for your project and you think it would be nice to have a
279
361
  particular feature that is presently not implemented, I would love to hear that
280
362
  and consider working on it. Just open an issue in Github as a feature request.
363
+
364
+
365
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/arangamani/jenkins_api_client/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
366
+
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "jenkins_api_client"
8
- s.version = "1.0.0.alpha.2"
8
+ s.version = "1.0.0.beta.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kannan Manickam"]
12
- s.date = "2013-10-25"
12
+ s.date = "2013-11-17"
13
13
  s.description = "\nThis is a simple and easy-to-use Jenkins Api client with features focused on\nautomating Job configuration programaticaly and so forth"
14
14
  s.email = ["arangamani.kannan@gmail.com"]
15
15
  s.executables = ["jenkinscli"]
@@ -42,13 +42,14 @@ Gem::Specification.new do |s|
42
42
  "lib/jenkins_api_client/node.rb",
43
43
  "lib/jenkins_api_client/plugin_manager.rb",
44
44
  "lib/jenkins_api_client/system.rb",
45
+ "lib/jenkins_api_client/urihelper.rb",
45
46
  "lib/jenkins_api_client/user.rb",
46
47
  "lib/jenkins_api_client/version.rb",
47
48
  "lib/jenkins_api_client/view.rb",
48
49
  "scripts/login_with_irb.rb",
49
50
  "spec/func_tests/client_spec.rb",
50
51
  "spec/func_tests/job_spec.rb",
51
- "spec/func_tests/node_spec.rb",
52
+ "spec/func_tests/node_spec.rb.pending",
52
53
  "spec/func_tests/plugin_spec.rb",
53
54
  "spec/func_tests/spec_helper.rb",
54
55
  "spec/func_tests/system_spec.rb",
@@ -56,6 +57,7 @@ Gem::Specification.new do |s|
56
57
  "spec/func_tests/view_spec.rb",
57
58
  "spec/unit_tests/build_queue_spec.rb",
58
59
  "spec/unit_tests/client_spec.rb",
60
+ "spec/unit_tests/fake_http_response.rb",
59
61
  "spec/unit_tests/fixtures/files/available_plugins.json",
60
62
  "spec/unit_tests/fixtures/files/computer_sample.xml",
61
63
  "spec/unit_tests/fixtures/files/installed_plugins.json",
@@ -287,6 +287,11 @@ module JenkinsApi
287
287
  )
288
288
  end
289
289
  end
290
+
291
+ # Pick out some useful header info before we return
292
+ @jenkins_version = response['X-Jenkins']
293
+ @hudson_version = response['X-Hudson']
294
+
290
295
  return response
291
296
  end
292
297
  protected :make_http_request
@@ -321,7 +326,6 @@ module JenkinsApi
321
326
  else
322
327
  to_get = "#{url_prefix}#{url_suffix}"
323
328
  end
324
- to_get = URI.escape(to_get)
325
329
  request = Net::HTTP::Get.new(to_get)
326
330
  @logger.info "GET #{to_get}"
327
331
  response = make_http_request(request)
@@ -346,8 +350,7 @@ module JenkinsApi
346
350
 
347
351
  # Added form_data default {} instead of nil to help with proxies
348
352
  # that barf with empty post
349
- url_prefix = URI.escape("#{@jenkins_path}#{url_prefix}")
350
- request = Net::HTTP::Post.new("#{url_prefix}")
353
+ request = Net::HTTP::Post.new("#{@jenkins_path}#{url_prefix}")
351
354
  @logger.info "POST #{url_prefix}"
352
355
  request.content_type = 'application/json'
353
356
  if @crumbs_enabled
@@ -386,8 +389,7 @@ module JenkinsApi
386
389
  # @return [String] XML configuration obtained from Jenkins
387
390
  #
388
391
  def get_config(url_prefix)
389
- url_prefix = URI.escape("#{@jenkins_path}#{url_prefix}")
390
- request = Net::HTTP::Get.new("#{url_prefix}/config.xml")
392
+ request = Net::HTTP::Get.new("#{@jenkins_path}#{url_prefix}/config.xml")
391
393
  @logger.info "GET #{url_prefix}/config.xml"
392
394
  response = make_http_request(request)
393
395
  handle_exception(response, "body")
@@ -413,8 +415,7 @@ module JenkinsApi
413
415
  begin
414
416
  refresh_crumbs
415
417
 
416
- url_prefix = URI.escape("#{@jenkins_path}#{url_prefix}")
417
- request = Net::HTTP::Post.new("#{url_prefix}")
418
+ request = Net::HTTP::Post.new("#{@jenkins_path}#{url_prefix}")
418
419
  @logger.info "POST #{url_prefix}"
419
420
  request.body = data
420
421
  request.content_type = content_type
@@ -480,21 +481,64 @@ module JenkinsApi
480
481
  end
481
482
 
482
483
  # Obtains the jenkins version from the API
484
+ # Only queries Jenkins if the version is not already stored.
485
+ # Note that the version is auto-updated after every request made to Jenkins
486
+ # since it is returned as a header in every response
483
487
  #
484
- # @return Jenkins version
488
+ # @return [String] Jenkins version
485
489
  #
486
490
  def get_jenkins_version
487
- response = get_root
488
- response["X-Jenkins"]
491
+ get_root if @jenkins_version.nil?
492
+ @jenkins_version
489
493
  end
490
494
 
491
495
  # Obtain the Hudson version of the CI server
496
+ # Only queries Hudson/Jenkins if the version is not already stored.
497
+ # Note that the version is auto-updated after every request made to Jenkins
498
+ # since it is returned as a header in every response
492
499
  #
493
500
  # @return [String] Version of Hudson on Jenkins server
494
501
  #
495
502
  def get_hudson_version
496
- response = get_root
497
- response["X-Hudson"]
503
+ get_root if @hudson_version.nil?
504
+ @hudson_version
505
+ end
506
+
507
+ # Converts a version string to a list of integers
508
+ # This makes it easier to compare versions since in 'version-speak',
509
+ # v 1.2 is a lot older than v 1.102 - and simple < > on version
510
+ # strings doesn't work so well
511
+ def deconstruct_version_string(version)
512
+ match = version.match(/^(\d+)\.(\d+)(?:\.(\d+))?$/)
513
+
514
+ # Match should have 4 parts [0] = input string, [1] = major
515
+ # [2] = minor, [3] = patch (possibly blank)
516
+ if match && match.size == 4
517
+ return [match[1].to_i, match[2].to_i, match[3].to_i || 0]
518
+ else
519
+ return nil
520
+ end
521
+ end
522
+
523
+ # Compare two version strings (A and B)
524
+ # if A == B, returns 0
525
+ # if A > B, returns 1
526
+ # if A < B, returns -1
527
+ def compare_versions(version_a, version_b)
528
+ if version_a == version_b
529
+ return 0
530
+ else
531
+ version_a_d = deconstruct_version_string(version_a)
532
+ version_b_d = deconstruct_version_string(version_b)
533
+
534
+ if version_a_d[0] > version_b_d[0] ||
535
+ (version_a_d[0] == version_b_d[0] && version_a_d[1] > version_b_d[1]) ||
536
+ (version_a_d[0] == version_b_d[0] && version_a_d[1] == version_b_d[1] && version_a_d[2] > version_b_d[2])
537
+ return 1
538
+ else
539
+ return -1
540
+ end
541
+ end
498
542
  end
499
543
 
500
544
  # Obtain the date of the Jenkins server