Bulk Editing Jenkins Configurations

dietz - 23 Apr 2014

During our SCM migration, we had to update the configurations of hundreds of jenkins jobs on three different instances. Rather than do that manually, we wrote this ruby snippet (edit_config.rb):

require 'fileutils'
require 'optparse'
require 'nokogiri'

# Accepts a block that takes an Nokogiri XML doc as a parameter
# and modifies the XML doc as desired.
def apply_to_configs (root_directory, orig_file_extension, &block)
  config_files = Dir.glob("#{root_directory}/**/config.xml")
  config_files.each { |config|
    doc = Nokogiri::XML::Document.parse(File.read(config)) do |options|
      options.default_xml.noblanks # ignore initial whitespace
    project = doc.at_xpath("//project")
    next if project.nil?
    FileUtils.cp config, "#{config}.#{orig_file_extension}"
    case block.arity
      when 1
        new_doc = yield doc
      when 2
        new_doc = yield doc, config
    File.open("#{config}", 'w') {|f| doc.write_xml_to(f, :indent => 2) }

This function updates each config.xml by following these steps:

  1. Find all config.xml files in any subdirectory of a root directory
  2. Make a backup copy of the file with an additional specified by origfileextension parameter
  3. Pass the contents of the config.xml as a nokogiri document object to the passed in block
  4. The block modifies the document object in whatever way desired
  5. Overwrite config.xml with the updated contents of the XML document.

Here's an example using applytoconfigs to set the checkbox "Send separate e-mails to individuals who broke the build" on every job with a post-build step to send failure emails.

require 'nokogiri'
require_relative './edit_config'

apply_to_configs($local_jobs_root, $orig_file_extension) do |config_doc, config_path|
  job_name = config_path.split("/")[-2]
  send_to_individuals = config_doc.at_xpath("//hudson.tasks.Mailer/sendToIndividuals")
  puts "Set #{send_to_individuals} for #{job_name}"
  send_to_individuals.content="true" unless send_to_individuals.nil?

Now that we have the automation in place, we've been able to use this several times to modify all our jenkins config setups.

comments powered by Disqus