-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7555595
commit 42c0a34
Showing
2 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#!/usr/bin/ruby | ||
require 'json' | ||
require 'net/http' | ||
require 'yaml' | ||
require 'logger' | ||
|
||
$log = Logger.new(STDOUT) | ||
$log.level = Logger::WARN | ||
|
||
class ForwardMerge | ||
attr_reader :issue, :milestone, :message, :line | ||
def initialize(issue, milestone, message, line) | ||
@issue = issue | ||
@milestone = milestone | ||
@message = message | ||
@line = line | ||
end | ||
end | ||
|
||
def find_forward_merges(message_file) | ||
$log.debug "Searching for forward merge" | ||
rev=`git rev-parse -q --verify MERGE_HEAD`.strip | ||
$log.debug "Found #{rev} from git rev-parse" | ||
return nil unless rev | ||
message = File.read(message_file) | ||
forward_merges = [] | ||
message.each_line do |line| | ||
$log.debug "Checking #{line} for message" | ||
match = /^(?:Fixes|Closes) gh-(\d+) in (\d\.\d\.[\dx](?:[\.\-](?:M|RC)\d)?)$/.match(line) | ||
if match then | ||
issue = match[1] | ||
milestone = match[2] | ||
$log.debug "Matched reference to issue #{issue} in milestone #{milestone}" | ||
forward_merges << ForwardMerge.new(issue, milestone, message, line) | ||
end | ||
end | ||
$log.debug "No match in merge message" unless forward_merges | ||
return forward_merges | ||
end | ||
|
||
def get_issue(username, password, repository, number) | ||
$log.debug "Getting issue #{number} from GitHub repository #{repository}" | ||
uri = URI("https://api.github.com/repos/#{repository}/issues/#{number}") | ||
http = Net::HTTP.new(uri.host, uri.port) | ||
http.use_ssl=true | ||
request = Net::HTTP::Get.new(uri.path) | ||
request.basic_auth(username, password) | ||
response = http.request(request) | ||
$log.debug "Get HTTP response #{response.code}" | ||
return JSON.parse(response.body) unless response.code != '200' | ||
puts "Failed to retrieve issue #{number}: #{response.message}" | ||
exit 1 | ||
end | ||
|
||
def find_milestone(username, password, repository, title) | ||
$log.debug "Finding milestone #{title} from GitHub repository #{repository}" | ||
uri = URI("https://api.github.com/repos/#{repository}/milestones") | ||
http = Net::HTTP.new(uri.host, uri.port) | ||
http.use_ssl=true | ||
request = Net::HTTP::Get.new(uri.path) | ||
request.basic_auth(username, password) | ||
response = http.request(request) | ||
milestones = JSON.parse(response.body) | ||
if title.end_with?(".x") | ||
prefix = title.delete_suffix('.x') | ||
$log.debug "Finding nearest milestone from candidates starting with #{prefix}" | ||
titles = milestones.map { |milestone| milestone['title'] } | ||
titles = titles.select{ |title| title.start_with?(prefix) unless title.end_with?('.x')} | ||
titles = titles.sort_by { |v| Gem::Version.new(v) } | ||
$log.debug "Considering candidates #{titles}" | ||
if(titles.empty?) | ||
puts "Cannot find nearest milestone for prefix #{title}" | ||
exit 1 | ||
end | ||
title = titles.first | ||
$log.debug "Found nearest milestone #{title}" | ||
end | ||
milestones.each do |milestone| | ||
$log.debug "Considering #{milestone['title']}" | ||
return milestone['number'] if milestone['title'] == title | ||
end | ||
puts "Milestone #{title} not found" | ||
exit 1 | ||
end | ||
|
||
def create_issue(username, password, repository, original, title, labels, milestone, milestone_name, dry_run) | ||
$log.debug "Finding forward-merge issue in GitHub repository #{repository} for '#{title}'" | ||
uri = URI("https://api.github.com/repos/#{repository}/issues") | ||
http = Net::HTTP.new(uri.host, uri.port) | ||
http.use_ssl=true | ||
request = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json') | ||
request.basic_auth(username, password) | ||
request.body = { | ||
title: title, | ||
labels: labels, | ||
milestone: milestone.to_i, | ||
body: "Forward port of issue ##{original} to #{milestone_name}." | ||
}.to_json | ||
if dry_run then | ||
puts "Dry run" | ||
puts "POSTing to #{uri} with body #{request.body}" | ||
return "dry-run" | ||
end | ||
response = JSON.parse(http.request(request).body) | ||
$log.debug "Created new issue #{response['number']}" | ||
return response['number'] | ||
end | ||
|
||
$log.debug "Running forward-merge hook script" | ||
message_file=ARGV[0] | ||
|
||
forward_merges = find_forward_merges(message_file) | ||
exit 0 unless forward_merges | ||
|
||
$log.debug "Loading config from ~/.dependency-management-plugin/forward_merge.yml" | ||
config = YAML.load_file(File.join(Dir.home, '.dependency-management-plugin', 'forward-merge.yml')) | ||
username = config['github']['credentials']['username'] | ||
password = config['github']['credentials']['password'] | ||
dry_run = config['dry_run'] | ||
repository = 'spring-gradle-plugins/dependency-management-plugin' | ||
|
||
forward_merges.each do |forward_merge| | ||
existing_issue = get_issue(username, password, repository, forward_merge.issue) | ||
title = existing_issue['title'] | ||
labels = existing_issue['labels'].map { |label| label['name'] } | ||
labels << "status: forward-port" | ||
$log.debug "Processing issue '#{title}'" | ||
|
||
milestone = find_milestone(username, password, repository, forward_merge.milestone) | ||
new_issue_number = create_issue(username, password, repository, forward_merge.issue, title, labels, milestone, forward_merge.milestone, dry_run) | ||
|
||
puts "Created gh-#{new_issue_number} for forward port of gh-#{forward_merge.issue} into #{forward_merge.milestone}" | ||
rewritten_message = forward_merge.message.sub(forward_merge.line, "Closes gh-#{new_issue_number}\n") | ||
File.write(message_file, rewritten_message) | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#!/usr/bin/ruby | ||
require 'json' | ||
require 'net/http' | ||
require 'yaml' | ||
require 'logger' | ||
|
||
$main_branch = "1.1.x" | ||
|
||
$log = Logger.new(STDOUT) | ||
$log.level = Logger::WARN | ||
|
||
def get_fixed_issues() | ||
$log.debug "Searching for forward merge" | ||
rev=`git rev-parse -q --verify MERGE_HEAD`.strip | ||
$log.debug "Found #{rev} from git rev-parse" | ||
return nil unless rev | ||
fixed = [] | ||
message = `git log -1 --pretty=%B #{rev}` | ||
message.each_line do |line| | ||
$log.debug "Checking #{line} for message" | ||
fixed << line.strip if /^(?:Fixes|Closes) gh-(\d+)/.match(line) | ||
end | ||
$log.debug "Found fixed issues #{fixed}" | ||
return fixed; | ||
end | ||
|
||
def rewrite_message(message_file, fixed) | ||
current_branch = `git rev-parse --abbrev-ref HEAD`.strip | ||
if current_branch == "main" | ||
current_branch = $main_branch | ||
end | ||
rewritten_message = "" | ||
message = File.read(message_file) | ||
message.each_line do |line| | ||
match = /^Merge.*branch\ '(.*)'(?:\ into\ (.*))?$/.match(line) | ||
if match | ||
from_branch = match[1] | ||
if from_branch.include? "/" | ||
from_branch = from_branch.partition("/").last | ||
end | ||
to_brach = match[2] | ||
$log.debug "Rewriting merge message" | ||
line = "Merge branch '#{from_branch}'" + (to_brach ? " into #{to_brach}\n" : "\n") | ||
end | ||
if fixed and line.start_with?("#") | ||
$log.debug "Adding fixed" | ||
rewritten_message << "\n" | ||
fixed.each do |fixes| | ||
rewritten_message << "#{fixes} in #{current_branch}\n" | ||
end | ||
fixed = nil | ||
end | ||
rewritten_message << line | ||
end | ||
return rewritten_message | ||
end | ||
|
||
$log.debug "Running prepare-forward-merge hook script" | ||
|
||
message_file=ARGV[0] | ||
message_type=ARGV[1] | ||
|
||
if message_type != "merge" | ||
$log.debug "Not a merge commit" | ||
exit 0; | ||
end | ||
|
||
$log.debug "Searching for forward merge" | ||
fixed = get_fixed_issues() | ||
rewritten_message = rewrite_message(message_file, fixed) | ||
File.write(message_file, rewritten_message) |