Skip to content

Commit 26813c0

Browse files
committed
Implement notes-github-pr post-receive hook
1 parent 4f68330 commit 26813c0

File tree

3 files changed

+98
-2
lines changed

3 files changed

+98
-2
lines changed

bin/notes-github-pr.rb

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env ruby
2+
# Add GitHub pull request reference to git notes.
3+
4+
require 'net/http'
5+
require 'uri'
6+
require 'tmpdir'
7+
require 'json'
8+
9+
class GitHub
10+
ENDPOINT = URI.parse('https://api.github.com')
11+
12+
def initialize(access_token)
13+
@access_token = access_token
14+
end
15+
16+
# https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/
17+
def pulls(owner:, repo:, commit_sha:)
18+
resp = get("/repos/#{owner}/#{repo}/commits/#{commit_sha}/pulls", accept: 'application/vnd.github.groot-preview+json')
19+
JSON.parse(resp.body)
20+
end
21+
22+
private
23+
24+
def get(path, accept: 'application/vnd.github.v3+json')
25+
Net::HTTP.start(ENDPOINT.host, ENDPOINT.port, use_ssl: ENDPOINT.scheme == 'https') do |http|
26+
headers = { 'Accept': accept, 'Authorization': "bearer #{@access_token}" }
27+
http.get(path, headers).tap(&:value)
28+
end
29+
end
30+
end
31+
32+
module Git
33+
class << self
34+
def abbrev_ref(refname)
35+
git('rev-parse', '--symbolic', '--abbrev-ref', refname).strip
36+
end
37+
38+
def rev_parse(arg, first_parent: false)
39+
git('rev-parse', *[('--first-parent' if first_parent)].compact, arg).lines.map(&:chomp)
40+
end
41+
42+
def commit_message(sha)
43+
git('log', '-1', '--pretty=format:%B', sha)
44+
end
45+
46+
def notes_message(sha)
47+
git('log', '-1', '--pretty=format:%N', sha)
48+
end
49+
50+
private
51+
52+
def git(*cmd)
53+
out = IO.popen(['git', *cmd], &:read)
54+
unless $?.success?
55+
abort "Failed to execute: git #{cmd.join(' ')}\n#{out}"
56+
end
57+
out
58+
end
59+
end
60+
end
61+
62+
github = GitHub.new(File.read(File.expand_path('~git/config/github-access-token')).chomp)
63+
64+
repo_path, *rest = ARGV
65+
rest.each_slice(3).map do |oldrev, newrev, refname|
66+
branch = Git.abbrev_ref(refname)
67+
next if branch != 'master' # we use pull requests only for master branches
68+
69+
Dir.mktmpdir do |workdir|
70+
depth = Git.rev_parse("#{oldrev}..#{newrev}").size + 1
71+
system('git', 'clone', "--depth=#{depth}", "--branch=#{branch}", "file:///#{repo_path}", workdir)
72+
Dir.chdir(workdir)
73+
74+
updated = false
75+
Git.rev_parse("#{oldrev}..#{newrev}", first_parent: true).each do |sha|
76+
github.pulls(owner: 'ruby', repo: 'ruby', commit_sha: sha).each do |pull|
77+
number = pull.fetch('number')
78+
url = pull.fetch('url')
79+
80+
message = Git.commit_message(sha)
81+
notes = Git.notes_message(sha)
82+
if !message.include?(url) && !message.include?("(##{number})") && !notes.include?(url)
83+
system('git', 'notes', 'append', '-m', "Merged: #{url}", sha)
84+
updated = true
85+
end
86+
end
87+
end
88+
89+
if updated
90+
system('git', 'push', 'origin', 'refs/notes/commits')
91+
end
92+
end
93+
end

hooks/post-receive-pre.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ curl -s "https://bugs.ruby-lang.org/sys/fetch_changesets?key=`cat ~git/config/re
3636
log "==> auto-style"
3737
SVN_ACCOUNT_NAME=git "${ruby_commit_hook}/bin/auto-style.rb" "$ruby_git" $*
3838

39-
log "==> update-version.h.rb"
39+
log "==> update-version.h"
4040
SVN_ACCOUNT_NAME=git "${ruby_commit_hook}/bin/update-version.h.rb" git "$ruby_git" $*
4141

4242
log "### end ###\n"

hooks/post-receive.sh

+4-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ curl -s "https://bugs.ruby-lang.org/sys/fetch_changesets?key=`cat ~git/config/re
3535
log "==> auto-style"
3636
SVN_ACCOUNT_NAME=git "${ruby_commit_hook}/bin/auto-style.rb" "$ruby_git" $*
3737

38-
log "==> update-version.h.rb"
38+
log "==> update-version.h"
3939
SVN_ACCOUNT_NAME=git "${ruby_commit_hook}/bin/update-version.h.rb" git "$ruby_git" $*
4040

41+
log "==> notes-github-pr"
42+
SVN_ACCOUNT_NAME=git "${ruby_commit_hook}/bin/notes-github-pr.rb" git "$ruby_git" $*
43+
4144
log "### end ###\n"

0 commit comments

Comments
 (0)