pronto-github_resolver 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8853fcc6e38eef6f5fbaac5dc815cabd7e3e81e18136675a9cddfbc203f538d7
4
- data.tar.gz: ab3620bd675754fc045ff7619f3053f27829786f4076a19f0cbd317ed3f84d56
3
+ metadata.gz: 96e8c0465386136dab740a7e36d4804a1a84fe6e2cb9bfab2ff2d567494c80e7
4
+ data.tar.gz: 817f09eb49a66f716d384f301334bab472f5e939b03c71ba962780c02ce27002
5
5
  SHA512:
6
- metadata.gz: f7097355369c367d5d6232204fcc623cfb6755a494e4b81467904d97d671b46aa70c7d9339ebb92bc5a8a8e9ed4d56642cba344a73a31ecc56904959132d456a
7
- data.tar.gz: cf0f065244dea041390ceabafb2cb76dcf71e46ea4d512666106b5ff9f1cc62f071bb5eb87945cb642cb08298d5873d9559db404ccd8f3cc5f64791248fa70db
6
+ metadata.gz: e06e67a83cf9c1cfec2d4152812c2948fd802f785f3565202dccfa8ca7ccf3af04f4a1ceee1fa2f8485f8f5ac2fb99cc183949c792088d7785381612e7fb8d59
7
+ data.tar.gz: bb93f3ea985b455ad96897e05a2724dc0e63f4ecfd6b90c87e630a15b989aa2f4b06d0c56d2d4419ceb5ee255730ce6a265576ef0ea5fc37cfcd226be5709568
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pronto-github_resolver (0.0.1)
4
+ pronto-github_resolver (0.0.5)
5
5
  pronto (~> 0.11)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -22,7 +22,9 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ - When any of pronto runners emits message with level `:error` or `:fatal` - generated PR review will have resolution 'REQUEST_CHANGES', and default in other cases.
26
+ - On each run comment threads where message is no longer generated will be marked as resolved.
27
+ - Set ENV['PRONTO_GITHUB_BOT_ID'] to github id of your bot user. This enables posting PR 'APPROVE' review by bot after all messages are resolved.
26
28
 
27
29
  ## Development
28
30
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Pronto
4
4
  module GithubResolver
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.5"
6
6
  end
7
7
  end
@@ -29,7 +29,7 @@ module Pronto
29
29
  client.create_pull_request_review(slug, pull_id, options)
30
30
  end
31
31
 
32
- def approve_pull_request(message=nil)
32
+ def approve_pull_request(message="")
33
33
  client.create_pull_request_review(slug, pull_id, {
34
34
  event: 'APPROVE', body: message, accept: 'application/vnd.github.v3.diff+json'
35
35
  })
@@ -39,8 +39,64 @@ module Pronto
39
39
  client.pull_request_reviews(slug, pull_id)
40
40
  end
41
41
 
42
- def bot_user_id
43
- client.user.id
42
+ def get_review_threads
43
+ owner, repo_name = (slug || "").split('/')
44
+ res = client.post :graphql, { query: <<~GQL }.to_json
45
+ query getUserId {
46
+ repository(owner: "#{owner}", name: "#{repo_name}") {
47
+ pullRequest: issueOrPullRequest(number: #{pull_id}) {
48
+ ... on PullRequest {
49
+ reviewThreads(last:100) {
50
+ totalCount
51
+ nodes {
52
+ id
53
+ comments(last: 10) {
54
+ nodes {
55
+ viewerDidAuthor
56
+ path position body
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ GQL
66
+
67
+ if res.errors || !res.data
68
+ # ex: [{:message=>"Parse error on \"11\" (INT) at [1, 22]", :locations=>[{:line=>1, :column=>22}]}]
69
+ # TODO: handle errors
70
+ return []
71
+ end
72
+
73
+ res.data.repository.pullRequest.reviewThreads.nodes.to_h { |node|
74
+ [
75
+ node.id,
76
+ node.comments.nodes.map{ |comment|
77
+ {
78
+ authored: comment.viewerDidAuthor,
79
+ path: comment.path, position: comment.position, body: comment.body
80
+ }
81
+ }
82
+ ]
83
+ }
84
+ end
85
+
86
+ def resolve_review_threads(node_ids)
87
+ return unless node_ids.any?
88
+
89
+ owner, repo_name = (slug || "").split('/')
90
+ query = <<~GQL
91
+ mutation {
92
+ #{
93
+ node_ids.each_with_index.map {|id, index|
94
+ "q#{index}: resolveReviewThread(input: { threadId: \"#{id}\" }){ thread { id } } "
95
+ }.join("\n")
96
+ }
97
+ }
98
+ GQL
99
+ client.post :graphql, { query: query }.to_json
44
100
  end
45
101
  end
46
102
 
@@ -52,12 +108,14 @@ module Pronto
52
108
  comments = new_comments(messages, patches)
53
109
  additions = remove_duplicate_comments(existing, comments)
54
110
 
111
+ # TODO: we can reuse some threads from graphql for existing messages detection (but there's no pagination)
112
+ resolve_old_messages(client, repo, comments)
113
+
55
114
  if comments.none?
56
115
  bot_reviews = client.existing_pull_request_reviews.select { |review| review.user.type == 'Bot' }
57
116
  if bot_reviews.any?
58
- bot_id = client.bot_user_id
59
117
  current_bot_review_status = bot_reviews.inject(nil) do |prev_status, review|
60
- next prev_status unless review.user.id == bot_id
118
+ next prev_status unless review_by_this_bot?(review)
61
119
 
62
120
  case review.state
63
121
  when 'CHANGES_REQUESTED' then review.state
@@ -79,11 +137,29 @@ module Pronto
79
137
  "#{additions.count} Pronto messages posted to #{pretty_name}"
80
138
  end
81
139
 
140
+ def review_by_this_bot?(review)
141
+ ENV['PRONTO_GITHUB_BOT_ID'] && review.user.id == ENV['PRONTO_GITHUB_BOT_ID'].to_i
142
+ end
143
+
82
144
  def submit_comments(client, comments, event: nil)
83
145
  client.publish_pull_request_comments(comments, event: event)
84
146
  rescue Octokit::UnprocessableEntity, HTTParty::Error => e
85
147
  $stderr.puts "Failed to post: #{e.message}"
86
148
  end
149
+
150
+ def resolve_old_messages(client, repo, actual_comments)
151
+ thread_ids_to_resolve = []
152
+ client.get_review_threads.each_pair do |thread_id, thread_comments|
153
+ next unless thread_comments.all? do |comment|
154
+ comment[:authored] &&
155
+ (actual_comments[[comment[:path], comment[:position]]] || []).none? { |actual_comment|
156
+ comment[:body].include?(actual_comment.body)
157
+ }
158
+ end
159
+ thread_ids_to_resolve << thread_id
160
+ end
161
+ client.resolve_review_threads(thread_ids_to_resolve)
162
+ end
87
163
  end
88
164
 
89
165
  class GithubPullRequestResolvingReviewFormatter < PullRequestFormatter
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pronto-github_resolver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasily Fedoseyev