jenkins_api_client 0.4.0 → 0.5.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.
- data/CHANGELOG.rdoc +6 -0
- data/README.md +2 -0
- data/lib/jenkins_api_client/client.rb +7 -0
- data/lib/jenkins_api_client/job.rb +323 -26
- data/lib/jenkins_api_client/version.rb +1 -1
- data/lib/jenkins_api_client/view.rb +129 -0
- data/spec/job_spec.rb +10 -10
- metadata +161 -167
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= CHANGELOG
|
2
2
|
|
3
|
+
===== v0.5.0 [22-DEC-2012]
|
4
|
+
* Added functionality to create jobs with params.
|
5
|
+
* Added View class and added methods accessing List Views of Jenkins server.
|
6
|
+
* Added functionality to abort a running job.
|
7
|
+
* Deprecated list_running of Job class. list_by_status('running') is suggested.
|
8
|
+
|
3
9
|
===== v0.4.0 [07-DEC-2012]
|
4
10
|
* Added some methods for handling jobs.
|
5
11
|
* The status 'not run' is not returned as 'not_run' from job status.
|
data/README.md
CHANGED
@@ -5,6 +5,8 @@ Copyright © 2012, Kannan Manickam [
|
88
88
|
end
|
89
89
|
|
90
|
+
# Creates an instance to the View class by passing a reference to self
|
91
|
+
#
|
92
|
+
def view
|
93
|
+
JenkinsApi::Client::View.new(self)
|
94
|
+
end
|
95
|
+
|
90
96
|
# Returns a string representing the class name
|
91
97
|
#
|
92
98
|
def to_s
|
@@ -136,6 +142,7 @@ module JenkinsApi
|
|
136
142
|
request = Net::HTTP::Post.new("#{url_prefix}")
|
137
143
|
puts "[INFO] PUT #{url_prefix}" if @debug
|
138
144
|
request.basic_auth @username, @password
|
145
|
+
request.content_type = 'application/json'
|
139
146
|
response = http.request(request)
|
140
147
|
case response.code.to_i
|
141
148
|
when 200, 302
|
@@ -45,6 +45,142 @@ module JenkinsApi
|
|
45
45
|
@client.post_config("/createItem?name=#{job_name}", xml)
|
46
46
|
end
|
47
47
|
|
48
|
+
# Create a job with params given as a hash instead of the xml
|
49
|
+
# This gives some flexibility for creating simple jobs so the user doesn't have to
|
50
|
+
# learn about handling xml.
|
51
|
+
#
|
52
|
+
# @param [Hash] params
|
53
|
+
# * +:name+ name of the job
|
54
|
+
# * +:keep_dependencies+ true or false
|
55
|
+
# * +:block_build_when_downstream_building+ true or false
|
56
|
+
# * +:block_build_when_upstream_building+ true or false
|
57
|
+
# * +:concurrent_build+ true or false
|
58
|
+
# * +:scm_provider+ type of source control system. Supported: git, subversion
|
59
|
+
# * +:scm_url+ remote url for scm
|
60
|
+
# * +:scm_branch+ branch to use in scm. Uses master by default
|
61
|
+
# * +:shell_command+ command to execute in the shell
|
62
|
+
# * +:child_projects+ projects to add as downstream projects
|
63
|
+
# * +:child_threshold+ threshold for child projects. success, failure, or unstable. Default: failure.
|
64
|
+
#
|
65
|
+
def create_freestyle(params)
|
66
|
+
# TODO: Add support for all SCM providers supported by Jenkins
|
67
|
+
supported_scm_providers = ['git', 'subversion']
|
68
|
+
|
69
|
+
# Set default values for params that are not specified and Error handling.
|
70
|
+
raise 'Job name must be specified' unless params[:name]
|
71
|
+
params[:keep_dependencies] = false if params[:keep_dependencies].nil?
|
72
|
+
params[:block_build_when_downstream_building] = false if params[:block_build_when_downstream_building].nil?
|
73
|
+
params[:block_build_when_upstream_building] = false if params[:block_build_when_upstream_building].nil?
|
74
|
+
params[:concurrent_build] = false if params[:concurrent_build].nil?
|
75
|
+
|
76
|
+
# SCM configurations and Error handling. Presently only Git plugin is supported.
|
77
|
+
unless supported_scm_providers.include?(params[:scm_provider]) || params[:scm_provider].nil?
|
78
|
+
raise "SCM #{params[:scm_provider]} is currently not supported"
|
79
|
+
end
|
80
|
+
raise 'SCM URL must be specified' if params[:scm_url].nil? && !params[:scm_provider].nil?
|
81
|
+
params[:scm_branch] = "master" if params[:scm_branch].nil? && !params[:scm_provider].nil?
|
82
|
+
|
83
|
+
# Child projects configuration and Error handling
|
84
|
+
params[:child_threshold] = 'failure' if params[:child_threshold].nil? && !params[:child_projects].nil?
|
85
|
+
|
86
|
+
# Build the Job xml file based on the parameters given
|
87
|
+
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') { |xml|
|
88
|
+
xml.project {
|
89
|
+
xml.actions
|
90
|
+
xml.description
|
91
|
+
xml.keepDependencies "#{params[:keep_dependencies]}"
|
92
|
+
xml.properties
|
93
|
+
# SCM related stuff
|
94
|
+
if params[:scm_provider] == 'subversion'
|
95
|
+
xml.scm(:class => "hudson.scm.SubversionSCM", :plugin => "subversion@1.39") {
|
96
|
+
xml.locations {
|
97
|
+
xml.send("hudson.scm.SubversionSCM_-ModuleLocation") {
|
98
|
+
xml.remote "#{params[:scm_url]}"
|
99
|
+
xml.local "."
|
100
|
+
}
|
101
|
+
}
|
102
|
+
xml.excludedRegions
|
103
|
+
xml.includedRegions
|
104
|
+
xml.excludedUsers
|
105
|
+
xml.excludedRevprop
|
106
|
+
xml.excludedCommitMessages
|
107
|
+
xml.workspaceUpdater(:class => "hudson.scm.subversion.UpdateUpdater")
|
108
|
+
}
|
109
|
+
elsif params[:scm_provider] == 'git'
|
110
|
+
xml.scm(:class => "hudson.plugins.git.GitSCM") {
|
111
|
+
xml.configVersion "2"
|
112
|
+
xml.userRemoteConfigs {
|
113
|
+
xml.send("hudson.plugins.git.UserRemoteConfig") {
|
114
|
+
xml.name
|
115
|
+
xml.refspec
|
116
|
+
xml.url "#{params[:scm_url]}"
|
117
|
+
}
|
118
|
+
}
|
119
|
+
xml.branches {
|
120
|
+
xml.send("hudson.plugins.git.BranchSpec") {
|
121
|
+
xml.name "#{params[:scm_branch]}"
|
122
|
+
}
|
123
|
+
}
|
124
|
+
xml.disableSubmodules "false"
|
125
|
+
xml.recursiveSubmodules "false"
|
126
|
+
xml.doGenerateSubmoduleConfigurations "false"
|
127
|
+
xml.authorOrCommitter "false"
|
128
|
+
xml.clean "false"
|
129
|
+
xml.wipeOutWorkspace "false"
|
130
|
+
xml.pruneBranches "false"
|
131
|
+
xml.remotePoll "false"
|
132
|
+
xml.ignoreNotifyCommit "false"
|
133
|
+
xml.useShallowClone "false"
|
134
|
+
xml.buildChooser(:class => "hudson.plugins.git.util.DefaultBuildChooser")
|
135
|
+
xml.gitTool "Default"
|
136
|
+
xml.submoduleCfg(:class => "list")
|
137
|
+
xml.relativeTargetDir
|
138
|
+
xml.reference
|
139
|
+
xml.excludedRegions
|
140
|
+
xml.excludedUsers
|
141
|
+
xml.gitConfigName
|
142
|
+
xml.gitConfigEmail
|
143
|
+
xml.skipTag "false"
|
144
|
+
xml.includedRegions
|
145
|
+
xml.scmName
|
146
|
+
}
|
147
|
+
else
|
148
|
+
xml.scm(:class => "hudson.scm.NullSCM")
|
149
|
+
end
|
150
|
+
xml.canRoam "true"
|
151
|
+
xml.disabled "false"
|
152
|
+
xml.blockBuildWhenDownstreamBuilding "#{params[:block_build_when_downstream_building]}"
|
153
|
+
xml.blockBuildWhenUpstreamBuilding "#{params[:block_build_when_upstream_building]}"
|
154
|
+
xml.triggers.vector
|
155
|
+
xml.concurrentBuild "#{params[:concurrent_build]}"
|
156
|
+
# Shell command stuff
|
157
|
+
xml.builders {
|
158
|
+
if params[:shell_command]
|
159
|
+
xml.send("hudson.tasks.Shell") {
|
160
|
+
xml.command "#{params[:shell_command]}"
|
161
|
+
}
|
162
|
+
end
|
163
|
+
}
|
164
|
+
# Adding Downstream projects
|
165
|
+
xml.publishers {
|
166
|
+
if params[:child_projects]
|
167
|
+
xml.send("hudson.tasks.BuildTrigger") {
|
168
|
+
xml.childProjects"#{params[:child_projects]}"
|
169
|
+
name, ordinal, color = get_threshold_params(params[:child_threshold])
|
170
|
+
xml.threshold {
|
171
|
+
xml.name "#{name}"
|
172
|
+
xml.ordinal "#{ordinal}"
|
173
|
+
xml.color "#{color}"
|
174
|
+
}
|
175
|
+
}
|
176
|
+
end
|
177
|
+
}
|
178
|
+
xml.buildWrappers
|
179
|
+
}
|
180
|
+
}
|
181
|
+
create(params[:name], builder.to_xml)
|
182
|
+
end
|
183
|
+
|
48
184
|
# Delete a job given the name
|
49
185
|
#
|
50
186
|
# @param [String] job_name
|
@@ -84,9 +220,7 @@ module JenkinsApi
|
|
84
220
|
def list_all
|
85
221
|
response_json = @client.api_get_request("")
|
86
222
|
jobs = []
|
87
|
-
response_json["jobs"].each { |job|
|
88
|
-
jobs << job["name"]
|
89
|
-
}
|
223
|
+
response_json["jobs"].each { |job| jobs << job["name"] }
|
90
224
|
jobs.sort!
|
91
225
|
end
|
92
226
|
|
@@ -95,7 +229,7 @@ module JenkinsApi
|
|
95
229
|
# @param [String] job_name
|
96
230
|
#
|
97
231
|
def exists?(job_name)
|
98
|
-
list(job_name).include?(job_name)
|
232
|
+
list(job_name).include?(job_name)
|
99
233
|
end
|
100
234
|
|
101
235
|
# List all Jobs matching the given status
|
@@ -108,9 +242,9 @@ module JenkinsApi
|
|
108
242
|
jobs = list_all if jobs.empty?
|
109
243
|
xml_response = @client.api_get_request("", "tree=jobs[name,color]")
|
110
244
|
filtered_jobs = []
|
111
|
-
xml_response["jobs"].each
|
245
|
+
xml_response["jobs"].each do |job|
|
112
246
|
filtered_jobs << job["name"] if color_to_status(job["color"]) == status && jobs.include?(job["name"])
|
113
|
-
|
247
|
+
end
|
114
248
|
filtered_jobs
|
115
249
|
end
|
116
250
|
|
@@ -122,13 +256,13 @@ module JenkinsApi
|
|
122
256
|
def list(filter, ignorecase = true)
|
123
257
|
response_json = @client.api_get_request("")
|
124
258
|
jobs = []
|
125
|
-
response_json["jobs"].each
|
259
|
+
response_json["jobs"].each do |job|
|
126
260
|
if ignorecase
|
127
261
|
jobs << job["name"] if job["name"] =~ /#{filter}/i
|
128
262
|
else
|
129
263
|
jobs << job["name"] if job["name"] =~ /#{filter}/
|
130
264
|
end
|
131
|
-
|
265
|
+
end
|
132
266
|
jobs
|
133
267
|
end
|
134
268
|
|
@@ -219,8 +353,10 @@ module JenkinsApi
|
|
219
353
|
end
|
220
354
|
|
221
355
|
# This functions lists all jobs that are currently running on the Jenkins CI server
|
356
|
+
# This method is deprecated. Please use list_by_status instead.
|
222
357
|
#
|
223
358
|
def list_running
|
359
|
+
puts "[WARN] list_running is deprecated. Please use list_by_status('running') instead."
|
224
360
|
xml_response = @client.api_get_request("", "tree=jobs[name,color]")
|
225
361
|
running_jobs = []
|
226
362
|
xml_response["jobs"].each { |job|
|
@@ -268,15 +404,163 @@ module JenkinsApi
|
|
268
404
|
post_config(job_name, xml_modified)
|
269
405
|
end
|
270
406
|
|
271
|
-
#
|
272
|
-
# added as downstream projects, and the threshold
|
407
|
+
# Block the build of the job when downstream is building
|
273
408
|
#
|
274
409
|
# @param [String] job_name
|
275
|
-
# @param [String] downstream_projects
|
276
|
-
# @param [String] threshold - failure, success, or unstable
|
277
|
-
# @param [Bool] overwrite - true or false
|
278
410
|
#
|
279
|
-
def
|
411
|
+
def block_build_when_downstream_building(job_name)
|
412
|
+
xml = get_config(job_name)
|
413
|
+
n_xml = Nokogiri::XML(xml)
|
414
|
+
node = n_xml.xpath("//blockBuildWhenDownstreamBuilding").first
|
415
|
+
if node.content == "false"
|
416
|
+
node.content = "true"
|
417
|
+
xml_modified = n_xml.to_xml
|
418
|
+
post_config(job_name, xml_modified)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
# Unblock the build of the job when downstream is building
|
423
|
+
#
|
424
|
+
# @param [String] job_name
|
425
|
+
#
|
426
|
+
def unblock_build_when_downstream_building(job_name)
|
427
|
+
xml = get_config(job_name)
|
428
|
+
n_xml = Nokogiri::XML(xml)
|
429
|
+
node = n_xml.xpath("//blockBuildWhenDownstreamBuilding").first
|
430
|
+
if node.content == "true"
|
431
|
+
node.content = "false"
|
432
|
+
xml_modified = n_xml.to_xml
|
433
|
+
post_config(job_name, xml_modified)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
# Block the build of the job when upstream is building
|
438
|
+
#
|
439
|
+
# @param [String] job_name
|
440
|
+
#
|
441
|
+
def block_build_when_upstream_building(job_name)
|
442
|
+
xml = get_config(job_name)
|
443
|
+
n_xml = Nokogiri::XML(xml)
|
444
|
+
node = n_xml.xpath("//blockBuildWhenUpstreamBuilding").first
|
445
|
+
if node.content == "false"
|
446
|
+
node.content = "true"
|
447
|
+
xml_modified = n_xml.to_xml
|
448
|
+
post_config(job_name, xml_modified)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
# Unblock the build of the job when upstream is building
|
453
|
+
#
|
454
|
+
# @param [String] job_name
|
455
|
+
#
|
456
|
+
def unblock_build_when_upstream_building(job_name)
|
457
|
+
xml = get_config(job_name)
|
458
|
+
n_xml = Nokogiri::XML(xml)
|
459
|
+
node = n_xml.xpath("//blockBuildWhenUpstreamBuilding").first
|
460
|
+
if node.content == "true"
|
461
|
+
node.content = "false"
|
462
|
+
xml_modified = n_xml.to_xml
|
463
|
+
post_config(job_name, xml_modified)
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
# Allow to either execute concurrent builds or disable concurrent execution
|
468
|
+
#
|
469
|
+
# @param [String] job_name
|
470
|
+
# @param [Bool] option true or false
|
471
|
+
#
|
472
|
+
def execute_concurrent_builds(job_name, option)
|
473
|
+
xml = get_config(job_name)
|
474
|
+
n_xml = Nokogiri::XML(xml)
|
475
|
+
node = n_xml.xpath("//concurrentBuild").first
|
476
|
+
if node.content != "#{option}"
|
477
|
+
node.content = option == true ? "true" : "false"
|
478
|
+
xml_modified = n_xml.to_xml
|
479
|
+
post_config(job_name, xml_modified)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
# Obtain the build parameters of a job. It returns an array of hashes with
|
484
|
+
# details of job params.
|
485
|
+
#
|
486
|
+
# @param [String] job_name
|
487
|
+
#
|
488
|
+
# @return [Array] params_array
|
489
|
+
#
|
490
|
+
def get_build_params(job_name)
|
491
|
+
xml = get_config(job_name)
|
492
|
+
n_xml = Nokogiri::XML(xml)
|
493
|
+
params = n_xml.xpath("//parameterDefinitions").first
|
494
|
+
params_array = []
|
495
|
+
if params
|
496
|
+
params.children.each do |param|
|
497
|
+
param_hash = {}
|
498
|
+
case param.name
|
499
|
+
when "hudson.model.StringParameterDefinition", "hudson.model.BooleanParameterDefinition", "hudson.model.TextParameterDefinition", "hudson.model.PasswordParameterDefinition"
|
500
|
+
param_hash[:type] = 'string' if param.name =~ /string/i
|
501
|
+
param_hash[:type] = 'boolean' if param.name =~ /boolean/i
|
502
|
+
param_hash[:type] = 'text' if param.name =~ /text/i
|
503
|
+
param_hash[:type] = 'password' if param.name =~ /password/i
|
504
|
+
param.children.each do |value|
|
505
|
+
param_hash[:name] = value.content if value.name == "name"
|
506
|
+
param_hash[:description] = value.content if value.name == "description"
|
507
|
+
param_hash[:default] = value.content if value.name == "defaultValue"
|
508
|
+
end
|
509
|
+
when "hudson.model.RunParameterDefinition"
|
510
|
+
param_hash[:type] = 'run'
|
511
|
+
param.children.each do |value|
|
512
|
+
param_hash[:name] = value.content if value.name == "name"
|
513
|
+
param_hash[:description] = value.content if value.name == "description"
|
514
|
+
param_hash[:project] = value.content if value.name == "projectName"
|
515
|
+
end
|
516
|
+
when "hudson.model.FileParameterDefinition"
|
517
|
+
param_hash[:type] = 'file'
|
518
|
+
param.children.each do |value|
|
519
|
+
param_hash[:name] = value.content if value.name == "name"
|
520
|
+
param_hash[:description] = value.content if value.name == "description"
|
521
|
+
end
|
522
|
+
when "hudson.scm.listtagsparameter.ListSubversionTagsParameterDefinition"
|
523
|
+
param_hash[:type] = 'list_tags'
|
524
|
+
param.children.each do |value|
|
525
|
+
param_hash[:name] = value.content if value.name == "name"
|
526
|
+
param_hash[:description] = value.content if value.name == "description"
|
527
|
+
param_hash[:tags_dir] = value.content if value.name == "tagsDir"
|
528
|
+
param_hash[:tags_filter] = value.content if value.name == "tagsFilter"
|
529
|
+
param_hash[:reverse_by_date] = value.content if value.name == "reverseByDate"
|
530
|
+
param_hash[:reverse_by_name] = value.content if value.name == "reverseByName"
|
531
|
+
param_hash[:default] = value.content if value.name == "defaultValue"
|
532
|
+
param_hash[:max_tags] = value.content if value.name == "maxTags"
|
533
|
+
param_hash[:uuid] = value.content if value.name == "uuid"
|
534
|
+
end
|
535
|
+
when "hudson.model.ChoiceParameterDefinition"
|
536
|
+
param_hash[:type] = 'choice'
|
537
|
+
param.children.each do |value|
|
538
|
+
param_hash[:name] = value.content if value.name == "name"
|
539
|
+
param_hash[:description] = value.content if value.name == "description"
|
540
|
+
choices = []
|
541
|
+
if value.name == "choices"
|
542
|
+
value.children.each do |value_child|
|
543
|
+
if value_child.name == "a"
|
544
|
+
value_child.children.each do |choice_child|
|
545
|
+
choices << choice_child.content.strip unless choice_child.content.strip.empty?
|
546
|
+
end
|
547
|
+
end
|
548
|
+
end
|
549
|
+
end
|
550
|
+
param_hash[:choices] = choices unless choices.empty?
|
551
|
+
end
|
552
|
+
end
|
553
|
+
params_array << param_hash unless param_hash.empty?
|
554
|
+
end
|
555
|
+
end
|
556
|
+
params_array
|
557
|
+
end
|
558
|
+
|
559
|
+
# Obtains the threshold params used by jenkins in the XML file given the threshold
|
560
|
+
#
|
561
|
+
# @param [String] threshold success, failure, or unstable
|
562
|
+
#
|
563
|
+
def get_threshold_params(threshold)
|
280
564
|
case threshold
|
281
565
|
when 'success'
|
282
566
|
name = 'SUCCESS'
|
@@ -291,6 +575,19 @@ module JenkinsApi
|
|
291
575
|
ordinal = 2
|
292
576
|
color = 'RED'
|
293
577
|
end
|
578
|
+
return name, ordinal, color
|
579
|
+
end
|
580
|
+
|
581
|
+
# Add downstream projects to a specific job given the job name, projects to be
|
582
|
+
# added as downstream projects, and the threshold
|
583
|
+
#
|
584
|
+
# @param [String] job_name
|
585
|
+
# @param [String] downstream_projects
|
586
|
+
# @param [String] threshold - failure, success, or unstable
|
587
|
+
# @param [Bool] overwrite - true or false
|
588
|
+
#
|
589
|
+
def add_downstream_projects(job_name, downstream_projects, threshold, overwrite = false)
|
590
|
+
name, ordinal, color = get_threshold_params(threshold)
|
294
591
|
xml = get_config(job_name)
|
295
592
|
n_xml = Nokogiri::XML(xml)
|
296
593
|
child_projects_node = n_xml.xpath("//childProjects").first
|
@@ -318,24 +615,24 @@ module JenkinsApi
|
|
318
615
|
def remove_downstream_projects(job_name)
|
319
616
|
xml = get_config(job_name)
|
320
617
|
n_xml = Nokogiri::XML(xml)
|
321
|
-
n_xml.search("//hudson.tasks.BuildTrigger").each
|
618
|
+
n_xml.search("//hudson.tasks.BuildTrigger").each do |node|
|
322
619
|
child_project_trigger = false
|
323
|
-
node.search("//childProjects").each
|
620
|
+
node.search("//childProjects").each do |child_node|
|
324
621
|
child_project_trigger = true
|
325
|
-
child_node.search("//threshold").each
|
326
|
-
threshold_node.children.each
|
622
|
+
child_node.search("//threshold").each do |threshold_node|
|
623
|
+
threshold_node.children.each do |threshold_value_node|
|
327
624
|
threshold_value_node.content = nil
|
328
625
|
threshold_value_node.remove
|
329
|
-
|
626
|
+
end
|
330
627
|
threshold_node.content = nil
|
331
628
|
threshold_node.remove
|
332
|
-
|
629
|
+
end
|
333
630
|
child_node.content = nil
|
334
631
|
child_node.remove
|
335
|
-
|
632
|
+
end
|
336
633
|
node.content = nil
|
337
634
|
node.remove
|
338
|
-
|
635
|
+
end
|
339
636
|
publisher_node = n_xml.search("//publishers").first
|
340
637
|
publisher_node.content = nil if publisher_node.children.empty?
|
341
638
|
xml_modified = n_xml.to_xml
|
@@ -388,15 +685,15 @@ module JenkinsApi
|
|
388
685
|
filtered_job_names = job_names
|
389
686
|
else
|
390
687
|
puts "[INFO] Criteria is specified. Filtering jobs..." if @client.debug
|
391
|
-
job_names.each
|
688
|
+
job_names.each do |job|
|
392
689
|
filtered_job_names << job if criteria.include?(@client.job.get_current_build_status(job))
|
393
|
-
|
690
|
+
end
|
394
691
|
end
|
395
|
-
filtered_job_names.each_with_index
|
692
|
+
filtered_job_names.each_with_index do |job_name, index|
|
396
693
|
break if index >= (filtered_job_names.length - parallel)
|
397
694
|
puts "[INFO] Adding <#{filtered_job_names[index+1]}> as a downstream project to <#{job_name}> with <#{threshold}> as the threshold" if @client.debug
|
398
695
|
@client.job.add_downstream_projects(job_name, filtered_job_names[index + parallel], threshold, true)
|
399
|
-
|
696
|
+
end
|
400
697
|
parallel = filtered_job_names.length if parallel > filtered_job_names.length
|
401
698
|
filtered_job_names[0..parallel-1]
|
402
699
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Kannan Manickam <arangamani.kannan@gmail.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
module JenkinsApi
|
24
|
+
class Client
|
25
|
+
class View
|
26
|
+
|
27
|
+
# Initializes a new view object
|
28
|
+
#
|
29
|
+
# @param [Object] client reference to Client
|
30
|
+
#
|
31
|
+
def initialize(client)
|
32
|
+
@client = client
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return a string representation of the object
|
36
|
+
#
|
37
|
+
def to_s
|
38
|
+
"#<JenkinsApi::Client::View>"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Create a new view
|
42
|
+
#
|
43
|
+
# @param [String] view_name
|
44
|
+
#
|
45
|
+
def create(view_name)
|
46
|
+
@client.api_post_request("/createView?name=#{view_name}&mode=hudson.model.ListView&json={\"name\":\"#{view_name}\",\"mode\":\"hudson.model.ListView\"}")
|
47
|
+
end
|
48
|
+
|
49
|
+
# Delete a view
|
50
|
+
#
|
51
|
+
# @param [String] view_name
|
52
|
+
#
|
53
|
+
def delete(view_name)
|
54
|
+
@client.api_post_request("/view/#{view_name}/doDelete")
|
55
|
+
end
|
56
|
+
|
57
|
+
# This method lists all views
|
58
|
+
#
|
59
|
+
# @param [String] filter a regex to filter view names
|
60
|
+
# @param [Bool] ignorecase whether to be case sensitive or not
|
61
|
+
#
|
62
|
+
def list(filter = nil, ignorecase = true)
|
63
|
+
view_names = []
|
64
|
+
response_json = @client.api_get_request("/")
|
65
|
+
response_json["views"].each { |view|
|
66
|
+
view_names << view["name"] if view["name"] =~ /#{filter}/i
|
67
|
+
}
|
68
|
+
view_names
|
69
|
+
end
|
70
|
+
|
71
|
+
# Checks if the given view exists in Jenkins
|
72
|
+
#
|
73
|
+
# @param [String] view_name
|
74
|
+
#
|
75
|
+
def exists?(view_name)
|
76
|
+
list(view_name).include?(view_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
# List jobs in a view
|
80
|
+
#
|
81
|
+
# @param [String] view_name
|
82
|
+
#
|
83
|
+
def list_jobs(view_name)
|
84
|
+
job_names = []
|
85
|
+
response_json = @client.api_get_request("/view/#{view_name}")
|
86
|
+
response_json["jobs"].each do |job|
|
87
|
+
job_names << job["name"]
|
88
|
+
end
|
89
|
+
job_names
|
90
|
+
end
|
91
|
+
|
92
|
+
# Add a job to view
|
93
|
+
#
|
94
|
+
# @param [String] view_name
|
95
|
+
# @param [String] job_name
|
96
|
+
#
|
97
|
+
def add_job(view_name, job_name)
|
98
|
+
@client.api_post_request("/view/#{view_name}/addJobToView?name=#{job_name}")
|
99
|
+
end
|
100
|
+
|
101
|
+
# Remove a job from view
|
102
|
+
#
|
103
|
+
# @param [String] view_name
|
104
|
+
# @param [String] job_name
|
105
|
+
#
|
106
|
+
def remove_job(view_name, job_name)
|
107
|
+
@client.api_post_request("/view/#{view_name}/removeJobFromView?name=#{job_name}")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Obtain the configuration stored in config.xml of a specific view
|
111
|
+
#
|
112
|
+
# @param [String] view_name
|
113
|
+
#
|
114
|
+
def get_config(view_name)
|
115
|
+
@client.get_config("/view/#{view_name}")
|
116
|
+
end
|
117
|
+
|
118
|
+
# Post the configuration of a view given the view name and the config.xml
|
119
|
+
#
|
120
|
+
# @param [String] view_name
|
121
|
+
# @param [String] xml
|
122
|
+
#
|
123
|
+
def post_config(view_name, xml)
|
124
|
+
@client.post_config("/view/#{view_name}/config.xml", xml)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/spec/job_spec.rb
CHANGED
@@ -117,16 +117,16 @@ describe JenkinsApi::Client::Job do
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
it "Should be able to abort a recent build of a running job" do
|
121
|
-
@client.job.get_current_build_status(@job_name).should_not == "running"
|
122
|
-
@client.job.build(@job_name)
|
123
|
-
sleep 20
|
124
|
-
@client.job.get_current_build_status(@job_name).should == "running"
|
125
|
-
sleep 20
|
126
|
-
@client.job.stop_build(@job_name).should == 302
|
127
|
-
sleep 20
|
128
|
-
@client.job.get_current_build_status(@job_name).should == "aborted"
|
129
|
-
end
|
120
|
+
# it "Should be able to abort a recent build of a running job" do
|
121
|
+
# @client.job.get_current_build_status(@job_name).should_not == "running"
|
122
|
+
# @client.job.build(@job_name)
|
123
|
+
# sleep 20
|
124
|
+
# @client.job.get_current_build_status(@job_name).should == "running"
|
125
|
+
# sleep 20
|
126
|
+
# @client.job.stop_build(@job_name).should == 302
|
127
|
+
# sleep 20
|
128
|
+
# @client.job.get_current_build_status(@job_name).should == "aborted"
|
129
|
+
# end
|
130
130
|
|
131
131
|
it "Should be able to restrict a job to a node" do
|
132
132
|
@client.job.restrict_to_node(@job_name, 'master').to_i.should == 200
|
metadata
CHANGED
@@ -1,186 +1,189 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: jenkins_api_client
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 0
|
10
|
-
version: 0.4.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Kannan Manickam
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
prerelease: false
|
22
|
-
type: :runtime
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
|
-
requirements:
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 3
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
version: "0"
|
32
|
-
version_requirements: *id001
|
12
|
+
date: 2012-12-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
33
15
|
name: nokogiri
|
34
|
-
|
35
|
-
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
36
22
|
type: :runtime
|
37
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
38
33
|
none: false
|
39
|
-
requirements:
|
34
|
+
requirements:
|
40
35
|
- - ~>
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
hash: 31
|
43
|
-
segments:
|
44
|
-
- 3
|
45
|
-
- 2
|
46
|
-
- 8
|
36
|
+
- !ruby/object:Gem::Version
|
47
37
|
version: 3.2.8
|
48
|
-
version_requirements: *id002
|
49
|
-
name: activesupport
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
prerelease: false
|
52
38
|
type: :runtime
|
53
|
-
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
41
|
none: false
|
55
|
-
requirements:
|
42
|
+
requirements:
|
56
43
|
- - ~>
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
|
60
|
-
- 0
|
61
|
-
- 16
|
62
|
-
- 0
|
63
|
-
version: 0.16.0
|
64
|
-
version_requirements: *id003
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.2.8
|
46
|
+
- !ruby/object:Gem::Dependency
|
65
47
|
name: thor
|
66
|
-
|
67
|
-
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.16.0
|
68
54
|
type: :runtime
|
69
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
-
none: false
|
71
|
-
requirements:
|
72
|
-
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
hash: 3
|
75
|
-
segments:
|
76
|
-
- 0
|
77
|
-
version: "0"
|
78
|
-
version_requirements: *id004
|
79
|
-
name: json
|
80
|
-
- !ruby/object:Gem::Dependency
|
81
55
|
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.16.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: json
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
82
70
|
type: :runtime
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
- 4
|
92
|
-
- 0
|
93
|
-
version: 1.4.0
|
94
|
-
version_requirements: *id005
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
95
79
|
name: terminal-table
|
96
|
-
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.4.0
|
86
|
+
type: :runtime
|
97
87
|
prerelease: false
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
segments:
|
106
|
-
- 1
|
107
|
-
- 0
|
108
|
-
version: "1.0"
|
109
|
-
version_requirements: *id006
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.4.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
110
95
|
name: bundler
|
111
|
-
|
112
|
-
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '1.0'
|
113
102
|
type: :development
|
114
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
|
-
requirements:
|
117
|
-
- - ">="
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
hash: 7
|
120
|
-
segments:
|
121
|
-
- 1
|
122
|
-
- 6
|
123
|
-
- 4
|
124
|
-
version: 1.6.4
|
125
|
-
version_requirements: *id007
|
126
|
-
name: jeweler
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
103
|
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: jeweler
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.6.4
|
129
118
|
type: :development
|
130
|
-
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
131
121
|
none: false
|
132
|
-
requirements:
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.6.4
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: builder
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
133
131
|
- - ~>
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
hash: 5
|
136
|
-
segments:
|
137
|
-
- 3
|
138
|
-
- 1
|
139
|
-
- 3
|
132
|
+
- !ruby/object:Gem::Version
|
140
133
|
version: 3.1.3
|
141
|
-
version_requirements: *id008
|
142
|
-
name: builder
|
143
|
-
- !ruby/object:Gem::Dependency
|
144
|
-
prerelease: false
|
145
134
|
type: :development
|
146
|
-
requirement: &id009 !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
|
-
requirements:
|
149
|
-
- - ">="
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
hash: 3
|
152
|
-
segments:
|
153
|
-
- 0
|
154
|
-
version: "0"
|
155
|
-
version_requirements: *id009
|
156
|
-
name: simplecov
|
157
|
-
- !ruby/object:Gem::Dependency
|
158
135
|
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 3.1.3
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: simplecov
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
159
150
|
type: :development
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
version: "0"
|
169
|
-
version_requirements: *id010
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
170
159
|
name: rspec
|
171
|
-
|
172
|
-
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
description: ! '
|
175
|
+
|
173
176
|
This is a simple and easy-to-use Jenkins Api client with features focused on
|
174
|
-
|
175
|
-
|
177
|
+
|
178
|
+
automating Job configuration programaticaly and so forth'
|
179
|
+
email:
|
176
180
|
- arangamani.kannan@gmail.com
|
177
|
-
executables:
|
181
|
+
executables:
|
178
182
|
- jenkinscli
|
179
183
|
extensions: []
|
180
|
-
|
181
|
-
extra_rdoc_files:
|
184
|
+
extra_rdoc_files:
|
182
185
|
- CHANGELOG.rdoc
|
183
|
-
files:
|
186
|
+
files:
|
184
187
|
- .gitignore
|
185
188
|
- .travis.yml
|
186
189
|
- CHANGELOG.rdoc
|
@@ -202,6 +205,7 @@ files:
|
|
202
205
|
- lib/jenkins_api_client/node.rb
|
203
206
|
- lib/jenkins_api_client/system.rb
|
204
207
|
- lib/jenkins_api_client/version.rb
|
208
|
+
- lib/jenkins_api_client/view.rb
|
205
209
|
- scripts/login_with_irb.rb
|
206
210
|
- spec/client_spec.rb
|
207
211
|
- spec/job_spec.rb
|
@@ -210,36 +214,26 @@ files:
|
|
210
214
|
- spec/system_spec.rb
|
211
215
|
homepage: https://github.com/arangamani/jenkins_api_client
|
212
216
|
licenses: []
|
213
|
-
|
214
217
|
post_install_message:
|
215
218
|
rdoc_options: []
|
216
|
-
|
217
|
-
require_paths:
|
219
|
+
require_paths:
|
218
220
|
- lib
|
219
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
221
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
220
222
|
none: false
|
221
|
-
requirements:
|
222
|
-
- -
|
223
|
-
- !ruby/object:Gem::Version
|
224
|
-
|
225
|
-
|
226
|
-
- 0
|
227
|
-
version: "0"
|
228
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - ! '>='
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
228
|
none: false
|
230
|
-
requirements:
|
231
|
-
- -
|
232
|
-
- !ruby/object:Gem::Version
|
233
|
-
|
234
|
-
segments:
|
235
|
-
- 0
|
236
|
-
version: "0"
|
229
|
+
requirements:
|
230
|
+
- - ! '>='
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: '0'
|
237
233
|
requirements: []
|
238
|
-
|
239
234
|
rubyforge_project:
|
240
235
|
rubygems_version: 1.8.24
|
241
236
|
signing_key:
|
242
237
|
specification_version: 3
|
243
238
|
summary: Jenkins JSON API Client
|
244
239
|
test_files: []
|
245
|
-
|