pronto 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +3 -0
- data/CHANGELOG.md +29 -0
- data/README.md +93 -2
- data/lib/pronto.rb +2 -0
- data/lib/pronto/clients/bitbucket_client.rb +46 -18
- data/lib/pronto/config.rb +16 -0
- data/lib/pronto/config_file.rb +4 -1
- data/lib/pronto/formatter/checkstyle_formatter.rb +1 -1
- data/lib/pronto/formatter/formatter.rb +2 -0
- data/lib/pronto/formatter/github_combined_status_formatter.rb +24 -0
- data/lib/pronto/formatter/github_pull_request_review_formatter.rb +1 -1
- data/lib/pronto/formatter/gitlab_merge_request_review_formatter.rb +29 -0
- data/lib/pronto/formatter/json_formatter.rb +1 -1
- data/lib/pronto/formatter/null_formatter.rb +1 -1
- data/lib/pronto/formatter/text_formatter.rb +1 -1
- data/lib/pronto/git/patch.rb +0 -2
- data/lib/pronto/git/repository.rb +2 -2
- data/lib/pronto/github.rb +25 -11
- data/lib/pronto/gitlab.rb +58 -1
- data/lib/pronto/runner.rb +8 -1
- data/lib/pronto/version.rb +1 -1
- data/pronto.gemspec +5 -4
- metadata +40 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46470dd7ac5341cc9bebbf13127f62c06d5d5a19cf55578a40439265761d59b3
|
4
|
+
data.tar.gz: a6a51d6593f9c4e521c8adf4a7fca559c3342931e7b207659e620d8d3585678a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e500bc433123227725e318c285995986ba6cf4a5281cbcb2be92aaac130515a788be5fabdd957d9d95e2f58fb95708bed6db193ab340c123760d8210471f4995
|
7
|
+
data.tar.gz: 1342570798515c8efdfcc17eaf383c308c8875031dd61cb4eef5821513c8e3a748b411b7112d5c210dabda11afc0831fc5767f08729dcad8d452e9c1215c60c1
|
data/.github/CODEOWNERS
ADDED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,35 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 0.11.0
|
6
|
+
|
7
|
+
### New features
|
8
|
+
|
9
|
+
* [#304](https://github.com/prontolabs/pronto/pull/304) add option to limit comments per PR review
|
10
|
+
* [#333](https://github.com/prontolabs/pronto/pull/333) add github_combined_status formatter
|
11
|
+
* [#334](https://github.com/prontolabs/pronto/pull/334) add configurable review_type for GitHub (with REQUEST_CHANGES as default)
|
12
|
+
* [#351](https://github.com/prontolabs/pronto/pull/351) add gitLab_mr formatter
|
13
|
+
* [#369](https://github.com/prontolabs/pronto/pull/369) make Pronto::Git::Patch#new_file_path public
|
14
|
+
* update to the BitBucket 2.0 API (_as the 1.0 API was deprecated_) via [#347](https://github.com/prontolabs/pronto/pull/347), [#348](https://github.com/prontolabs/pronto/pull/348), [#352](https://github.com/prontolabs/pronto/pull/352) and [#354](https://github.com/prontolabs/pronto/pull/354)
|
15
|
+
|
16
|
+
### Bugs fixed
|
17
|
+
|
18
|
+
* [#344](https://github.com/prontolabs/pronto/pull/344) treat Gemfile and .gemspecs as Ruby
|
19
|
+
* [#380](https://github.com/prontolabs/pronto/pull/380) fix compatibility with rugged >= 0.99
|
20
|
+
* [#387](https://github.com/prontolabs/pronto/pull/387) fix running pronto inside git submodules
|
21
|
+
|
22
|
+
### Changes
|
23
|
+
|
24
|
+
* [#370](https://github.com/prontolabs/pronto/pull/370) allow thor 1.x gem versions
|
25
|
+
* [#379](https://github.com/prontolabs/pronto/pull/379) allow rugged 1.0.x gem versions
|
26
|
+
* [#386](https://github.com/prontolabs/pronto/pull/386) add ruby 2.7 to CI
|
27
|
+
* [#390](https://github.com/prontolabs/pronto/pull/390) fix issue with generating Sorbet RBI
|
28
|
+
* [#396](https://github.com/prontolabs/pronto/pull/396) add support for Ruby 3.0
|
29
|
+
* document/improve GitHub Actions integration in README.md via [#360](https://github.com/prontolabs/pronto/pull/360), [#378](https://github.com/prontolabs/pronto/pull/378) and [#389](https://github.com/prontolabs/pronto/pull/389)
|
30
|
+
* add links to additional pronto runners in README.md
|
31
|
+
|
32
|
+
## 0.10.0
|
33
|
+
|
5
34
|
### New features
|
6
35
|
|
7
36
|
* [#301](https://github.com/prontolabs/pronto/pull/301): add ability to auto approve Bitbucket pull requests.
|
data/README.md
CHANGED
@@ -110,18 +110,40 @@ If you want comments to appear on pull request diff, instead of commit:
|
|
110
110
|
$ PRONTO_GITHUB_ACCESS_TOKEN=token pronto run -f github_pr -c origin/master
|
111
111
|
```
|
112
112
|
|
113
|
-
If you want review to appear on pull request diff, instead of comments:
|
113
|
+
If you want review to appear on pull request diff, instead of separate comments:
|
114
114
|
|
115
115
|
```sh
|
116
116
|
$ PRONTO_GITHUB_ACCESS_TOKEN=token pronto run -f github_pr_review -c origin/master
|
117
117
|
```
|
118
118
|
|
119
|
+
All the **N** pending comments will be now separated into **X** number of PR reviews.
|
120
|
+
The number of the PR reviews will be controlled by an additional environment variable or with the help of a config setting.
|
121
|
+
This way, by a single pronto run, all the comments will be published to the PR, but divided into small reviews
|
122
|
+
in order to avoid the rate limit of the providers.
|
123
|
+
|
124
|
+
```
|
125
|
+
X = N / {PRONTO_WARNINGS_PER_REVIEW || warnings_per_review || 30})
|
126
|
+
```
|
127
|
+
|
128
|
+
Note: In case no environment variable or config setting is specified in `.pronto.yml`,
|
129
|
+
a default value of `30` will be used.
|
130
|
+
|
131
|
+
```sh
|
132
|
+
$ PRONTO_WARNINGS_PER_REVIEW=30 PRONTO_GITHUB_ACCESS_TOKEN=token pronto run -f github_pr_review -c origin/master
|
133
|
+
```
|
134
|
+
|
119
135
|
Use `GithubStatusFormatter` to submit [commit status](https://github.com/blog/1227-commit-status-api):
|
120
136
|
|
121
137
|
```sh
|
122
138
|
$ PRONTO_GITHUB_ACCESS_TOKEN=token pronto run -f github_status -c origin/master
|
123
139
|
```
|
124
140
|
|
141
|
+
If you want to show a one single status for all runners, instead of status per runner:
|
142
|
+
|
143
|
+
```sh
|
144
|
+
$ PRONTO_GITHUB_ACCESS_TOKEN=token pronto run -f github_combined_status -c origin/master
|
145
|
+
```
|
146
|
+
|
125
147
|
It's possible to combine multiple formatters.
|
126
148
|
To get both pull request comments and commit status summary use:
|
127
149
|
|
@@ -140,6 +162,39 @@ formatters = [formatter, status_formatter]
|
|
140
162
|
Pronto.run('origin/master', '.', formatters)
|
141
163
|
```
|
142
164
|
|
165
|
+
#### GitHub Actions Integration
|
166
|
+
|
167
|
+
You can also run Pronto as a GitHub action.
|
168
|
+
|
169
|
+
Here's an example `.github/workflows/pronto.yml` workflow file using the `github_status` and `github_pr` formatters and running on each GitHub PR, with `pronto-rubocop` as the runner:
|
170
|
+
|
171
|
+
|
172
|
+
```yml
|
173
|
+
name: Pronto
|
174
|
+
on: [pull_request]
|
175
|
+
|
176
|
+
jobs:
|
177
|
+
pronto:
|
178
|
+
|
179
|
+
runs-on: ubuntu-latest
|
180
|
+
|
181
|
+
steps:
|
182
|
+
- name: Checkout code
|
183
|
+
uses: actions/checkout@v2
|
184
|
+
- run: |
|
185
|
+
git fetch --no-tags --prune --depth=10 origin +refs/heads/*:refs/remotes/origin/*
|
186
|
+
- name: Setup Ruby
|
187
|
+
uses: ruby/setup-ruby@v1
|
188
|
+
- name: Setup pronto
|
189
|
+
run: gem install pronto pronto-rubocop
|
190
|
+
- name: Run Pronto
|
191
|
+
run: pronto run -f github_status github_pr -c origin/${{ github.base_ref }}
|
192
|
+
env:
|
193
|
+
PRONTO_PULL_REQUEST_ID: ${{ github.event.pull_request.number }}
|
194
|
+
PRONTO_GITHUB_ACCESS_TOKEN: "${{ github.token }}"
|
195
|
+
```
|
196
|
+
check Wiki on [GitHub Actions Integration](https://github.com/prontolabs/pronto/wiki/GitHub-Actions-Integration) for more info.
|
197
|
+
|
143
198
|
### GitLab Integration
|
144
199
|
|
145
200
|
You can run Pronto as a step of your CI builds and get the results as comments
|
@@ -159,6 +214,29 @@ Then just run it:
|
|
159
214
|
$ PRONTO_GITLAB_API_PRIVATE_TOKEN=token pronto run -f gitlab -c origin/master
|
160
215
|
```
|
161
216
|
|
217
|
+
**note: this requires at least Gitlab 11.6+**
|
218
|
+
|
219
|
+
Merge request integration:
|
220
|
+
|
221
|
+
```sh
|
222
|
+
$ PRONTO_GITLAB_API_PRIVATE_TOKEN=token PRONTO_PULL_REQUEST_ID=id pronto run -f gitlab_mr -c origin/master
|
223
|
+
```
|
224
|
+
|
225
|
+
On GitLabCI make make sure to run Pronto in a [merge request pipeline](https://docs.gitlab.com/ce/ci/merge_request_pipelines/):
|
226
|
+
|
227
|
+
```yml
|
228
|
+
lint:
|
229
|
+
image: ruby
|
230
|
+
variables:
|
231
|
+
PRONTO_GITLAB_API_ENDPOINT: "https://gitlab.com/api/v4"
|
232
|
+
PRONTO_GITLAB_API_PRIVATE_TOKEN: token
|
233
|
+
only:
|
234
|
+
- merge_requests
|
235
|
+
script:
|
236
|
+
- bundle install
|
237
|
+
- bundle exec pronto run -f gitlab_mr -c origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
238
|
+
```
|
239
|
+
|
162
240
|
### Bitbucket Integration
|
163
241
|
|
164
242
|
You can run Pronto as a step of your CI builds and get the results as comments
|
@@ -210,6 +288,7 @@ bitbucket:
|
|
210
288
|
password: pass
|
211
289
|
web_endpoint: https://bitbucket.org/
|
212
290
|
max_warnings: 150
|
291
|
+
warnings_per_review: 30
|
213
292
|
verbose: false
|
214
293
|
```
|
215
294
|
|
@@ -260,13 +339,17 @@ The following values are available only to the text formatter:
|
|
260
339
|
Pronto can run various tools and libraries, as long as there's a runner for it.
|
261
340
|
Currently available:
|
262
341
|
|
342
|
+
* [pronto-bigfiles](https://github.com/apiology/pronto-bigfiles)
|
263
343
|
* [pronto-blacklist](https://github.com/pbstriker38/pronto-blacklist)
|
264
344
|
* [pronto-brakeman](https://github.com/prontolabs/pronto-brakeman)
|
345
|
+
* [pronto-bundler_audit](https://github.com/pdobb/pronto-bundler_audit)
|
346
|
+
* [pronto-checkstyle](https://github.com/seikichi/pronto-checkstyle)
|
265
347
|
* [pronto-coffeelint](https://github.com/siebertm/pronto-coffeelint)
|
266
348
|
* [pronto-clang_format](https://github.com/micjabbour/pronto-clang_format)
|
267
349
|
* [pronto-clang_tidy](https://github.com/micjabbour/pronto-clang_tidy)
|
268
350
|
* [pronto-clippy](https://github.com/hauleth/pronto-clippy)
|
269
351
|
* [pronto-credo](https://github.com/carakan/pronto-credo)
|
352
|
+
* [pronto-dialyxir](https://github.com/Apelsinka223/pronto-dialyxir)
|
270
353
|
* [pronto-dialyzer](https://github.com/iurifq/pronto-dialyzer)
|
271
354
|
* [pronto-dirty_words](https://github.com/kevinjalbert/pronto-dirty_words)
|
272
355
|
* [pronto-dogma](https://github.com/iurifq/pronto-dogma)
|
@@ -274,11 +357,15 @@ Currently available:
|
|
274
357
|
* [pronto-eslint](https://github.com/prontolabs/pronto-eslint) (uses [eslintrb](https://github.com/zendesk/eslintrb))
|
275
358
|
* [pronto-eslint_npm](https://github.com/doits/pronto-eslint_npm) (uses eslint installed from npm)
|
276
359
|
* [pronto-fasterer](https://github.com/prontolabs/pronto-fasterer)
|
360
|
+
* [pronto-findbugs](https://github.com/seikichi/pronto-findbugs)
|
277
361
|
* [pronto-flake8](https://github.com/scoremedia/pronto-flake8)
|
278
362
|
* [pronto-flay](https://github.com/prontolabs/pronto-flay)
|
279
363
|
* [pronto-flow](https://github.com/kevinjalbert/pronto-flow)
|
280
364
|
* [pronto-foodcritic](https://github.com/prontolabs/pronto-foodcritic)
|
365
|
+
* [pronto-goodcheck](https://github.com/aergonaut/pronto-goodcheck)
|
281
366
|
* [pronto-haml](https://github.com/prontolabs/pronto-haml)
|
367
|
+
* [pronto-hlint](https://github.com/fretlink/pronto-hlint/) (uses Haskell code suggestions [hlint](https://github.com/ndmitchell/hlint))
|
368
|
+
* [pronto-infer](https://github.com/seikichi/pronto-infer)
|
282
369
|
* [pronto-inspec](https://github.com/stiller-leser/pronto-inspec)
|
283
370
|
* [pronto-jscs](https://github.com/spajus/pronto-jscs)
|
284
371
|
* [pronto-jshint](https://github.com/prontolabs/pronto-jshint)
|
@@ -289,7 +376,9 @@ Currently available:
|
|
289
376
|
* [pronto-phpmd](https://github.com/EllisV/pronto-phpmd)
|
290
377
|
* [pronto-phpstan](https://github.com/Powerhamster/pronto-phpstan)
|
291
378
|
* [pronto-poper](https://github.com/prontolabs/pronto-poper)
|
379
|
+
* [pronto-punchlist](https://github.com/apiology/pronto-punchlist)
|
292
380
|
* [pronto-rails_best_practices](https://github.com/prontolabs/pronto-rails_best_practices)
|
381
|
+
* [pronto-rails_data_schema](https://github.com/mbajur/pronto-rails_data_schema)
|
293
382
|
* [pronto-rails_schema](https://github.com/raimondasv/pronto-rails_schema)
|
294
383
|
* [pronto-reek](https://github.com/prontolabs/pronto-reek)
|
295
384
|
* [pronto-rubocop](https://github.com/prontolabs/pronto-rubocop)
|
@@ -297,15 +386,17 @@ Currently available:
|
|
297
386
|
* [pronto-shellcheck](https://github.com/pclalv/pronto-shellcheck)
|
298
387
|
* [pronto-slim](https://github.com/nysthee/pronto-slim)
|
299
388
|
* [pronto-slim_lint](https://github.com/ibrahima/pronto-slim_lint)
|
389
|
+
* [pronto-sorbet](https://github.com/teamsimplepay/pronto-sorbet)
|
300
390
|
* [pronto-spell](https://github.com/prontolabs/pronto-spell)
|
391
|
+
* [pronto-standardrb](https://github.com/julianrubisch/pronto-standardrb)
|
301
392
|
* [pronto-stylelint](https://github.com/kevinjalbert/pronto-stylelint)
|
302
393
|
* [pronto-swiftlint](https://github.com/ajanauskas/pronto-swiftlint)
|
303
394
|
* [pronto-tailor](https://github.com/ajanauskas/pronto-tailor)
|
304
395
|
* [pronto-textlint](https://github.com/seikichi/pronto-textlint)
|
305
396
|
* [pronto-tslint_npm](https://github.com/eprislac/pronto-tslint_npm)
|
306
397
|
* [pronto-yamllint](https://github.com/pauliusm/pronto-yamllint)
|
307
|
-
* [pronto-goodcheck](https://github.com/aergonaut/pronto-goodcheck)
|
308
398
|
* [pronto-undercover](https://github.com/grodowski/pronto-undercover)
|
399
|
+
* [pronto-xmllint](https://github.com/pauliusm/pronto-xmllint)
|
309
400
|
|
310
401
|
## Articles
|
311
402
|
|
data/lib/pronto.rb
CHANGED
@@ -42,9 +42,11 @@ require 'pronto/formatter/commit_formatter'
|
|
42
42
|
require 'pronto/formatter/pull_request_formatter'
|
43
43
|
require 'pronto/formatter/github_formatter'
|
44
44
|
require 'pronto/formatter/github_status_formatter'
|
45
|
+
require 'pronto/formatter/github_combined_status_formatter'
|
45
46
|
require 'pronto/formatter/github_pull_request_formatter'
|
46
47
|
require 'pronto/formatter/github_pull_request_review_formatter'
|
47
48
|
require 'pronto/formatter/gitlab_formatter'
|
49
|
+
require 'pronto/formatter/gitlab_merge_request_review_formatter'
|
48
50
|
require 'pronto/formatter/bitbucket_formatter'
|
49
51
|
require 'pronto/formatter/bitbucket_pull_request_formatter'
|
50
52
|
require 'pronto/formatter/bitbucket_server_pull_request_formatter'
|
@@ -1,28 +1,39 @@
|
|
1
1
|
class BitbucketClient
|
2
2
|
include HTTParty
|
3
|
-
base_uri 'https://api.bitbucket.org/
|
3
|
+
base_uri 'https://api.bitbucket.org/2.0/repositories'
|
4
4
|
|
5
5
|
def initialize(username, password)
|
6
6
|
self.class.basic_auth(username, password)
|
7
7
|
end
|
8
8
|
|
9
9
|
def commit_comments(slug, sha)
|
10
|
-
response = get("/#{slug}/
|
11
|
-
openstruct(response)
|
10
|
+
response = get("/#{slug}/commit/#{sha}/comments?pagelen=100")
|
11
|
+
result = parse_comments(openstruct(response))
|
12
|
+
while (response['next'])
|
13
|
+
response = get response['next']
|
14
|
+
result.concat(parse_comments(openstruct(response)))
|
15
|
+
end
|
16
|
+
result
|
12
17
|
end
|
13
18
|
|
14
19
|
def create_commit_comment(slug, sha, body, path, position)
|
15
|
-
post("/#{slug}/
|
20
|
+
post("/#{slug}/commit/#{sha}/comments", body, path, position)
|
16
21
|
end
|
17
22
|
|
18
23
|
def pull_comments(slug, pull_id)
|
19
|
-
response = get("/#{slug}/pullrequests/#{pull_id}/comments")
|
20
|
-
openstruct(response)
|
24
|
+
response = get("/#{slug}/pullrequests/#{pull_id}/comments?pagelen=100")
|
25
|
+
parse_comments(openstruct(response))
|
26
|
+
result = parse_comments(openstruct(response))
|
27
|
+
while (response['next'])
|
28
|
+
response = get response['next']
|
29
|
+
result.concat(parse_comments(openstruct(response)))
|
30
|
+
end
|
31
|
+
result
|
21
32
|
end
|
22
33
|
|
23
34
|
def pull_requests(slug)
|
24
|
-
response = get("
|
25
|
-
openstruct(response
|
35
|
+
response = get("/#{slug}/pullrequests?state=OPEN")
|
36
|
+
openstruct(response)
|
26
37
|
end
|
27
38
|
|
28
39
|
def create_pull_comment(slug, pull_id, body, path, position)
|
@@ -30,29 +41,46 @@ class BitbucketClient
|
|
30
41
|
end
|
31
42
|
|
32
43
|
def approve_pull_request(slug, pull_id)
|
33
|
-
self.class.post("
|
44
|
+
self.class.post("/#{slug}/pullrequests/#{pull_id}/approve")
|
34
45
|
end
|
35
46
|
|
36
47
|
def unapprove_pull_request(slug, pull_id)
|
37
|
-
self.class.delete("
|
48
|
+
self.class.delete("/#{slug}/pullrequests/#{pull_id}/approve")
|
38
49
|
end
|
39
50
|
|
40
51
|
private
|
41
52
|
|
42
|
-
def pull_request_api(slug)
|
43
|
-
"https://api.bitbucket.org/2.0/repositories/#{slug}"
|
44
|
-
end
|
45
|
-
|
46
53
|
def openstruct(response)
|
47
|
-
response
|
54
|
+
if response['values']
|
55
|
+
response['values'].map { |r| OpenStruct.new(r) }
|
56
|
+
else
|
57
|
+
p response
|
58
|
+
raise 'BitBucket response invalid'
|
59
|
+
end
|
48
60
|
end
|
49
61
|
|
62
|
+
def parse_comments(values)
|
63
|
+
values.each do |value|
|
64
|
+
value.content = value.content['raw']
|
65
|
+
value.line_to = value.inline ? value.inline['to'] : 0
|
66
|
+
value.filename = value.inline ? value.inline['path'] : ''
|
67
|
+
end
|
68
|
+
values
|
69
|
+
end
|
70
|
+
|
50
71
|
def post(url, body, path, position)
|
51
72
|
options = {
|
52
73
|
body: {
|
53
|
-
content:
|
54
|
-
|
55
|
-
|
74
|
+
content: {
|
75
|
+
raw: body
|
76
|
+
},
|
77
|
+
inline: {
|
78
|
+
to: position,
|
79
|
+
path: path
|
80
|
+
}
|
81
|
+
}.to_json,
|
82
|
+
headers: {
|
83
|
+
'Content-Type': 'application/json'
|
56
84
|
}
|
57
85
|
}
|
58
86
|
self.class.post(url, options)
|
data/lib/pronto/config.rb
CHANGED
@@ -18,6 +18,18 @@ module Pronto
|
|
18
18
|
consolidated
|
19
19
|
end
|
20
20
|
|
21
|
+
def github_review_type
|
22
|
+
review_type =
|
23
|
+
ENV['PRONTO_GITHUB_REVIEW_TYPE'] ||
|
24
|
+
@config_hash.fetch('github_review_type', false)
|
25
|
+
|
26
|
+
if review_type == 'request_changes'
|
27
|
+
'REQUEST_CHANGES'
|
28
|
+
else
|
29
|
+
'COMMENT'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
def excluded_files(runner)
|
22
34
|
files =
|
23
35
|
if runner == 'all'
|
@@ -39,6 +51,10 @@ module Pronto
|
|
39
51
|
URI.parse(bitbucket_web_endpoint).host
|
40
52
|
end
|
41
53
|
|
54
|
+
def warnings_per_review
|
55
|
+
ENV['PRONTO_WARNINGS_PER_REVIEW'] && Integer(ENV['PRONTO_WARNINGS_PER_REVIEW']) || @config_hash['warnings_per_review']
|
56
|
+
end
|
57
|
+
|
42
58
|
def max_warnings
|
43
59
|
ENV['PRONTO_MAX_WARNINGS'] && Integer(ENV['PRONTO_MAX_WARNINGS']) || @config_hash['max_warnings']
|
44
60
|
end
|
data/lib/pronto/config_file.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Pronto
|
2
2
|
class ConfigFile
|
3
3
|
DEFAULT_MESSAGE_FORMAT = '%{msg}'.freeze
|
4
|
+
DEFAULT_WARNINGS_PER_REVIEW = 30
|
4
5
|
|
5
6
|
EMPTY = {
|
6
7
|
'all' => {
|
@@ -11,7 +12,8 @@ module Pronto
|
|
11
12
|
'slug' => nil,
|
12
13
|
'access_token' => nil,
|
13
14
|
'api_endpoint' => 'https://api.github.com/',
|
14
|
-
'web_endpoint' => 'https://github.com/'
|
15
|
+
'web_endpoint' => 'https://github.com/',
|
16
|
+
'review_type' => 'request_changes'
|
15
17
|
},
|
16
18
|
'gitlab' => {
|
17
19
|
'slug' => nil,
|
@@ -32,6 +34,7 @@ module Pronto
|
|
32
34
|
'runners' => [],
|
33
35
|
'formatters' => [],
|
34
36
|
'max_warnings' => nil,
|
37
|
+
'warnings_per_review' => DEFAULT_WARNINGS_PER_REVIEW,
|
35
38
|
'verbose' => false,
|
36
39
|
'format' => DEFAULT_MESSAGE_FORMAT
|
37
40
|
}.freeze
|
@@ -13,9 +13,11 @@ module Pronto
|
|
13
13
|
FORMATTERS = {
|
14
14
|
'github' => GithubFormatter,
|
15
15
|
'github_status' => GithubStatusFormatter,
|
16
|
+
'github_combined_status' => GithubCombinedStatusFormatter,
|
16
17
|
'github_pr' => GithubPullRequestFormatter,
|
17
18
|
'github_pr_review' => GithubPullRequestReviewFormatter,
|
18
19
|
'gitlab' => GitlabFormatter,
|
20
|
+
'gitlab_mr' => GitlabMergeRequestReviewFormatter,
|
19
21
|
'bitbucket' => BitbucketFormatter,
|
20
22
|
'bitbucket_pr' => BitbucketPullRequestFormatter,
|
21
23
|
'bitbucket_server_pr' => BitbucketServerPullRequestFormatter,
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'github_status_formatter/status_builder'
|
2
|
+
|
3
|
+
module Pronto
|
4
|
+
module Formatter
|
5
|
+
class GithubCombinedStatusFormatter
|
6
|
+
def format(messages, repo, _)
|
7
|
+
client = Github.new(repo)
|
8
|
+
head = repo.head_commit_sha
|
9
|
+
|
10
|
+
create_status(client, head, messages.uniq || [])
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def create_status(client, sha, messages)
|
16
|
+
builder = GithubStatusFormatter::StatusBuilder.new(nil, messages)
|
17
|
+
status = Status.new(sha, builder.state,
|
18
|
+
'pronto', builder.description)
|
19
|
+
|
20
|
+
client.create_commit_status(status)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -10,7 +10,7 @@ module Pronto
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def submit_comments(client, comments)
|
13
|
-
client.
|
13
|
+
client.publish_pull_request_comments(comments)
|
14
14
|
rescue Octokit::UnprocessableEntity, HTTParty::Error => e
|
15
15
|
$stderr.puts "Failed to post: #{e.message}"
|
16
16
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pronto
|
2
|
+
module Formatter
|
3
|
+
class GitlabMergeRequestReviewFormatter < PullRequestFormatter
|
4
|
+
def client_module
|
5
|
+
Gitlab
|
6
|
+
end
|
7
|
+
|
8
|
+
def pretty_name
|
9
|
+
'Gitlab'
|
10
|
+
end
|
11
|
+
|
12
|
+
def existing_comments(_, client, repo)
|
13
|
+
sha = repo.head_commit_sha
|
14
|
+
comments = client.pull_comments(sha)
|
15
|
+
grouped_comments(comments)
|
16
|
+
end
|
17
|
+
|
18
|
+
def submit_comments(client, comments)
|
19
|
+
client.create_pull_request_review(comments)
|
20
|
+
rescue => e
|
21
|
+
$stderr.puts "Failed to post: #{e.message}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def line_number(message, _)
|
25
|
+
message.line.line.new_lineno if message.line
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -3,7 +3,7 @@ require 'pronto/formatter/text_message_decorator'
|
|
3
3
|
module Pronto
|
4
4
|
module Formatter
|
5
5
|
class TextFormatter < Base
|
6
|
-
def format(messages,
|
6
|
+
def format(messages, _repo, _patches)
|
7
7
|
messages.map do |message|
|
8
8
|
message_format = config.message_format(self.class.name)
|
9
9
|
message_data = TextMessageDecorator.new(message).to_h
|
data/lib/pronto/git/patch.rb
CHANGED
@@ -38,7 +38,7 @@ module Pronto
|
|
38
38
|
|
39
39
|
def commits_until(sha)
|
40
40
|
result = []
|
41
|
-
@repo.walk(
|
41
|
+
@repo.walk(head_commit_sha, Rugged::SORT_TOPO).take_while do |commit|
|
42
42
|
result << commit.oid
|
43
43
|
!commit.oid.start_with?(sha)
|
44
44
|
end
|
@@ -46,7 +46,7 @@ module Pronto
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def path
|
49
|
-
Pathname.new(@repo.
|
49
|
+
Pathname.new(@repo.workdir).cleanpath
|
50
50
|
end
|
51
51
|
|
52
52
|
def blame(path, lineno)
|
data/lib/pronto/github.rb
CHANGED
@@ -45,17 +45,12 @@ module Pronto
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
comments: comments.map do |c|
|
55
|
-
{ path: c.path, position: c.position, body: c.body }
|
56
|
-
end
|
57
|
-
}
|
58
|
-
client.create_pull_request_review(slug, pull_id, options)
|
48
|
+
def publish_pull_request_comments(comments)
|
49
|
+
comments_left = comments.clone
|
50
|
+
while comments_left.any?
|
51
|
+
comments_to_publish = comments_left.slice!(0, warnings_per_review)
|
52
|
+
create_pull_request_review(comments_to_publish)
|
53
|
+
end
|
59
54
|
end
|
60
55
|
|
61
56
|
def create_commit_status(status)
|
@@ -68,6 +63,21 @@ module Pronto
|
|
68
63
|
|
69
64
|
private
|
70
65
|
|
66
|
+
def create_pull_request_review(comments)
|
67
|
+
options = {
|
68
|
+
event: @config.github_review_type,
|
69
|
+
accept: 'application/vnd.github.v3.diff+json', # https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
|
70
|
+
comments: comments.map do |comment|
|
71
|
+
{
|
72
|
+
path: comment.path,
|
73
|
+
position: comment.position,
|
74
|
+
body: comment.body
|
75
|
+
}
|
76
|
+
end
|
77
|
+
}
|
78
|
+
client.create_pull_request_review(slug, pull_id, options)
|
79
|
+
end
|
80
|
+
|
71
81
|
def slug
|
72
82
|
return @config.github_slug if @config.github_slug
|
73
83
|
@slug ||= begin
|
@@ -103,5 +113,9 @@ module Pronto
|
|
103
113
|
@github_pull.pull_by_commit(@repo.head_commit_sha)
|
104
114
|
end
|
105
115
|
end
|
116
|
+
|
117
|
+
def warnings_per_review
|
118
|
+
@warnings_per_review ||= @config.warnings_per_review
|
119
|
+
end
|
106
120
|
end
|
107
121
|
end
|
data/lib/pronto/gitlab.rb
CHANGED
@@ -2,12 +2,49 @@ module Pronto
|
|
2
2
|
class Gitlab < Client
|
3
3
|
def commit_comments(sha)
|
4
4
|
@comment_cache[sha.to_s] ||= begin
|
5
|
-
client.commit_comments(slug, sha
|
5
|
+
client.commit_comments(slug, sha).auto_paginate.map do |comment|
|
6
6
|
Comment.new(sha, comment.note, comment.path, comment.line)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def pull_comments(sha)
|
12
|
+
@comment_cache["#{slug}/#{pull_id}"] ||= begin
|
13
|
+
arr = []
|
14
|
+
client.merge_request_discussions(slug, pull_id).auto_paginate.each do |comment|
|
15
|
+
comment.notes.each do |note|
|
16
|
+
next unless note['position']
|
17
|
+
|
18
|
+
arr << Comment.new(
|
19
|
+
sha,
|
20
|
+
note['body'],
|
21
|
+
note['position']['new_path'],
|
22
|
+
note['position']['new_line']
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
arr
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_pull_request_review(comments)
|
31
|
+
return if comments.empty?
|
32
|
+
|
33
|
+
comments.each do |comment|
|
34
|
+
options = {
|
35
|
+
body: comment.body,
|
36
|
+
position: position_sha.dup.merge(
|
37
|
+
new_path: comment.path,
|
38
|
+
position_type: 'text',
|
39
|
+
new_line: comment.position,
|
40
|
+
old_line: nil,
|
41
|
+
)
|
42
|
+
}
|
43
|
+
|
44
|
+
client.create_merge_request_discussion(slug, pull_id, options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
11
48
|
def create_commit_comment(comment)
|
12
49
|
@config.logger.log("Creating commit comment on #{comment.sha}")
|
13
50
|
client.create_commit_comment(slug, comment.sha, comment.body,
|
@@ -17,6 +54,15 @@ module Pronto
|
|
17
54
|
|
18
55
|
private
|
19
56
|
|
57
|
+
def position_sha
|
58
|
+
# Better to get those informations from Gitlab API directly than trying to look for them here.
|
59
|
+
# (FYI you can't use `pull` method because index api does not contains those informations)
|
60
|
+
@position_sha ||= begin
|
61
|
+
data = client.merge_request(slug, pull_id)
|
62
|
+
data.diff_refs.to_h
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
20
66
|
def slug
|
21
67
|
return @config.gitlab_slug if @config.gitlab_slug
|
22
68
|
@slug ||= begin
|
@@ -27,6 +73,17 @@ module Pronto
|
|
27
73
|
end
|
28
74
|
end
|
29
75
|
|
76
|
+
def pull_id
|
77
|
+
env_pull_id || raise(Pronto::Error, "Unable to determine merge request id. Specify either `PRONTO_PULL_REQUEST_ID` or `CI_MERGE_REQUEST_IID`.")
|
78
|
+
end
|
79
|
+
|
80
|
+
def env_pull_id
|
81
|
+
pull_request = super
|
82
|
+
|
83
|
+
pull_request ||= ENV['CI_MERGE_REQUEST_IID']
|
84
|
+
pull_request.to_i if pull_request
|
85
|
+
end
|
86
|
+
|
30
87
|
def slug_regex(url)
|
31
88
|
if url =~ %r{^ssh:\/\/}
|
32
89
|
%r{.*#{host}(:[0-9]+)?(:|\/)(?<slug>.*).git}
|
data/lib/pronto/runner.rb
CHANGED
@@ -28,7 +28,10 @@ module Pronto
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def ruby_file?(path)
|
31
|
-
rb_file?(path) ||
|
31
|
+
rb_file?(path) ||
|
32
|
+
rake_file?(path) ||
|
33
|
+
gem_file?(path) ||
|
34
|
+
ruby_executable?(path)
|
32
35
|
end
|
33
36
|
|
34
37
|
def repo_path
|
@@ -45,6 +48,10 @@ module Pronto
|
|
45
48
|
File.extname(path) == '.rake'
|
46
49
|
end
|
47
50
|
|
51
|
+
def gem_file?(path)
|
52
|
+
File.basename(path) == 'Gemfile' || File.extname(path) == '.gemspec'
|
53
|
+
end
|
54
|
+
|
48
55
|
def ruby_executable?(path)
|
49
56
|
return false if File.directory?(path)
|
50
57
|
line = File.open(path, &:readline)
|
data/lib/pronto/version.rb
CHANGED
data/pronto.gemspec
CHANGED
@@ -40,14 +40,15 @@ Gem::Specification.new do |s|
|
|
40
40
|
s.require_paths = ['lib']
|
41
41
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
42
42
|
|
43
|
-
s.add_runtime_dependency('gitlab', '~> 4.
|
43
|
+
s.add_runtime_dependency('gitlab', '~> 4.4', '>= 4.4.0')
|
44
44
|
s.add_runtime_dependency('httparty', '>= 0.13.7')
|
45
45
|
s.add_runtime_dependency('octokit', '~> 4.7', '>= 4.7.0')
|
46
46
|
s.add_runtime_dependency('rainbow', '>= 2.2', '< 4.0')
|
47
|
-
s.add_runtime_dependency('
|
48
|
-
s.add_runtime_dependency('
|
47
|
+
s.add_runtime_dependency('rexml', '~> 3.2')
|
48
|
+
s.add_runtime_dependency('rugged', '>= 0.23.0', '< 1.1.0')
|
49
|
+
s.add_runtime_dependency('thor', '>= 0.20.3', '< 2.0')
|
49
50
|
s.add_development_dependency('bundler', '>= 1.15')
|
50
|
-
s.add_development_dependency('pronto-rubocop', '~> 0.
|
51
|
+
s.add_development_dependency('pronto-rubocop', '~> 0.10.0')
|
51
52
|
s.add_development_dependency('rake', '~> 12.0')
|
52
53
|
s.add_development_dependency('rspec', '~> 3.4')
|
53
54
|
s.add_development_dependency('rspec-its', '~> 1.2')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pronto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mindaugas Mozūras
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gitlab
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.
|
19
|
+
version: 4.4.0
|
20
20
|
- - "~>"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '4.
|
22
|
+
version: '4.4'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 4.
|
29
|
+
version: 4.4.0
|
30
30
|
- - "~>"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '4.
|
32
|
+
version: '4.4'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: httparty
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +84,20 @@ dependencies:
|
|
84
84
|
- - "<"
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '4.0'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rexml
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '3.2'
|
94
|
+
type: :runtime
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '3.2'
|
87
101
|
- !ruby/object:Gem::Dependency
|
88
102
|
name: rugged
|
89
103
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,9 +105,9 @@ dependencies:
|
|
91
105
|
- - ">="
|
92
106
|
- !ruby/object:Gem::Version
|
93
107
|
version: 0.23.0
|
94
|
-
- - "
|
108
|
+
- - "<"
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
110
|
+
version: 1.1.0
|
97
111
|
type: :runtime
|
98
112
|
prerelease: false
|
99
113
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -101,23 +115,29 @@ dependencies:
|
|
101
115
|
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: 0.23.0
|
104
|
-
- - "
|
118
|
+
- - "<"
|
105
119
|
- !ruby/object:Gem::Version
|
106
|
-
version:
|
120
|
+
version: 1.1.0
|
107
121
|
- !ruby/object:Gem::Dependency
|
108
122
|
name: thor
|
109
123
|
requirement: !ruby/object:Gem::Requirement
|
110
124
|
requirements:
|
111
|
-
- - "
|
125
|
+
- - ">="
|
112
126
|
- !ruby/object:Gem::Version
|
113
|
-
version: 0.20.
|
127
|
+
version: 0.20.3
|
128
|
+
- - "<"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '2.0'
|
114
131
|
type: :runtime
|
115
132
|
prerelease: false
|
116
133
|
version_requirements: !ruby/object:Gem::Requirement
|
117
134
|
requirements:
|
118
|
-
- - "
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: 0.20.3
|
138
|
+
- - "<"
|
119
139
|
- !ruby/object:Gem::Version
|
120
|
-
version:
|
140
|
+
version: '2.0'
|
121
141
|
- !ruby/object:Gem::Dependency
|
122
142
|
name: bundler
|
123
143
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,14 +158,14 @@ dependencies:
|
|
138
158
|
requirements:
|
139
159
|
- - "~>"
|
140
160
|
- !ruby/object:Gem::Version
|
141
|
-
version: 0.
|
161
|
+
version: 0.10.0
|
142
162
|
type: :development
|
143
163
|
prerelease: false
|
144
164
|
version_requirements: !ruby/object:Gem::Requirement
|
145
165
|
requirements:
|
146
166
|
- - "~>"
|
147
167
|
- !ruby/object:Gem::Version
|
148
|
-
version: 0.
|
168
|
+
version: 0.10.0
|
149
169
|
- !ruby/object:Gem::Dependency
|
150
170
|
name: rake
|
151
171
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,6 +263,7 @@ extra_rdoc_files:
|
|
243
263
|
- LICENSE
|
244
264
|
- README.md
|
245
265
|
files:
|
266
|
+
- ".github/CODEOWNERS"
|
246
267
|
- CHANGELOG.md
|
247
268
|
- CONTRIBUTING.md
|
248
269
|
- LICENSE
|
@@ -268,6 +289,7 @@ files:
|
|
268
289
|
- lib/pronto/formatter/commit_formatter.rb
|
269
290
|
- lib/pronto/formatter/formatter.rb
|
270
291
|
- lib/pronto/formatter/git_formatter.rb
|
292
|
+
- lib/pronto/formatter/github_combined_status_formatter.rb
|
271
293
|
- lib/pronto/formatter/github_formatter.rb
|
272
294
|
- lib/pronto/formatter/github_pull_request_formatter.rb
|
273
295
|
- lib/pronto/formatter/github_pull_request_review_formatter.rb
|
@@ -275,6 +297,7 @@ files:
|
|
275
297
|
- lib/pronto/formatter/github_status_formatter/sentence.rb
|
276
298
|
- lib/pronto/formatter/github_status_formatter/status_builder.rb
|
277
299
|
- lib/pronto/formatter/gitlab_formatter.rb
|
300
|
+
- lib/pronto/formatter/gitlab_merge_request_review_formatter.rb
|
278
301
|
- lib/pronto/formatter/json_formatter.rb
|
279
302
|
- lib/pronto/formatter/null_formatter.rb
|
280
303
|
- lib/pronto/formatter/pull_request_formatter.rb
|
@@ -316,7 +339,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
316
339
|
- !ruby/object:Gem::Version
|
317
340
|
version: '0'
|
318
341
|
requirements: []
|
319
|
-
rubygems_version: 3.0.
|
342
|
+
rubygems_version: 3.0.3
|
320
343
|
signing_key:
|
321
344
|
specification_version: 4
|
322
345
|
summary: Pronto runs analysis by checking only the introduced changes
|