Merge pull request #7844 from jonchang/signoff-approving-reviews
pr-pull: add commit message trailers for pull requests with approved reviews
This commit is contained in:
commit
b57290b23f
@ -73,13 +73,18 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def signoff!(pr, path: ".")
|
def signoff!(pr, tap:)
|
||||||
message = Utils.popen_read "git", "-C", path, "log", "-1", "--pretty=%B"
|
message = Utils.popen_read "git", "-C", tap.path, "log", "-1", "--pretty=%B"
|
||||||
subject = message.lines.first.strip
|
subject = message.lines.first.strip
|
||||||
|
|
||||||
# Skip the subject and separate lines that look like trailers (e.g. "Co-authored-by")
|
# Skip the subject and separate lines that look like trailers (e.g. "Co-authored-by")
|
||||||
# from lines that look like regular body text.
|
# from lines that look like regular body text.
|
||||||
trailers, body = message.lines.drop(1).partition { |s| s.match?(/^[a-z-]+-by:/i) }
|
trailers, body = message.lines.drop(1).partition { |s| s.match?(/^[a-z-]+-by:/i) }
|
||||||
|
|
||||||
|
# Approving reviewers also sign-off on merge
|
||||||
|
trailers += GitHub.approved_reviews(tap.user, "homebrew-#{tap.repo}", pr).map do |r|
|
||||||
|
"Signed-off-by: #{r["name"]} <#{r["email"]}>\n"
|
||||||
|
end
|
||||||
trailers = trailers.uniq.join.strip
|
trailers = trailers.uniq.join.strip
|
||||||
body = body.join.strip.gsub(/\n{3,}/, "\n\n")
|
body = body.join.strip.gsub(/\n{3,}/, "\n\n")
|
||||||
|
|
||||||
@ -90,7 +95,7 @@ module Homebrew
|
|||||||
if Homebrew.args.dry_run?
|
if Homebrew.args.dry_run?
|
||||||
puts "git commit --amend --signoff -m $message"
|
puts "git commit --amend --signoff -m $message"
|
||||||
else
|
else
|
||||||
safe_system "git", "-C", path, "commit", "--amend", "--signoff", "--allow-empty", "-q", "-m", new_message
|
safe_system "git", "-C", tap.path, "commit", "--amend", "--signoff", "--allow-empty", "-q", "-m", new_message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -232,7 +237,7 @@ module Homebrew
|
|||||||
cd dir do
|
cd dir do
|
||||||
original_commit = Utils.popen_read("git", "-C", tap.path, "rev-parse", "HEAD").chomp
|
original_commit = Utils.popen_read("git", "-C", tap.path, "rev-parse", "HEAD").chomp
|
||||||
cherry_pick_pr! pr, path: tap.path
|
cherry_pick_pr! pr, path: tap.path
|
||||||
signoff! pr, path: tap.path unless args.clean?
|
signoff! pr, tap: tap unless args.clean?
|
||||||
|
|
||||||
unless args.no_upload?
|
unless args.no_upload?
|
||||||
mirror_formulae(tap, original_commit, org: bintray_org, repo: mirror_repo, publish: !args.no_publish?)
|
mirror_formulae(tap, original_commit, org: bintray_org, repo: mirror_repo, publish: !args.no_publish?)
|
||||||
|
|||||||
@ -42,6 +42,13 @@ describe GitHub do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "::approved_reviews", :needs_network do
|
||||||
|
it "can get reviews for a pull request" do
|
||||||
|
reviews = subject.approved_reviews("Homebrew", "homebrew-core", 1, commit: "deadbeef")
|
||||||
|
expect(reviews).to eq([])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "::get_artifact_url", :needs_network do
|
describe "::get_artifact_url", :needs_network do
|
||||||
it "fails to find a nonexistant workflow" do
|
it "fails to find a nonexistant workflow" do
|
||||||
expect {
|
expect {
|
||||||
|
|||||||
@ -392,6 +392,52 @@ module GitHub
|
|||||||
open_api(uri) { |json| json.fetch("items", []) }
|
open_api(uri) { |json| json.fetch("items", []) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def approved_reviews(user, repo, pr, commit: nil)
|
||||||
|
url = "https://api.github.com/graphql"
|
||||||
|
data = {
|
||||||
|
query: <<~EOS,
|
||||||
|
{ repository(name: "#{repo}", owner: "#{user}") {
|
||||||
|
pullRequest(number: #{pr}) {
|
||||||
|
reviews(states: APPROVED, first: 100) {
|
||||||
|
nodes {
|
||||||
|
author {
|
||||||
|
... on User { email login name databaseId }
|
||||||
|
... on Organization { email login name databaseId }
|
||||||
|
}
|
||||||
|
authorAssociation
|
||||||
|
commit { oid }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOS
|
||||||
|
}
|
||||||
|
result = open_api(url, data: data, request_method: "POST")
|
||||||
|
raise Error, result["errors"] if result["errors"].present?
|
||||||
|
|
||||||
|
reviews = result["data"]["repository"]["pullRequest"]["reviews"]["nodes"]
|
||||||
|
|
||||||
|
reviews.map do |r|
|
||||||
|
next if commit.present? && commit != r["commit"]["oid"]
|
||||||
|
next unless %w[MEMBER OWNER].include? r["authorAssociation"]
|
||||||
|
|
||||||
|
email = if r["author"]["email"].blank?
|
||||||
|
"#{r["author"]["databaseId"]}+#{r["author"]["login"]}@users.noreply.github.com"
|
||||||
|
else
|
||||||
|
r["author"]["email"]
|
||||||
|
end
|
||||||
|
|
||||||
|
name = r["author"]["name"].presence || r["author"]["login"]
|
||||||
|
|
||||||
|
{
|
||||||
|
"email" => email,
|
||||||
|
"name" => name,
|
||||||
|
"login" => r["author"]["login"],
|
||||||
|
}
|
||||||
|
end.compact
|
||||||
|
end
|
||||||
|
|
||||||
def dispatch_event(user, repo, event, **payload)
|
def dispatch_event(user, repo, event, **payload)
|
||||||
url = "#{API_URL}/repos/#{user}/#{repo}/dispatches"
|
url = "#{API_URL}/repos/#{user}/#{repo}/dispatches"
|
||||||
open_api(url, data: { event_type: event, client_payload: payload },
|
open_api(url, data: { event_type: event, client_payload: payload },
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user