Class: JenkinsApi::Client::Job

Inherits:
Object
  • Object
show all
Includes:
UriHelper
Defined in:
lib/improved_jenkins_client/job.rb

Overview

This class communicates with the Jenkins “/job” API to obtain details about jobs, creating, deleting, building, and various other operations.

Constant Summary collapse

JENKINS_QUEUE_ID_SUPPORT_VERSION =

Version that jenkins started to include queued build info in build response

'1.519'

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from UriHelper

#form_encode, #path_encode

Constructor Details

#initialize(client, *plugin_settings) ⇒ Job

Initialize the Job object and store the reference to Client object

Parameters:

  • client (Client)

    the client object



44
45
46
47
48
# File 'lib/improved_jenkins_client/job.rb', line 44

def initialize(client, *plugin_settings)
  @client = client
  @logger = @client.logger
  @plugin_collection = JenkinsApi::Client::PluginSettings::Collection.new(*plugin_settings)
end

Instance Attribute Details

#plugin_collectionObject (readonly)

Returns the value of attribute plugin_collection.



36
37
38
# File 'lib/improved_jenkins_client/job.rb', line 36

def plugin_collection
  @plugin_collection
end

Instance Method Details

#add_downstream_projects(job_name, downstream_projects, threshold, overwrite = false) ⇒ String

Add downstream projects to a specific job given the job name, projects to be added as downstream projects, and the threshold

Parameters:

  • job_name (String)
  • downstream_projects (String)
  • threshold (String)
    • failure, success, or unstable

  • overwrite (Boolean) (defaults to: false)
    • true or false

Returns:

  • (String)

    response_code return code from HTTP POST



1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
# File 'lib/improved_jenkins_client/job.rb', line 1435

def add_downstream_projects(job_name,
                            downstream_projects,
                            threshold, overwrite = false)
  @logger.info "Adding #{downstream_projects.inspect} as downstream" +
    " projects for '#{job_name}' with the threshold of '#{threshold}'" +
    " and overwrite option of '#{overwrite}'"
  name, ord, col = get_threshold_params(threshold)
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  child_projects_node = n_xml.xpath("//childProjects").first
  if child_projects_node
    if overwrite
      child_projects_node.content = "#{downstream_projects}"
    else
      to_replace = child_projects_node.content +
        ", #{downstream_projects}"
      child_projects_node.content = to_replace
    end
  else
    publisher_node = n_xml.xpath("//publishers").first
    build_trigger_node = publisher_node.add_child(
      "<hudson.tasks.BuildTrigger/>"
    )
    child_project_node = build_trigger_node.first.add_child(
      "<childProjects>#{downstream_projects}</childProjects>"
    )
    threshold_node = child_project_node.first.add_next_sibling(
      "<threshold/>"
    )
    threshold_node.first.add_child(
      "<name>#{name}</name><ordinal>#{ord}</ordinal><color>#{col}</color>"
    )
  end
  xml_modified = n_xml.to_xml
  post_config(job_name, xml_modified)
end

#add_email_notification(params) ⇒ Object

Adding email notification to a job

Parameters:

  • params (Hash)

    parameters to add email notification

Options Hash (params):

  • :name (String)

    Name of the job

  • :notification_email (String)

    Email address to send

  • :notification_email_for_every_unstable (Boolean)

    Send email notification email for every unstable build



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/improved_jenkins_client/job.rb', line 388

def add_email_notification(params)
  raise "No job name specified" unless params[:name]
  raise "No email address specified" unless params[:notification_email]
  @logger.info "Adding '#{params[:notification_email]}' to be" +
    " notified for '#{params[:name]}'"
  xml = get_config(params[:name])
  n_xml = Nokogiri::XML(xml)
  if n_xml.xpath("//hudson.tasks.Mailer").empty?
    p_xml = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |b_xml|
      notification_email(params, b_xml)
    end
    email_xml = Nokogiri::XML(p_xml.to_xml).xpath(
      "//hudson.tasks.Mailer"
    ).first
    n_xml.xpath("//publishers").first.add_child(email_xml)
    post_config(params[:name], n_xml.to_xml)
  end
end

#add_plugin(plugin) ⇒ JenkinsApi::Client::PluginSettings::Collection

Add a plugin to be included in job’s xml configureation

Parameters:

  • plugin (Jenkins::Api::Client::PluginSettings::Base)

Returns:



55
56
57
# File 'lib/improved_jenkins_client/job.rb', line 55

def add_plugin(plugin)
  plugin_collection.add(plugin)
end

#add_skype_notification(params) ⇒ Object

Adding skype notificaiton to a job

Parameters:

  • params (Hash)

    parameters for adding skype notification

    • :name name of the job to add skype notification

    • :skype_targets skype targets for sending notifications to. Use * to specify group chats. Use space to separate multiple targets. Example: testuser, *testgroup.

    • :skype_strategy skype strategy to be used for sending notifications. Valid values: all, failure, failure_and_fixed, change. Default: change.

    • :skype_notify_on_build_start Default: false

    • :skype_notify_suspects Default: false

    • :skype_notify_culprits Default: false

    • :skype_notify_fixers Default: false

    • :skype_notify_upstream_committers Default: false

    • :skype_message what should be sent as notification message. Valid: just_summary, summary_and_scm_changes, summary_and_build_parameters, summary_scm_changes_and_failed_tests. Default: summary_and_scm_changes



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
# File 'lib/improved_jenkins_client/job.rb', line 427

def add_skype_notification(params)
  raise "No job name specified" unless params[:name]
  raise "No Skype target specified" unless params[:skype_targets]
  @logger.info "Adding Skype notification for '#{params[:name]}'"
  xml = get_config(params[:name])
  n_xml = Nokogiri::XML(xml)
  if n_xml.xpath("//hudson.plugins.skype.im.transport.SkypePublisher").empty?
    p_xml = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |b_xml|
      skype_notification(params, b_xml)
    end
    skype_xml = Nokogiri::XML(p_xml.to_xml).xpath(
      "//hudson.plugins.skype.im.transport.SkypePublisher"
    ).first
    n_xml.xpath("//publishers").first.add_child(skype_xml)
    post_config(params[:name], n_xml.to_xml)
  end
end

#add_upstream_projects(job_name, upstream_projects, threshold, overwrite = false) ⇒ String

Add upstream projects to a specific job given the job name, projects to be added as upstream projects, and the threshold

Parameters:

  • job_name (String)
  • upstream_projects (String)
    • separated with comma

  • threshold (String)
    • failure, success, or unstable

  • overwrite (Boolean) (defaults to: false)
    • true or false

Returns:

  • (String)

    response_code return code from HTTP POST



1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
# File 'lib/improved_jenkins_client/job.rb', line 1516

def add_upstream_projects(job_name,
                          upstream_projects,
                          threshold, overwrite = false)
  @logger.info "Adding #{upstream_projects.inspect} as upstream" +
                   " projects for '#{job_name}' with the threshold of '#{threshold}'" +
                   " and overwrite option of '#{overwrite}'"
  name, ord, col = get_threshold_params(threshold)
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  upstream_projects_node = n_xml.xpath("//upstreamProjects").first
  if upstream_projects_node
    if overwrite
      upstream_projects_node.content = "#{upstream_projects}"
    else
      to_replace = upstream_projects_node.content +
          ", #{upstream_projects}"
      upstream_projects_node.content = to_replace
    end
  else
    triggers_node = n_xml.xpath("//triggers").first
    reverse_build_trigger_node = triggers_node.add_child(
        "<jenkins.triggers.ReverseBuildTrigger/>"
    )
    reverse_build_trigger_node.first.add_child(
        "<spec/>"
    )
    reverse_build_trigger_node.first.add_child(
        "<upstreamProjects>#{upstream_projects}</upstreamProjects>"
    )
    threshold_node = reverse_build_trigger_node.first.add_child(
        "<threshold/>"
    )
    threshold_node.first.add_child(
        "<name>#{name}</name><ordinal>#{ord}</ordinal><color>#{col}</color>"
    )
  end
  xml_modified = n_xml.to_xml
  post_config(job_name, xml_modified)
end

#artifact_archiver(artifact_params, xml) ⇒ Nokogiri::XML::Builder

Configure post-build step to archive artifacts

Parameters:

  • artifact_params (Hash)

    parameters controlling how artifacts are archived

Options Hash (artifact_params):

  • :artifact_files (String)

    pattern or names of files to archive

  • :excludes (String)

    pattern or names of files to exclude

  • :fingerprint (Boolean) — default: false

    fingerprint the archives

  • :allow_empty_archive (Boolean) — default: false

    whether to allow empty archives

  • :only_if_successful (Boolean) — default: false

    only archive if successful

  • :default_excludes (Boolean) — default: false

    exclude defaults automatically

Returns:

  • (Nokogiri::XML::Builder)


464
465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/improved_jenkins_client/job.rb', line 464

def artifact_archiver(artifact_params, xml)
  return xml if artifact_params.nil?

  xml.send('hudson.tasks.ArtifactArchiver') do |x|
    x.artifacts artifact_params.fetch(:artifact_files) { '' }
    x.excludes artifact_params.fetch(:excludes) { '' }
    x.fingerprint artifact_params.fetch(:fingerprint) { false }
    x.allowEmptyArchive artifact_params.fetch(:allow_empty_archive) { false }
    x.onlyIfSuccessful artifact_params.fetch(:only_if_successful) { false }
    x.defaultExcludes artifact_params.fetch(:default_excludes) { false }
  end

  xml
end

#artifact_exists?(job_name, build_number = 0) ⇒ Boolean

A Method to check artifact exists path from the Current Build

Parameters:

  • job_name (String)
  • build_number (Integer) (defaults to: 0)

    defaults to latest build

Returns:

  • (Boolean)


1731
1732
1733
1734
1735
1736
1737
1738
1739
# File 'lib/improved_jenkins_client/job.rb', line 1731

def artifact_exists?(job_name, build_number = 0)
  begin
    artifact_path(job_name: job_name, build_number: build_number)

    return true
  rescue Exception => e
    return false
  end
end

#block_build_when_downstream_building(job_name) ⇒ String

Block the build of the job when downstream is building

Parameters:

  • job_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
# File 'lib/improved_jenkins_client/job.rb', line 1229

def block_build_when_downstream_building(job_name)
  @logger.info "Blocking builds of '#{job_name}' when downstream" +
    " projects are building"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  node = n_xml.xpath("//blockBuildWhenDownstreamBuilding").first
  if node.content == "false"
    node.content = "true"
    xml_modified = n_xml.to_xml
    post_config(job_name, xml_modified)
  end
end

#block_build_when_upstream_building(job_name) ⇒ String

Block the build of the job when upstream is building

Parameters:

  • job_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
# File 'lib/improved_jenkins_client/job.rb', line 1267

def block_build_when_upstream_building(job_name)
  @logger.info "Blocking builds of '#{job_name}' when upstream" +
    " projects are building"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  node = n_xml.xpath("//blockBuildWhenUpstreamBuilding").first
  if node.content == "false"
    node.content = "true"
    xml_modified = n_xml.to_xml
    post_config(job_name, xml_modified)
  end
end

#build(job_name, params = {}, opts = {}) ⇒ Integer, String

Build a Jenkins job, optionally waiting for build to start and returning the build number. Adds support for new/old Jenkins servers where build_queue id may not be available. Also adds support for periodic callbacks, and optional cancellation of queued_job if not started within allowable time window (if build_queue option available)

Notes:
  'opts' may be a 'true' or 'false' value to maintain
    compatibility with old method signature, where true indicates
  'return_build_number'. In this case, true is translated to:
    { 'build_start_timeout' => @client_timeout }
    which simulates earlier behavior.

progress_proc
  Optional proc that is called periodically while waiting for
  build to start.
  Initial call (with poll_count == 0) indicates build has been
  requested, and that polling is starting.
  Final call will indicate one of build_started or cancelled.
  params:
    max_wait [Integer] Same as opts['build_start_timeout']
    current_wait [Integer]
    poll_count [Integer] How many times has queue been polled

completion_proc
  Optional proc that is called <just before> the 'build' method
  exits.
  params:
    build_number [Integer]  Present if build started or nil
    build_cancelled [Boolean]  True if build timed out and was
      successfully removed from build-queue

Parameters:

  • job_name (String)

    the name of the job

  • params (Hash) (defaults to: {})

    the parameters for parameterized build

  • opts (Hash) (defaults to: {})

    options for this method

    • build_start_timeout [Integer] How long to wait for queued build to start before giving up. Default: 0/nil

    • cancel_on_build_start_timeout [Boolean] Should an attempt be made to cancel the queued build if it hasn’t started within ‘build_start_timeout’ seconds? This only works on newer versions of Jenkins where JobQueue is exposed in build post response. Default: false

    • poll_interval [Integer] How often should we check with CI Server while waiting for start. Default: 2 (seconds)

    • progress_proc [Proc] A proc that will receive progress notitications. Default: nil

    • completion_proc [Proc] A proc that is called <just before> this method (build) exits. Default: nil

Returns:

  • (Integer)

    build number, or nil if not started (IF TIMEOUT SPECIFIED)

  • (String)

    HTTP response code (per prev. behavior) (NO TIMEOUT SPECIFIED)



918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
# File 'lib/improved_jenkins_client/job.rb', line 918

def build(job_name, params={}, opts = {})
  if opts.nil? || opts.is_a?(FalseClass)
    opts = {}
  elsif opts.is_a?(TrueClass)
    opts = { 'build_start_timeout' => @client_timeout }
  end

  opts['job_name'] = job_name

  msg = "Building job '#{job_name}'"
  msg << " with parameters: #{params.inspect}" unless params.empty?
  @logger.info msg

  if (opts['build_start_timeout'] || 0) > 0
    # Best-guess build-id
    # This is only used if we go the old-way below... but we can use this number to detect if multiple
    # builds were queued
    current_build_id = get_current_build_number(job_name)
    expected_build_id = current_build_id > 0 ? current_build_id + 1 : 1
  end

  if (params.nil? or params.empty?)
    response = @client.api_post_request("/job/#{path_encode job_name}/build",
      {},
      true)
  else
    response = @client.api_post_request("/job/#{path_encode job_name}/buildWithParameters",
      params,
      true)
  end

  if (opts['build_start_timeout'] || 0) > 0
    if @client.compare_versions(@client.get_jenkins_version, JENKINS_QUEUE_ID_SUPPORT_VERSION) >= 0
      return get_build_id_from_queue(response, expected_build_id, opts)
    else
      return get_build_id_the_old_way(expected_build_id, opts)
    end
  else
    return response.code
  end
end

#build_freestyle_config(params) ⇒ String

Builds the XML configuration based on the parameters passed as a Hash

Parameters:

  • params (Hash)

    the parameters for building XML configuration

Returns:

  • (String)

    the generated XML configuration of the project

Raises:

  • (ArgumentError)


250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/improved_jenkins_client/job.rb', line 250

def build_freestyle_config(params)
  # Supported SCM providers
  supported_scm = ["git", "subversion", "cvs"]

  # Set default values for params that are not specified.
  raise ArgumentError, "Job name must be specified" \
    unless params.is_a?(Hash) && params[:name]

  [
    :keep_dependencies,
    :block_build_when_downstream_building,
    :block_build_when_upstream_building,
    :concurrent_build
  ].each do |param|
    params[param] = false if params[param].nil?
  end

  if params[:notification_email]
    if params[:notification_email_for_every_unstable].nil?
      params[:notification_email_for_every_unstable] = false
    end
    if params[:notification_email_send_to_individuals].nil?
      params[:notification_email_send_to_individuals] ||= false
    end
  end

  # SCM configurations and Error handling.
  unless params[:scm_provider].nil?
    unless supported_scm.include?(params[:scm_provider])
      raise "SCM #{params[:scm_provider]} is currently not supported"
    end
    raise "SCM URL must be specified" if params[:scm_url].nil?
    params[:scm_branch] = "master" if params[:scm_branch].nil?
    if params[:scm_use_head_if_tag_not_found].nil?
      params[:scm_use_head_if_tag_not_found] = false
    end
  end

  # Child projects configuration and Error handling
  if params[:child_threshold].nil? && !params[:child_projects].nil?
    params[:child_threshold] = "failure"
  end

  @logger.debug "Creating a freestyle job with params: #{params.inspect}"

  # Build the Job xml file based on the parameters given
  builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
    xml.project do
      xml.actions
      xml.description
      xml.keepDependencies "#{params[:keep_dependencies]}"
      xml.properties
      #buildlogs related stuff
      if params[:discard_old_builds]
        xml.logRotator(:class => 'hudson.tasks.LogRotator') do
          xml.daysToKeep params[:discard_old_builds][:daysToKeep] || -1
          xml.numToKeep params[:discard_old_builds][:numToKeep] || -1
          xml.artifactDaysToKeep params[:discard_old_builds][:artifactDaysToKeep] || -1
          xml.artifactNumToKeep params[:discard_old_builds][:artifactNumToKeep] || -1
        end
      end

      # SCM related stuff
      if params[:scm_provider] == 'subversion'
        # Build subversion related XML portion
        scm_subversion(params, xml)
      elsif params[:scm_provider] == "cvs"
        # Build CVS related XML portion
        scm_cvs(params, xml)
      elsif params[:scm_provider] == "git"
        # Build Git related XML portion
        scm_git(params, xml)
      else
        xml.scm(:class => "hudson.scm.NullSCM")
      end
      # Restrict job to run in a specified node
      if params[:restricted_node]
        xml.assignedNode "#{params[:restricted_node]}"
        xml.canRoam "false"
      else
        xml.canRoam "true"
      end
      xml.disabled "false"
      xml.blockBuildWhenDownstreamBuilding(
        "#{params[:block_build_when_downstream_building]}")
      xml.blockBuildWhenUpstreamBuilding(
        "#{params[:block_build_when_upstream_building]}")
      xml.triggers.vector do
        if params[:timer]
          xml.send("hudson.triggers.TimerTrigger") do
            xml.spec params[:timer]
          end
        end

        if params[:scm_trigger]
          xml.send("hudson.triggers.SCMTrigger") do
            xml.spec params[:scm_trigger]
            xml.ignorePostCommitHooks params.fetch(:ignore_post_commit_hooks) { false }
          end
        end
      end
      xml.concurrentBuild "#{params[:concurrent_build]}"
      # Shell command stuff
      xml.builders do
        if params[:shell_command]
          xml.send("hudson.tasks.Shell") do
            xml.command "#{params[:shell_command]}"
          end
        end
      end
      # Adding Downstream projects
      xml.publishers do
        # Build portion of XML that adds child projects
        child_projects(params, xml) if params[:child_projects]
        # Build portion of XML that adds email notification
        notification_email(params, xml) if params[:notification_email]
        # Build portion of XML that adds skype notification
        skype_notification(params, xml) if params[:skype_targets]
        artifact_archiver(params[:artifact_archiver], xml)
      end
      xml.buildWrappers
    end
  end

  xml_doc = Nokogiri::XML(builder.to_xml)
  plugin_collection.configure(xml_doc).to_xml
end

#chain(job_names, threshold, criteria, parallel = 1) ⇒ Array

Chain the jobs given based on specified criteria

Parameters:

  • job_names (Array)

    Array of job names to be chained

  • threshold (String)

    threshold for running the next job

  • criteria (Array)

    criteria which should be applied for picking the jobs for the chain

  • parallel (Integer) (defaults to: 1)

    Number of jobs that should be considered for parallel run

Returns:

  • (Array)

    job_names Names of jobs that are in the top of the chain



1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
# File 'lib/improved_jenkins_client/job.rb', line 1614

def chain(job_names, threshold, criteria, parallel = 1)
  raise "Parallel jobs should be at least 1" if parallel < 1
  unchain(job_names)

  @logger.info "Chaining jobs: #{job_names.inspect}" +
    " with threshold of '#{threshold}' and criteria as '#{criteria}'" +
    " with #{parallel} number of parallel jobs"
  filtered_job_names = []
  if criteria.include?("all") || criteria.empty?
    filtered_job_names = job_names
  else
    job_names.each do |job|
      filtered_job_names << job if criteria.include?(
        @client.job.get_current_build_status(job)
      )
    end
  end

  filtered_job_names.each_with_index do |job_name, index|
    break if index >= (filtered_job_names.length - parallel)
    @client.job.add_downstream_projects(
      job_name, filtered_job_names[index + parallel], threshold, true
    )
  end
  if parallel > filtered_job_names.length
    parallel = filtered_job_names.length
  end
  filtered_job_names[0..parallel-1]
end

#change_description(job_name, description) ⇒ String

Change the description of a specific job

Parameters:

  • job_name (String)
  • description (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1213
1214
1215
1216
1217
1218
1219
1220
1221
# File 'lib/improved_jenkins_client/job.rb', line 1213

def change_description(job_name, description)
  @logger.info "Changing the description of '#{job_name}' to '#{description}'"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  desc = n_xml.xpath("//description").first
  desc.content = "#{description}"
  xml_modified = n_xml.to_xml
  post_config(job_name, xml_modified)
end

#color_to_status(color) ⇒ String

This method maps the color to status of a job

Parameters:

  • color (String)

    color given by the API for a job

Returns:

  • (String)

    status status of the given job matching the color



799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
# File 'lib/improved_jenkins_client/job.rb', line 799

def color_to_status(color)
  case color
  when "blue"
    "success"
  when "red"
    "failure"
  when "yellow"
    "unstable"
  when /anime/
    "running"
  # In the recent version of Jenkins (> 1.517), jobs that are not built
  # yet have a color of "notbuilt" instead of "grey". Include that to the
  # not_run condition so it is backward compatible.
  when "grey", "notbuilt"
    "not_run"
  when "aborted"
    "aborted"
  when "disabled"
    "disabled"
  else
    "invalid"
  end
end

#copy(from_job_name, to_job_name = nil) ⇒ String

Copy a job

Parameters:

  • from_job_name (String)

    the name of the job to copy from

  • to_job_name (String) (defaults to: nil)

    the name of the job to copy to

Returns:

  • (String)

    the response from the HTTP POST request



565
566
567
568
569
570
571
# File 'lib/improved_jenkins_client/job.rb', line 565

def copy(from_job_name, to_job_name=nil)
  to_job_name = "copy_of_#{from_job_name}" if to_job_name.nil?
  @logger.info "Copying job '#{from_job_name}' to '#{to_job_name}'"
  @client.api_post_request(
    "/createItem?name=#{path_encode to_job_name}&mode=copy&from=#{path_encode from_job_name}"
  )
end

#create(job_name, xml) ⇒ String

Create a job with the name specified and the xml given

Parameters:

  • job_name (String)

    the name of the job

  • xml (String)

    the xml configuration of the job

Returns:

  • (String)

    the HTTP status code from the POST request

See Also:



102
103
104
105
# File 'lib/improved_jenkins_client/job.rb', line 102

def create(job_name, xml)
  @logger.info "Creating job '#{job_name}'"
  @client.post_config("/createItem?name=#{form_encode job_name}", xml)
end

#create_freestyle(params) ⇒ String

Create a freestyle project by accepting a Hash of parameters. For the parameter description see #create_of_update_freestyle

Examples:

Create a Freestype Project

create_freestyle(
  :name => "test_freestyle_job",
  :keep_dependencies => true,
  :concurrent_build => true,
  :scm_provider => "git",
  :scm_url => "git://github.com./arangamani/improved_jenkins_client.git",
  :scm_branch => "master",
  :shell_command => "bundle install\n rake func_tests"
)

Parameters:

  • params (Hash)

    the parameters for creating a job

Returns:

  • (String)

    the HTTP status code from the POST request

See Also:



223
224
225
226
# File 'lib/improved_jenkins_client/job.rb', line 223

def create_freestyle(params)
  xml = build_freestyle_config(params)
  create(params[:name], xml)
end

#create_or_update(job_name, xml) ⇒ String

Create or Update a job with the name specified and the xml given

Parameters:

  • job_name (String)

    the name of the job

  • xml (String)

    the xml configuration of the job

Returns:

  • (String)

    the HTTP status code from the POST request

See Also:



84
85
86
87
88
89
90
# File 'lib/improved_jenkins_client/job.rb', line 84

def create_or_update(job_name, xml)
  if exists?(job_name)
    update(job_name, xml)
  else
    create(job_name, xml)
  end
end

#create_or_update_freestyle(params) ⇒ String

Create or Update a job with params given as a hash instead of the xml This gives some flexibility for creating/updating simple jobs so the user doesn’t have to learn about handling xml.

Parameters:

  • params (Hash)

    parameters to create a freestyle project

Options Hash (params):

  • :name (String)

    the name of the job

  • :keep_dependencies (Boolean) — default: false

    whether to keep the dependencies or not

  • :block_build_when_downstream_building (Boolean) — default: false

    whether to block build when the downstream project is building

  • :block_build_when_upstream_building (Boolean) — default: false

    whether to block build when the upstream project is building

  • :concurrent_build (Boolean) — default: false

    whether to allow concurrent execution of builds

  • :scm_provider (String)

    the type of source control. Supported providers: git, svn, and cvs

  • :scm_url (String)

    the remote url for the selected scm provider

  • :scm_credentials_id (String)

    the id of the credentials to use for authenticating with scm. Only for “git”

  • :scm_git_tool (String)

    the git executable. Defaults to “Default”; only for “git”

  • :scm_module (String)

    the module to download. Only for use with “cvs” scm provider

  • :scm_branch (String) — default: master

    the branch to use in scm.

  • :scm_tag (String)

    the tag to download from scm. Only for use with “cvs” scm provider

  • :scm_use_head_if_tag_not_found (Boolean)

    whether to use head if specified tag is not found. Only for “cvs”

  • :timer (String)

    the timer for running builds periodically

  • :shell_command (String)

    the command to execute in the shell

  • :notification_email (String)

    the email for sending notification

  • :skype_targets (String)

    the skype targets for sending notifications to. Use * to specify group chats. Use space to separate multiple targets. Note that this option requires the “skype” plugin to be installed in jenkins. Example: testuser *testgroup

  • :skype_strategy (String) — default: change

    the skype strategy to be used for sending notifications. Valid values: all, failure, failure_and_fixed, change.

  • :skype_notify_on_build_start (Boolean) — default: false

    whether to notify skype targets on build start

  • :skype_notify_suspects (Boolean) — default: false

    whether to notify suspects on skype

  • :skype_notify_culprits (Boolean) — default: false

    whether to notify culprits on skype

  • :skype_notify_fixers (Boolean) — default: false

    whether to notify fixers on skype

  • :skype_notify_upstream_committers (Boolean) — default: false

    whether to notify upstream committers on skype

  • :skype_message (String) — default: summary_and_scm_changes

    the information to be sent as notification message. Valid: just_summary, summary_and_scm_changes, summary_and_build_parameters, summary_scm_changes_and_failed_tests.

  • :child_projects (String)

    the projects to add as downstream projects

  • :child_threshold (String) — default: failure

    the threshold for child projects. Valid options: success, failure, or unstable.

Returns:

  • (String)

    the HTTP status code from the POST request

See Also:



193
194
195
196
197
198
199
# File 'lib/improved_jenkins_client/job.rb', line 193

def create_or_update_freestyle(params)
  if exists?(params[:name])
    update_freestyle(params)
  else
    create_freestyle(params)
  end
end

#delete(job_name) ⇒ String

Delete a job given the name

Parameters:

  • job_name (String)

    the name of the job to delete

Returns:

  • (String)

    the response from the HTTP POST request



495
496
497
498
# File 'lib/improved_jenkins_client/job.rb', line 495

def delete(job_name)
  @logger.info "Deleting job '#{job_name}'"
  @client.api_post_request("/job/#{path_encode job_name}/doDelete")
end

#delete_all!Object

Note:

This method will remove all jobs from Jenkins. Please use with caution.

Deletes all jobs from Jenkins



505
506
507
508
# File 'lib/improved_jenkins_client/job.rb', line 505

def delete_all!
  @logger.info "Deleting all jobs from jenkins"
  list_all.each { |job| delete(job) }
end

#delete_promote_config(job_name, process) ⇒ Object

Delete a job’s promotion config

Parameters:

  • job_name (String)
  • process (String)

    The process name

Returns:

  • nil



1710
1711
1712
1713
# File 'lib/improved_jenkins_client/job.rb', line 1710

def delete_promote_config(job_name, process)
  @logger.info "Deleting promote config for job '#{job_name}' process '#{process}'"
  @client.post_config("/job/#{job_name}/promotion/process/#{process}/doDelete")
end

#disable(job_name) ⇒ Object

Disable a job given the name of the job

Parameters:

  • job_name (String)


1131
1132
1133
1134
# File 'lib/improved_jenkins_client/job.rb', line 1131

def disable(job_name)
  @logger.info "Disabling job '#{job_name}'"
  @client.api_post_request("/job/#{path_encode job_name}/disable")
end

#each_build(job_name, fields: ['*'], start_index: 0, limit: nil, page_size: 100) ⇒ Object

Yields all builds using the allBuilds API endpoint.

Parameters:

  • job_name (String)

    the job to retrieve builds for

  • fields (Array) (defaults to: ['*'])

    the fields to retrieve from each build. [‘*’] by default, meaning all fields

  • limit (Integer) (defaults to: nil)

    the maximum total number of builds to retrieve

  • page_size (Integer) (defaults to: 100)

    the number of builds to retrieve at once



742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
# File 'lib/improved_jenkins_client/job.rb', line 742

def each_build(
    job_name,
    fields: ['*'],
    start_index: 0,
    limit: nil,
    page_size: 100)
  unless page_size.is_a?(Integer) && page_size >= 1
    raise "Invalid page size: #{page_size} (#{page_size.class}) -- must be at least one"
  end
  unless start_index.is_a?(Integer) && start_index >= 0
    raise "Invalid start index: #{start_index} (#{start_index.class}), must be a " +
          "nonnegative integer"
  end
  unless limit.nil? || limit.is_a?(Integer) && limit >= 0
    raise "Invalid limit: #{limit} (#{limit.class}) -- must be nil or a non-negative integer"
  end
  unless fields.is_a?(Array) && fields.size >= 1
    raise "Invalid array of fields to retrieve: #{fields} (#{fields.class}), must have at " +
          "least one element"
  end

  start_index = 0
  url = "/job/#{path_encode job_name}"
  fields_str = fields.join(',')
  while limit.nil? || start_index < limit do
    @logger.info(
        "Obtaining the build details of '#{job_name}' (fields: #{fields}) starting at " +
        "index #{start_index} with page size #{page_size}")

    end_index = start_index + page_size
    end_index = limit if !limit.nil? && end_index > limit

    break if start_index >= end_index

    tree = "allBuilds[#{fields_str}]{#{start_index},#{end_index}}"
    response_json = @client.api_get_request(url, tree_string(tree))
    build_range = response_json["allBuilds"]

    break if build_range.size == 0  # End of results.

    build_range.each do |result|
      yield result
    end

    # We got some results but less than what we asked for. This must be the last page.
    break if build_range.size < end_index - start_index

    start_index += page_size
  end
end

#enable(job_name) ⇒ Object

Enable a job given the name of the job

Parameters:

  • job_name (String)


1122
1123
1124
1125
# File 'lib/improved_jenkins_client/job.rb', line 1122

def enable(job_name)
  @logger.info "Enabling job '#{job_name}'"
  @client.api_post_request("/job/#{path_encode job_name}/enable")
end

#execute_concurrent_builds(job_name, option) ⇒ String

Allow or disable concurrent build execution

Parameters:

  • job_name (String)
  • option (Bool)

    true or false

Returns:

  • (String)

    response_code return code from HTTP POST



1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
# File 'lib/improved_jenkins_client/job.rb', line 1306

def execute_concurrent_builds(job_name, option)
  @logger.info "Setting the concurrent build execution option of" +
    " '#{job_name}' to #{option}"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  node = n_xml.xpath("//concurrentBuild").first
  if node.content != "#{option}"
    node.content = option == true ? "true" : "false"
    xml_modified = n_xml.to_xml
    post_config(job_name, xml_modified)
  end
end

#exists?(job_name) ⇒ Boolean

Checks if the given job exists in Jenkins

Parameters:

  • job_name (String)

    the name of the job to check

Returns:

  • (Boolean)

    whether the job exists in jenkins or not



629
630
631
# File 'lib/improved_jenkins_client/job.rb', line 629

def exists?(job_name)
  list(job_name).include?(job_name)
end

#find_artifact(job_name, build_number = 0) ⇒ Object

A Method to find artifacts path from the Current Build

Parameters:

  • job_name (String)
  • build_number (Integer) (defaults to: 0)

    defaults to latest build



1721
1722
1723
# File 'lib/improved_jenkins_client/job.rb', line 1721

def find_artifact(job_name, build_number = 0)
  find_artifacts(job_name, build_number).first
end

#find_artifacts(job_name, build_number = nil) ⇒ String, Hash

Find the artifacts for build_number of job_name, defaulting to current job

Parameters:

  • job_name (String)
  • build_number (Integer) (defaults to: nil)

    Optional build number

Returns:

  • (String, Hash)

    JSON response from Jenkins



1747
1748
1749
1750
1751
1752
# File 'lib/improved_jenkins_client/job.rb', line 1747

def find_artifacts(job_name, build_number = nil)
  response_json       = get_build_details(job_name, build_number)
  artifact_path(build_details: response_json).map do |p|
    URI.escape("#{response_json['url']}artifact/#{p['relativePath']}")
  end
end

#find_latest_artifacts(job_name) ⇒ String, Hash

Find the artifacts for the current job

Parameters:

  • job_name (String)

Returns:

  • (String, Hash)

    JSON response from Jenkins



1759
1760
1761
# File 'lib/improved_jenkins_client/job.rb', line 1759

def find_latest_artifacts(job_name)
  find_artifacts(job_name)
end

#get_build_details(job_name, build_num, tree: nil) ⇒ Object

Obtain detailed build info for a job

Parameters:

  • job_name (String)
  • build_num (Number)
  • tree (String) (defaults to: nil)


1198
1199
1200
1201
1202
1203
1204
# File 'lib/improved_jenkins_client/job.rb', line 1198

def get_build_details(job_name, build_num, tree: nil)
  build_num = get_current_build_number(job_name) if build_num == 0
  log_msg = "Obtaining the build details of '#{job_name}' Build ##{build_num}"
  log_msg += " (with tree=...)" unless tree.nil?

  @client.api_get_request("/job/#{path_encode job_name}/#{build_num}/", tree_string(tree))
end

#get_build_params(job_name) ⇒ Array

Obtain the build parameters of a job. It returns an array of hashes with details of job params.

Parameters:

  • job_name (String)

Returns:

  • (Array)

    params_array Array of parameters for the given job



1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
# File 'lib/improved_jenkins_client/job.rb', line 1326

def get_build_params(job_name)
  @logger.info "Obtaining the build params of '#{job_name}'"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  params = n_xml.xpath("//parameterDefinitions").first
  params_array = []
  if params
    params.children.each do |param|
      param_hash = {}
      case param.name
      when "hudson.model.StringParameterDefinition",
           "hudson.model.BooleanParameterDefinition",
           "hudson.model.TextParameterDefinition",
           "hudson.model.PasswordParameterDefinition"
        param_hash[:type] = 'string' if param.name =~ /string/i
        param_hash[:type] = 'boolean' if param.name =~ /boolean/i
        param_hash[:type] = 'text' if param.name =~ /text/i
        param_hash[:type] = 'password' if param.name =~ /password/i
        param.children.each do |value|
          param_hash[:name] = value.content if value.name == "name"
          if value.name == "description"
            param_hash[:description] = value.content
          end
          if value.name == "defaultValue"
            param_hash[:default] = value.content
          end
        end
      when "hudson.model.RunParameterDefinition"
        param_hash[:type] = 'run'
        param.children.each do |value|
          param_hash[:name] = value.content if value.name == "name"
          if value.name == "description"
            param_hash[:description] = value.content
          end
          if value.name == "projectName"
            param_hash[:project] = value.content
          end
        end
      when "hudson.model.FileParameterDefinition"
        param_hash[:type] = 'file'
        param.children.each do |value|
          param_hash[:name] = value.content if value.name == "name"
          if value.name == "description"
            param_hash[:description] = value.content
          end
        end
      when "hudson.scm.listtagsparameter.ListSubversionTagsParameterDefinition"
        param_hash[:type] = 'list_tags'
        param.children.each do |value|
          if value.name == "name"
            param_hash[:name] = value.content
          end
          if value.name == "description"
            param_hash[:description] = value.content
          end
          if value.name == "tagsDir"
            param_hash[:tags_dir] = value.content
          end
          if value.name == "tagsFilter"
            param_hash[:tags_filter] = value.content
          end
          if value.name == "reverseByDate"
            param_hash[:reverse_by_date] = value.content
          end
          if value.name == "reverseByName"
            param_hash[:reverse_by_name] = value.content
          end
          if value.name == "defaultValue"
            param_hash[:default] = value.content
          end
          param_hash[:max_tags] = value.content if value.name == "maxTags"
          param_hash[:uuid] = value.content if value.name == "uuid"
        end
      when "hudson.model.ChoiceParameterDefinition"
        param_hash[:type] = 'choice'
        param.children.each do |value|
          param_hash[:name] = value.content if value.name == "name"
          param_hash[:description] = value.content \
            if value.name == "description"
          choices = []
          if value.name == "choices"
            value.children.each do |value_child|
              if value_child.name == "a"
                value_child.children.each do |choice_child|
                  choices << choice_child.content.strip \
                    unless choice_child.content.strip.empty?
                end
              end
            end
          end
          param_hash[:choices] = choices unless choices.empty?
        end
      end
      params_array << param_hash unless param_hash.empty?
    end
  end
  params_array
end

#get_builds(job_name, options = {}) ⇒ Object

Obtain build details of a specific job

Parameters:

  • job_name (String)


725
726
727
728
729
730
731
732
# File 'lib/improved_jenkins_client/job.rb', line 725

def get_builds(job_name, options = {})
  @logger.info "Obtaining the builds of job '#{job_name}'"
  url = "/job/#{path_encode job_name}"

  tree = options[:tree]
  response_json = @client.api_get_request url, tree_string(tree)
  response_json["builds"]
end

#get_config(job_name) ⇒ String

Obtain the configuration stored in config.xml of a specific job

Parameters:

  • job_name (String)

Returns:

  • (String)

    XML Config.xml of the job



1142
1143
1144
1145
# File 'lib/improved_jenkins_client/job.rb', line 1142

def get_config(job_name)
  @logger.info "Obtaining the config.xml of '#{job_name}'"
  @client.get_config("/job/#{path_encode job_name}")
end

#get_console_output(job_name, build_num = 0, start = 0, mode = 'text') ⇒ Hash

Get progressive console output from Jenkins server for a job

Parameters:

  • job_name (String)

    Name of the Jenkins job

  • build_num (Number) (defaults to: 0)

    Specific build number to obtain the console output from. Default is the recent build

  • start (Number) (defaults to: 0)

    start offset to get only a portion of the text

  • mode (String) (defaults to: 'text')

    Mode of text output. ‘text’ or ‘html’

Returns:

  • (Hash)

    response

    • output console output of the job

    • size size of the text. This can be used as ‘start’ for the next call to get progressive output

    • more more data available for the job. ‘true’ if available and nil otherwise



588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
# File 'lib/improved_jenkins_client/job.rb', line 588

def get_console_output(job_name, build_num = 0, start = 0, mode = 'text')
  build_num = get_current_build_number(job_name) if build_num == 0
  if build_num == 0
    puts "No builds for this job '#{job_name}' yet."
    return nil
  end
  if mode == 'text'
    mode = 'Text'
  elsif mode == 'html'
    mode = 'Html'
  else
    raise "Mode should either be 'text' or 'html'. You gave: #{mode}"
  end
  get_msg = "/job/#{path_encode job_name}/#{build_num}/logText/progressive#{mode}?"
  get_msg << "start=#{start}"
  raw_response = true
  api_response = @client.api_get_request(get_msg, nil, nil, raw_response)
  #puts "Response: #{api_response.header['x-more-data']}"
  response = {}
  response['output'] = api_response.body
  response['size'] = api_response.header['x-text-size']
  response['more'] = api_response.header['x-more-data']

  response
end

#get_current_build_number(job_name) ⇒ Integer Also known as: build_number

Obtain the current build number of the given job This function returns nil if there were no builds for the given job.

Parameters:

  • job_name (String)

Returns:

  • (Integer)

    current build number of the given job



860
861
862
863
# File 'lib/improved_jenkins_client/job.rb', line 860

def get_current_build_number(job_name)
  @logger.info "Obtaining the current build number of '#{job_name}'"
  @client.api_get_request("/job/#{path_encode job_name}")['nextBuildNumber'].to_i - 1
end

#get_current_build_status(job_name) ⇒ String Also known as: status

Obtain the current build status of the job By default Jenkins returns the color of the job status icon This function translates the color into a meaningful status

Parameters:

  • job_name (String)

Returns:

  • (String)

    status current status of the given job



846
847
848
849
850
# File 'lib/improved_jenkins_client/job.rb', line 846

def get_current_build_status(job_name)
  @logger.info "Obtaining the current build status of '#{job_name}'"
  response_json = @client.api_get_request("/job/#{path_encode job_name}")
  color_to_status(response_json["color"])
end

#get_downstream_projects(job_name) ⇒ Object

List downstream projects of a specific job

Parameters:

  • job_name (String)

    the name of the job to obtain downstream projects for



715
716
717
718
719
# File 'lib/improved_jenkins_client/job.rb', line 715

def get_downstream_projects(job_name)
  @logger.info "Obtaining the down stream projects of '#{job_name}'"
  response_json = @client.api_get_request("/job/#{path_encode job_name}")
  response_json["downstreamProjects"]
end

#get_plugin_results(job_name, build_num, plugin_name) ⇒ Object

Obtain the plugin results for a specific build of a job

Parameters:

  • job_name (String)
  • build_num (Number)
  • plugin_name (String)


1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
# File 'lib/improved_jenkins_client/job.rb', line 1181

def get_plugin_results(job_name, build_num, plugin_name)
  build_num = get_current_build_number(job_name) if build_num == 0
  @logger.info "Obtaining the '#{plugin_name}' plugin results of '#{job_name}'" +
    " Build ##{build_num}"
  @client.api_get_request("/job/#{path_encode job_name}/#{build_num}/#{plugin_name}Result")
rescue Exceptions::NotFound
  # Not found is acceptable, as not all builds will have plugin results
  # and this is what jenkins throws at us in that case
  nil
end

#get_promote_config(job_name, process) ⇒ String

Get a job’s promotion config

Parameters:

  • job_name (String)
  • process (String)

    The process name

Returns:

  • (String)

    Promote config



1689
1690
1691
1692
# File 'lib/improved_jenkins_client/job.rb', line 1689

def get_promote_config(job_name, process)
  @logger.info "Getting promote config for job '#{job_name}' process '#{process}'"
  @client.get_config("/job/#{job_name}/promotion/process/#{process}/config.xml")
end

#get_promotions(job_name) ⇒ Hash

Get a list of promoted builds for given job

Parameters:

  • job_name (String)

Returns:

  • (Hash)

    Hash map of promitions and the promoted builds. Promotions that didn’t took place yet return nil



1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
# File 'lib/improved_jenkins_client/job.rb', line 1649

def get_promotions(job_name)
  result = {}

  @logger.info "Obtaining the promotions of '#{job_name}'"
  response_json = @client.api_get_request("/job/#{job_name}/promotion")

  response_json["processes"].each do |promotion|
    @logger.info "Getting promotion details of '#{promotion['name']}'"

    if promotion['color'] == 'notbuilt'
      result[promotion['name']] = nil
    else
      promo_json = @client.api_get_request("/job/#{job_name}/promotion/latest/#{promotion['name']}")
      result[promotion['name']] = promo_json['target']['number']
    end
  end

  result
end

#get_test_results(job_name, build_num) ⇒ Object

Obtain the test results for a specific build of a job

Parameters:

  • job_name (String)
  • build_num (Number)


1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
# File 'lib/improved_jenkins_client/job.rb', line 1164

def get_test_results(job_name, build_num)
  build_num = get_current_build_number(job_name) if build_num == 0
  @logger.info "Obtaining the test results of '#{job_name}'" +
    " Build ##{build_num}"
  @client.api_get_request("/job/#{path_encode job_name}/#{build_num}/testReport")
rescue Exceptions::NotFound
  # Not found is acceptable, as not all builds will have test results
  # and this is what jenkins throws at us in that case
  nil
end

#get_upstream_projects(job_name) ⇒ Object

List upstream projects of a specific job

Parameters:

  • job_name (String)

    the name of the job to obtain upstream projects for



704
705
706
707
708
# File 'lib/improved_jenkins_client/job.rb', line 704

def get_upstream_projects(job_name)
  @logger.info "Obtaining the upstream projects of '#{job_name}'"
  response_json = @client.api_get_request("/job/#{path_encode job_name}")
  response_json["upstreamProjects"]
end

#init_promote_process(job_name, process, config) ⇒ String

Create a new promotion process

This must be called before set/get promote config can be used on a process

Must be called after updating the job’s config

Parameters:

  • job_name (String)
  • process (String)

    The process name

Returns:

  • (String)

    Process config



1678
1679
1680
1681
# File 'lib/improved_jenkins_client/job.rb', line 1678

def init_promote_process(job_name, process, config)
  @logger.info "Creating new process #{process} for job #{job_name}"
  @client.post_config("/job/#{job_name}/promotion/createProcess?name=#{process}", config)
end

#list(filter, ignorecase = true) ⇒ Array<String>

List all jobs that match the given regex

Parameters:

  • filter (String)

    a regular expression or a string to filter jobs

  • ignorecase (Boolean) (defaults to: true)

    whether to ignore case or not

Returns:

  • (Array<String>)

    jobs matching the given pattern



664
665
666
667
668
669
670
671
672
673
674
675
676
# File 'lib/improved_jenkins_client/job.rb', line 664

def list(filter, ignorecase = true)
  @logger.info "Obtaining jobs matching filter '#{filter}'"
  response_json = @client.api_get_request("")
  jobs = []
  response_json["jobs"].each do |job|
    if ignorecase
      jobs << job["name"] if job["name"] =~ /#{filter}/i
    else
      jobs << job["name"] if job["name"] =~ /#{filter}/
    end
  end
  jobs
end

#list_allArray<String>

List all jobs on the Jenkins CI server

Returns:

  • (Array<String>)

    the names of all jobs in jenkins



618
619
620
621
# File 'lib/improved_jenkins_client/job.rb', line 618

def list_all
  response_json = @client.api_get_request("", "tree=jobs[name]")["jobs"]
  response_json.map { |job| job["name"] }.sort
end

#list_all_with_detailsArray<Hash>

List all jobs on the Jenkins CI server along with their details

Returns:

  • (Array<Hash>)

    the details of all jobs in jenkins



682
683
684
685
686
# File 'lib/improved_jenkins_client/job.rb', line 682

def list_all_with_details
  @logger.info "Obtaining the details of all jobs"
  response_json = @client.api_get_request("")
  response_json["jobs"]
end

#list_by_status(status, jobs = []) ⇒ Array<String>

List all Jobs matching the given status You can optionally pass in jobs list to filter the status from

Parameters:

  • status (String)

    the job status to filter

  • jobs (Array<String>) (defaults to: [])

    if specified this array will be used for filtering by the status otherwise the filtering will be done using all jobs available in jenkins

Returns:

  • (Array<String>)

    filtered jobs



643
644
645
646
647
648
649
650
651
652
653
654
655
# File 'lib/improved_jenkins_client/job.rb', line 643

def list_by_status(status, jobs = [])
  jobs = list_all if jobs.empty?
  @logger.info "Obtaining jobs matching status '#{status}'"
  json_response = @client.api_get_request("", "tree=jobs[name,color]")
  filtered_jobs = []
  json_response["jobs"].each do |job|
    if color_to_status(job["color"]) == status &&
       jobs.include?(job["name"])
      filtered_jobs << job["name"]
    end
  end
  filtered_jobs
end

#list_details(job_name) ⇒ Hash

List details of a specific job

Parameters:

  • job_name (String)

    the name of the job to obtain the details from

Returns:

  • (Hash)

    the details of the specified job



694
695
696
697
# File 'lib/improved_jenkins_client/job.rb', line 694

def list_details(job_name)
  @logger.info "Obtaining the details of '#{job_name}'"
  @client.api_get_request("/job/#{path_encode job_name}")
end

#poll(job_name) ⇒ String

Programatically schedule SCM polling for the specified job

Parameters:

  • job_name (String)

    the name of the job

Returns:

  • (String)

    the response code from the HTTP post request



1113
1114
1115
1116
# File 'lib/improved_jenkins_client/job.rb', line 1113

def poll(job_name)
  @logger.info "Polling SCM changes for job '#{job_name}'"
  @client.api_post_request("/job/#{job_name}/polling")
end

#post_config(job_name, xml) ⇒ String

Post the configuration of a job given the job name and the config.xml

Parameters:

  • job_name (String)
  • xml (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1154
1155
1156
1157
# File 'lib/improved_jenkins_client/job.rb', line 1154

def post_config(job_name, xml)
  @logger.info "Posting the config.xml of '#{job_name}'"
  @client.post_config("/job/#{path_encode job_name}/config.xml", xml)
end

#queued?(job_name) ⇒ Integer

Determine if the build is queued

Parameters:

  • job_name (String)

Returns:

  • (Integer)

    build number if queued, or [Boolean] false if not queued



829
830
831
832
833
834
835
836
# File 'lib/improved_jenkins_client/job.rb', line 829

def queued?(job_name)
  queue_result = @client.api_get_request("/job/#{path_encode job_name}")['inQueue']
  if queue_result
    return @client.api_get_request("/job/#{path_encode job_name}")['nextBuildNumber']
  else
    return queue_result
  end
end

#recreate(job_name) ⇒ String

Re-create the same job This is a hack to clear any existing builds

Parameters:

  • job_name (String)

    the name of the job to recreate

Returns:

  • (String)

    the response from the HTTP POST request



551
552
553
554
555
556
# File 'lib/improved_jenkins_client/job.rb', line 551

def recreate(job_name)
  @logger.info "Recreating job '#{job_name}'"
  job_xml = get_config(job_name)
  delete(job_name)
  create(job_name, job_xml)
end

#remove_downstream_projects(job_name) ⇒ String

Remove all downstream projects of a specific job

Parameters:

  • job_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
# File 'lib/improved_jenkins_client/job.rb', line 1478

def remove_downstream_projects(job_name)
  @logger.info "Removing the downstream projects of '#{job_name}'"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  n_xml.search("//hudson.tasks.BuildTrigger").each do |node|
    child_project_trigger = false
    node.search("//childProjects").each do |child_node|
      child_project_trigger = true
      child_node.search("//threshold").each do |threshold_node|
        threshold_node.children.each do |threshold_value_node|
          threshold_value_node.content = nil
          threshold_value_node.remove
        end
        threshold_node.content = nil
        threshold_node.remove
      end
      child_node.content = nil
      child_node.remove
    end
    node.content = nil
    node.remove
  end
  publisher_node = n_xml.search("//publishers").first
  publisher_node.content = nil if publisher_node.children.empty?
  xml_modified = n_xml.to_xml
  post_config(job_name, xml_modified)
end

#remove_plugin(plugin) ⇒ JenkinsApi::Client::PluginSettings::Collection

Remove a plugin to be included in job’s xml configureation

Parameters:

  • plugin (Jenkins::Api::Client::PluginSettings::Base)

Returns:



64
65
66
# File 'lib/improved_jenkins_client/job.rb', line 64

def remove_plugin(plugin)
  plugin_collection.remove(plugin)
end

#remove_upstream_projects(job_name) ⇒ String

Remove all upstream projects of a specific job

Parameters:

  • job_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1562
1563
1564
1565
1566
1567
1568
1569
# File 'lib/improved_jenkins_client/job.rb', line 1562

def remove_upstream_projects(job_name)
  @logger.info "Removing the upstream projects of '#{job_name}'"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  n_xml.search("//jenkins.triggers.ReverseBuildTrigger").remove
  xml_modified = n_xml.to_xml
  post_config(job_name, xml_modified)
end

#rename(old_job, new_job) ⇒ Object

Rename a job given the old name and new name

Parameters:

  • old_job (String)

    Name of the old job

  • new_job (String)

    Name of the new job.



484
485
486
487
# File 'lib/improved_jenkins_client/job.rb', line 484

def rename(old_job, new_job)
  @logger.info "Renaming job '#{old_job}' to '#{new_job}'"
  @client.api_post_request("/job/#{path_encode old_job}/doRename?newName=#{form_encode new_job}")
end

#restrict_to_node(job_name, node_name) ⇒ String

Resctrict the given job to a specific node

Parameters:

  • job_name (String)
  • node_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
# File 'lib/improved_jenkins_client/job.rb', line 1578

def restrict_to_node(job_name, node_name)
  @logger.info "Restricting '#{job_name}' to '#{node_name}' node"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  if (node = n_xml.xpath("//assignedNode").first)
    node.content = node_name
  else
    project = n_xml.xpath("//scm").first
    project.add_next_sibling("<assignedNode>#{node_name}</assignedNode>")
    roam_node = n_xml.xpath("//canRoam").first
    roam_node.content = "false"
  end
  xml_modified = n_xml.to_xml
  post_config(job_name, xml_modified)
end

#set_promote_config(job_name, process, config) ⇒ Object

Set a job’s promotion config

Parameters:

  • job_name (String)
  • process (String)

    The process name

  • Job (String)

    config

Returns:

  • nil



1700
1701
1702
1703
# File 'lib/improved_jenkins_client/job.rb', line 1700

def set_promote_config(job_name, process, config)
  @logger.info "Setting promote config for job '#{job_name}' process '#{process}' to #{config}"
  @client.post_config("/job/#{job_name}/promotion/process/#{process}/config.xml", config)
end

#stop_build(job_name, build_number = 0) ⇒ Object Also known as: stop, abort

Stops a running build of a job This method will stop the current/most recent build if no build number is specified. The build will be stopped only if it was in ‘running’ state.

Parameters:

  • job_name (String)

    the name of the job to stop the build

  • build_number (Number) (defaults to: 0)

    the build number to stop



529
530
531
532
533
534
535
536
537
538
539
540
# File 'lib/improved_jenkins_client/job.rb', line 529

def stop_build(job_name, build_number = 0)
  build_number = get_current_build_number(job_name) if build_number == 0
  raise "No builds for #{job_name}" unless build_number
  @logger.info "Stopping job '#{job_name}' Build ##{build_number}"
  # Check and see if the build is running
  is_building = @client.api_get_request(
    "/job/#{path_encode job_name}/#{build_number}"
  )["building"]
  if is_building
    @client.api_post_request("/job/#{path_encode job_name}/#{build_number}/stop")
  end
end

#to_sObject

Return a string representation of the object



70
71
72
# File 'lib/improved_jenkins_client/job.rb', line 70

def to_s
  "#<JenkinsApi::Client::Job>"
end

#unblock_build_when_downstream_building(job_name) ⇒ String

Unblock the build of the job when downstream is building

Parameters:

  • job_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
# File 'lib/improved_jenkins_client/job.rb', line 1248

def unblock_build_when_downstream_building(job_name)
  @logger.info "Unblocking builds of '#{job_name}' when downstream" +
    " projects are building"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  node = n_xml.xpath("//blockBuildWhenDownstreamBuilding").first
  if node.content == "true"
    node.content = "false"
    xml_modified = n_xml.to_xml
    post_config(job_name, xml_modified)
  end
end

#unblock_build_when_upstream_building(job_name) ⇒ String

Unblock the build of the job when upstream is building

Parameters:

  • job_name (String)

Returns:

  • (String)

    response_code return code from HTTP POST



1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
# File 'lib/improved_jenkins_client/job.rb', line 1286

def unblock_build_when_upstream_building(job_name)
  @logger.info "Unblocking builds of '#{job_name}' when upstream" +
    " projects are building"
  xml = get_config(job_name)
  n_xml = Nokogiri::XML(xml)
  node = n_xml.xpath("//blockBuildWhenUpstreamBuilding").first
  if node.content == "true"
    node.content = "false"
    xml_modified = n_xml.to_xml
    post_config(job_name, xml_modified)
  end
end

#unchain(job_names) ⇒ Object

Unchain any existing chain between given job names

Parameters:

  • job_names (Array)

    Array of job names to be unchained



1598
1599
1600
1601
# File 'lib/improved_jenkins_client/job.rb', line 1598

def unchain(job_names)
  @logger.info "Unchaining jobs: #{job_names.inspect}"
  job_names.each { |job| remove_downstream_projects(job) }
end

#update(job_name, xml) ⇒ String

Update a job with the name specified and the xml given

Parameters:

  • job_name (String)

    the name of the job

  • xml (String)

    the xml configuration of the job

Returns:

  • (String)

    the HTTP status code from the POST request

See Also:



117
118
119
120
# File 'lib/improved_jenkins_client/job.rb', line 117

def update(job_name, xml)
  @logger.info "Updating job '#{job_name}'"
  post_config(job_name, xml)
end

#update_freestyle(params) ⇒ String

Update a job with params given as a hash instead of the xml. For the parameter description see #create_or_update_freestyle

Parameters:

  • params (Hash)

    parameters to update a freestyle project

Returns:

  • (String)

    the HTTP status code from the POST request

See Also:



239
240
241
242
# File 'lib/improved_jenkins_client/job.rb', line 239

def update_freestyle(params)
  xml = build_freestyle_config(params)
  update(params[:name], xml)
end

#wipe_out_workspace(job_name) ⇒ String

Wipe out the workspace for a job given the name

Parameters:

  • job_name (String)

    the name of the job to wipe out the workspace

Returns:

  • (String)

    response from the HTTP POST request



516
517
518
519
# File 'lib/improved_jenkins_client/job.rb', line 516

def wipe_out_workspace(job_name)
  @logger.info "Wiping out the workspace of job '#{job_name}'"
  @client.api_post_request("/job/#{path_encode job_name}/doWipeOutWorkspace")
end