Created
May 4, 2012 09:13
-
-
Save matthijsgroen/2593504 to your computer and use it in GitHub Desktop.
Jenkins command line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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