Skip to content

Instantly share code, notes, and snippets.

@op-ct
Created February 20, 2016 10:30
Show Gist options
  • Save op-ct/c0838a39759a382c5973 to your computer and use it in GitHub Desktop.
Save op-ct/c0838a39759a382c5973 to your computer and use it in GitHub Desktop.
Jenkins Gerrit Trigger that Checks on Travis CI results
# - gets latest Travis CI result and exits 0 (CR+1) or fails (CR-1)
# - gets the latest GitHub PR pull from Gerrit comments
# - warns if latest Gerrit patchset is newer than latest GitHub PR pull (because Travis results aren't the latest)
# TODO: warn if latest Travis request is newer than latest GerritHub PR PR pull (because GerritHub needs to be updated)
require 'travis'
require 'travis/tools/github'
require 'json'
gerrit = {}
gerrit[:user] = ENV.fetch('GERRIT_USER') # NOTE: define this as a Jenkins env va
gerrit[:host] = ENV.fetch('GERRIT_HOST')
gerrit[:port] = ENV.fetch('GERRIT_PORT')
github_api_token = ENV.fetch('GITHUB_API_TOKEN') # TODO: travis can fetch this via .netrc
gerrit[:project] = ENV.fetch('GERRIT_PROJECT')
gerrit[:change_id] = ENV.fetch('GERRIT_CHANGE_ID')
slug = gerrit[:project]
travis_token = Travis.github_auth( ENV['GITHUB_API_TOKEN'])
puts "Hello #{Travis::User.current.name}!"
repo = Travis::Repository.find(slug)
build = repo.builds.first
commit = build.commit
# Find the most recent pull request in the gerrit patchsets
gerrit[:query_json] = %x{ssh -xp#{gerrit[:port]} #{gerrit[:user]}@#{gerrit[:host]} gerrit query --patch-sets --comments --format JSON change:#{gerrit[:change_id]}}
gerrit[:query_data] = JSON.parse gerrit[:query_json]
.split(/\n{/)
.first
gerrit[:pull_comments] = gerrit[:query_data]
.fetch('comments')
.select{|x| x.fetch('message') =~ %r{^GitHub Pull Request: https://api.github.com/repos/#{slug}/pulls} }
gerrit[:latest_pr] = {
:timestamp => gerrit[:pull_comments]
.last['timestamp'],
:number => gerrit[:pull_comments]
.last['message']
.sub(%r{^GitHub Pull Request: https://api.github.com/repos/#{slug}/pulls/(\d+).*$}m, '\1' ),
}
gerrit[:latest_pr][:revision] = gerrit[:query_data]['patchSets']
.select{|x| x['createdOn'].to_i == gerrit[:latest_pr][:timestamp] }
.first
.fetch('revision')
# Warn if GerritHub has been updated since the last GitHub PR pull
gerrit[:ps_timestamps] = gerrit[:query_data]['patchSets']
.map{|x| x['createdOn'] }
i = gerrit[:ps_timestamps]
.index(gerrit[:latest_pr][:timestamp])
max_i = gerrit[:ps_timestamps].size - 1
travis_is_trustworthy = true
if i==max_i
puts "#{slug} Pull request ##{gerrit[:latest_pr][:number]} is the most recent Patch Set in Gerrit (this is good)."
else
width=80
warn ''
warn '-'*80
warn "WARNING: *#{max_i-i}* patchsets have been submitted directly to Gerrit since `#{slug}` PR ##{gerrit[:latest_pr][:number]}; Travis CI will not have tested these changes!"
.scan(/\S.{0,#{width-2}}\S(?=\s|$)|\S+/)
.join("\n")
warn '-'*80
warn ''
travis_is_trustworthy = false
end
request = repo
.requests
.select{|x| x.head_commit? && x.head_commit == gerrit[:latest_pr][:revision] }
.first
build = repo
.builds
.select{ |x| x.commit_id? && x.commit_id == request.commit_id }
.first
fail "FAILBARF: Travis build ##{build.number} for PR ##{build.pr_number} is not finished!" unless build.finished?
fail "FAILURE: Travis build ##{build.number} for PR ##{build.pr_number} failed!" unless build.green?
puts '-'*80
puts "SUCCESS! #{slug} PR# #{gerrit[:latest_pr][:number]} has passed Travis CI build #{build.number}!"
puts ''
puts "HOWEVER, subsequent direct Gerrit patchset make Travis' results untrustworthy." unless travis_is_trustworthy
puts '-'*80
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment