Skip to content

Instantly share code, notes, and snippets.

@matthijsgroen
Created May 4, 2012 09:13
Show Gist options
  • Save matthijsgroen/2593504 to your computer and use it in GitHub Desktop.
Save matthijsgroen/2593504 to your computer and use it in GitHub Desktop.
Jenkins command line
#!/usr/bin/ruby
require 'net/http'
require 'net/https'
require 'base64'
require 'uri'
require 'yaml'
require 'cgi'
module Configuration
def config_file
"#{ENV['HOME']}/.jnkrc"
end
def configuration
return @configuration if @configuration
@configuration = {}
@configuration = YAML.load_file(config_file) if File.exists? config_file
@configuration
end
def update_configuration attributes
@configuration = configuration.merge(attributes)
File.open(config_file, "w") { |f| f.write(@configuration.to_yaml) }
end
def user args
return false unless args.length == 2
update_configuration({:username => args[0], :password => encode_pass(args[1])})
end
def encode_pass(pass)
Base64::encode64 pass
end
def decode_pass(pass)
Base64::decode64 pass
end
def init args
return false unless args.length == 2
configuration[:mappings] ||= {}
configuration[:mappings][repository] ||= {}
configuration[:mappings][repository][:config] = args[0]
configuration[:mappings][repository][:token] = args[1]
update_configuration({})
puts %{"#{repository}" => "#{args[0]}"}
true
end
def control args
return false unless args.length == 1
update_configuration(:control_center => args[0])
puts %{control center set to: #{args[0]}}
true
end
def jenkins_configuration
return @jenkins_configuration if @jenkins_configuration
return nil unless configuration[:mappings] and configuration[:mappings][repository]
@jenkinks_configuration = configuration[:mappings][repository]
@jenkinks_configuration
end
end
module Git
def remote
@remote ||= `git remote -v | grep \\(push\\)`.split[1]
end
def repository
@repository ||= remote.split("/")[-1]
end
def branch
@branch ||= `git branch | grep \\*`.split[1]
end
def branch_changes
@branch_changes ||= `git status --short --porcelain`.split("\n")
end
end
module Commands
def push args
unless jenkins_configuration
puts %{could not find configuration for "#{repository}/#{branch}". Please use 'map' to setup triggering}
return true
end
flags = args.collect { |flag| flag["--"] ? flag.gsub("--", "") : nil }.compact
if flags.include? "force"
unless branch_changes.empty?
puts "Your branch has the current uncommitted changes:"
branch_changes.each { |change| puts change }
return true
end
`git push origin #{branch}`
end
print Time.now.strftime "[%a %d %b %H:%M] "
puts %{triggering #{configuration[:control_center]} to execute "#{jenkins_configuration[:config]}" for #{repository}/#{branch}}
session = jenkins_login
trigger_job session, jenkins_configuration, "branch" => branch
true
end
end
module JenkinsCommunication
def form_encode data
params = []
data.each do |field, value|
params.push "#{CGI::escape field}=#{CGI::escape value}"
end
params.join "&"
end
def jenkins_login
root_uri = URI.parse("#{configuration[:control_center]}")
uri = URI.parse("#{configuration[:control_center]}/j_acegi_security_check")
headers = {
'Content-Type' => "application/x-www-form-urlencoded"
}
data = {
"j_username" => configuration[:username],
"j_password" => decode_pass(configuration[:password]),
"from" => root_uri.path
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == "https"
res = http.post(uri.path, form_encode(data), headers)
raise "Invalid credentials" if res.code == "403"
res.response['set-cookie']
end
def trigger_job session, config, options
uri = URI.parse("#{configuration[:control_center]}/job/#{config[:config]}/buildWithParameters")
headers = {
"Cookie" => session
}
data = {
"token" => config[:token]
}.merge options
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == "https"
res = http.get("#{uri.path}?#{form_encode data}", headers)
end
end
include Configuration, Git, Commands, JenkinsCommunication
command = ARGV.shift
known_commands = {
"push" => "pushes the current branch as feature branch run on jenkins. Use --force to push your latest commits to the server before running CI",
"control" => "set the url to the jenkins control center. usage: control http://jenkins/path",
"init" => "Initialize this git repo to a Jenkins auth-key. usage: init jenkins-config auth-key",
"user" => "Setup Jenkins credentials. usage: user username password"
}
show_help = true
show_help = false if known_commands.has_key? command and send command.to_sym, ARGV
if show_help
puts "commands available:"
known_commands.keys.sort.each { |key| puts " #{"%-10s" % key}\t#{known_commands[key]}" }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment