reviewlette 0.0.9 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 163d81e853831b82b114bf4705a4b89621e308dc
4
- data.tar.gz: 75186e2b3813ee25c38b8ebdf60df1c9a5205171
3
+ metadata.gz: fc2e0db8f1f84d6d27f7057eecdb21a24aab3f7e
4
+ data.tar.gz: b7e681c5a4954a09144b509b5434a649b9c378a4
5
5
  SHA512:
6
- metadata.gz: 4daa9c0f5d7e62f4dc08604b66a6b8888b3ae5d6ca4486ac29d67cff05bec0ea9d5e7659e682b3107562e7021ac665e0d25e4955d067d4729e64c3d8a1d572ed
7
- data.tar.gz: 56f797d47df14a587b4b3bbfe99ad5290e345565c47548adb33f5d11641cc6fefdcd62f413798ad974d07bea0a3340f44a293a5684e44cea224b8c5d21e5e7f4
6
+ metadata.gz: 21647bb1f08a246343b1c3cb8920a668f87cbe2c461affaeceec60bb57f3d2c0f1c39357c4bcf77ae0419ff150a46ff8f6db9f21842c175cd5a3731f04af12ed
7
+ data.tar.gz: f4e2ac2ca8900f6a195d284d32e6e001751ee79528f8d0bbfdf899334f8e54e5bde6d96388892cc741cd2e928cfc8af743c512e1d1091eeb139cc59530a38791
@@ -0,0 +1 @@
1
+ /config/
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.0.0"
3
+ - "2.3.1"
4
4
  # uncomment this line if your project needs to run something other than `rake`:
5
- # script: bundle exec rspec spec
5
+ # script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -1,24 +1,21 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'json'
4
- gem 'haml'
5
- gem 'octokit', '~> 3.8.0'
6
- gem 'ruby-trello'
7
- gem 'rdoc'
8
- gem 'rspec'
9
- gem 'webmock'
10
- gem 'rake'
11
- gem 'ap'
12
- gem 'byebug'
13
- gem 'simplecov'
14
- gem 'prophet'
15
- gem 'coveralls'
16
- gem 'sequel'
17
- gem 'sqlite3'
3
+ gemspec
18
4
 
5
+ group :development, :test do
6
+ gem 'ap'
7
+ gem 'rake'
8
+ gem 'debugger-linecache'
9
+ gem 'byebug'
10
+ end
19
11
 
20
- group :development do
12
+ group :test do
13
+ gem 'rspec'
14
+ gem 'webmock'
21
15
  gem 'guard'
22
16
  gem 'guard-rspec'
23
17
  gem 'libnotify'
18
+ gem 'simplecov'
19
+ gem 'coveralls'
20
+ gem 'rdoc'
24
21
  end
@@ -1,42 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ reviewlette (1.0.0)
5
+ octokit
6
+ ruby-trello
7
+
1
8
  GEM
2
9
  remote: http://rubygems.org/
3
10
  specs:
4
- activemodel (4.1.1)
5
- activesupport (= 4.1.1)
6
- builder (~> 3.1)
7
- activesupport (4.1.1)
8
- i18n (~> 0.6, >= 0.6.9)
9
- json (~> 1.7, >= 1.7.7)
11
+ activemodel (5.0.0.1)
12
+ activesupport (= 5.0.0.1)
13
+ activesupport (5.0.0.1)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (~> 0.7)
10
16
  minitest (~> 5.1)
11
- thread_safe (~> 0.1)
12
17
  tzinfo (~> 1.1)
13
- addressable (2.3.8)
18
+ addressable (2.5.0)
19
+ public_suffix (~> 2.0, >= 2.0.2)
14
20
  ap (0.1.1)
15
21
  httparty (>= 0.7.7)
16
- builder (3.2.2)
17
- byebug (3.1.2)
18
- columnize (~> 0.8)
19
- celluloid (0.16.0)
20
- timers (~> 4.0.0)
21
- coderay (1.1.0)
22
- columnize (0.8.9)
23
- coveralls (0.7.0)
24
- multi_json (~> 1.3)
25
- rest-client
26
- simplecov (>= 0.7)
27
- term-ansicolor
28
- thor
29
- crack (0.4.2)
22
+ byebug (9.0.6)
23
+ coderay (1.1.1)
24
+ concurrent-ruby (1.0.2)
25
+ coveralls (0.8.17)
26
+ json (>= 1.8, < 3)
27
+ simplecov (~> 0.12.0)
28
+ term-ansicolor (~> 1.3)
29
+ thor (~> 0.19.1)
30
+ tins (~> 1.6)
31
+ crack (0.4.3)
30
32
  safe_yaml (~> 1.0.0)
33
+ debugger-linecache (1.2.0)
31
34
  diff-lcs (1.2.5)
32
- docile (1.1.3)
33
- faraday (0.9.1)
35
+ docile (1.1.5)
36
+ domain_name (0.5.20161129)
37
+ unf (>= 0.0.5, < 1.0.0)
38
+ faraday (0.10.0)
34
39
  multipart-post (>= 1.2, < 3)
35
- ffi (1.9.8)
40
+ ffi (1.9.14)
36
41
  formatador (0.2.5)
37
- guard (2.12.6)
42
+ guard (2.14.0)
38
43
  formatador (>= 0.2.4)
39
- listen (~> 2.7)
44
+ listen (>= 2.7, < 4.0)
40
45
  lumberjack (~> 1.0)
41
46
  nenv (~> 0.1)
42
47
  notiffany (~> 0.0)
@@ -44,97 +49,96 @@ GEM
44
49
  shellany (~> 0.0)
45
50
  thor (>= 0.18.1)
46
51
  guard-compat (1.2.1)
47
- guard-rspec (4.5.2)
52
+ guard-rspec (4.7.3)
48
53
  guard (~> 2.1)
49
54
  guard-compat (~> 1.1)
50
55
  rspec (>= 2.99.0, < 4.0)
51
- haml (4.0.5)
52
- tilt
53
- hitimes (1.2.2)
54
- httparty (0.13.1)
55
- json (~> 1.8)
56
+ hashdiff (0.3.1)
57
+ http-cookie (1.0.3)
58
+ domain_name (~> 0.5)
59
+ httparty (0.14.0)
56
60
  multi_xml (>= 0.5.2)
57
- i18n (0.6.9)
58
- json (1.8.1)
61
+ i18n (0.7.0)
62
+ json (2.0.2)
59
63
  libnotify (0.9.1)
60
64
  ffi (>= 1.0.11)
61
- listen (2.10.1)
62
- celluloid (~> 0.16.0)
63
- rb-fsevent (>= 0.9.3)
64
- rb-inotify (>= 0.9)
65
- lumberjack (1.0.9)
65
+ listen (3.1.5)
66
+ rb-fsevent (~> 0.9, >= 0.9.4)
67
+ rb-inotify (~> 0.9, >= 0.9.7)
68
+ ruby_dep (~> 1.2)
69
+ lumberjack (1.0.10)
66
70
  method_source (0.8.2)
67
- mime-types (2.3)
68
- minitest (5.3.4)
69
- multi_json (1.10.0)
70
- multi_xml (0.5.5)
71
+ mime-types (2.99.3)
72
+ minitest (5.10.1)
73
+ multi_xml (0.6.0)
71
74
  multipart-post (2.0.0)
72
- nenv (0.2.0)
73
- notiffany (0.0.6)
75
+ nenv (0.3.0)
76
+ netrc (0.11.0)
77
+ notiffany (0.1.1)
74
78
  nenv (~> 0.1)
75
79
  shellany (~> 0.0)
76
- oauth (0.4.7)
77
- octokit (3.8.0)
78
- sawyer (~> 0.6.0, >= 0.5.3)
79
- prophet (1.5.5)
80
- octokit
81
- rspec
82
- pry (0.10.1)
80
+ oauth (0.5.1)
81
+ octokit (4.6.2)
82
+ sawyer (~> 0.8.0, >= 0.5.3)
83
+ pry (0.10.4)
83
84
  coderay (~> 1.1.0)
84
85
  method_source (~> 0.8.1)
85
86
  slop (~> 3.4)
86
- rake (10.3.2)
87
- rb-fsevent (0.9.5)
88
- rb-inotify (0.9.5)
87
+ public_suffix (2.0.4)
88
+ rake (12.0.0)
89
+ rb-fsevent (0.9.8)
90
+ rb-inotify (0.9.7)
89
91
  ffi (>= 0.5.0)
90
- rdoc (4.1.1)
91
- json (~> 1.4)
92
- rest-client (1.6.7)
93
- mime-types (>= 1.16)
94
- rspec (3.0.0)
95
- rspec-core (~> 3.0.0)
96
- rspec-expectations (~> 3.0.0)
97
- rspec-mocks (~> 3.0.0)
98
- rspec-core (3.0.0)
99
- rspec-support (~> 3.0.0)
100
- rspec-expectations (3.0.0)
92
+ rdoc (5.0.0)
93
+ rest-client (1.8.0)
94
+ http-cookie (>= 1.0.2, < 2.0)
95
+ mime-types (>= 1.16, < 3.0)
96
+ netrc (~> 0.7)
97
+ rspec (3.5.0)
98
+ rspec-core (~> 3.5.0)
99
+ rspec-expectations (~> 3.5.0)
100
+ rspec-mocks (~> 3.5.0)
101
+ rspec-core (3.5.4)
102
+ rspec-support (~> 3.5.0)
103
+ rspec-expectations (3.5.0)
104
+ diff-lcs (>= 1.2.0, < 2.0)
105
+ rspec-support (~> 3.5.0)
106
+ rspec-mocks (3.5.0)
101
107
  diff-lcs (>= 1.2.0, < 2.0)
102
- rspec-support (~> 3.0.0)
103
- rspec-mocks (3.0.0)
104
- rspec-support (~> 3.0.0)
105
- rspec-support (3.0.0)
106
- ruby-trello (1.1.1)
108
+ rspec-support (~> 3.5.0)
109
+ rspec-support (3.5.0)
110
+ ruby-trello (1.5.1)
107
111
  activemodel (>= 3.2.0)
108
112
  addressable (~> 2.3)
109
113
  json
110
- oauth (~> 0.4.5)
111
- rest-client (~> 1.6.7)
112
- safe_yaml (1.0.3)
113
- sawyer (0.6.0)
114
- addressable (~> 2.3.5)
115
- faraday (~> 0.8, < 0.10)
116
- sequel (4.13.0)
114
+ oauth (>= 0.4.5)
115
+ rest-client (~> 1.8.0)
116
+ ruby_dep (1.5.0)
117
+ safe_yaml (1.0.4)
118
+ sawyer (0.8.1)
119
+ addressable (>= 2.3.5, < 2.6)
120
+ faraday (~> 0.8, < 1.0)
117
121
  shellany (0.0.1)
118
- simplecov (0.8.2)
122
+ simplecov (0.12.0)
119
123
  docile (~> 1.1.0)
120
- multi_json
121
- simplecov-html (~> 0.8.0)
122
- simplecov-html (0.8.0)
124
+ json (>= 1.8, < 3)
125
+ simplecov-html (~> 0.10.0)
126
+ simplecov-html (0.10.0)
123
127
  slop (3.6.0)
124
- sqlite3 (1.3.9)
125
- term-ansicolor (1.3.0)
128
+ term-ansicolor (1.4.0)
126
129
  tins (~> 1.0)
127
- thor (0.19.1)
128
- thread_safe (0.3.4)
129
- tilt (2.0.1)
130
- timers (4.0.1)
131
- hitimes
132
- tins (1.1.0)
133
- tzinfo (1.2.1)
130
+ thor (0.19.4)
131
+ thread_safe (0.3.5)
132
+ tins (1.13.0)
133
+ tzinfo (1.2.2)
134
134
  thread_safe (~> 0.1)
135
- webmock (1.18.0)
135
+ unf (0.1.4)
136
+ unf_ext
137
+ unf_ext (0.0.7.2)
138
+ webmock (2.3.1)
136
139
  addressable (>= 2.3.6)
137
140
  crack (>= 0.3.2)
141
+ hashdiff
138
142
 
139
143
  PLATFORMS
140
144
  ruby
@@ -143,21 +147,16 @@ DEPENDENCIES
143
147
  ap
144
148
  byebug
145
149
  coveralls
150
+ debugger-linecache
146
151
  guard
147
152
  guard-rspec
148
- haml
149
- json
150
153
  libnotify
151
- octokit (~> 3.8.0)
152
- prophet
153
154
  rake
154
155
  rdoc
156
+ reviewlette!
155
157
  rspec
156
- ruby-trello
157
- sequel
158
158
  simplecov
159
- sqlite3
160
159
  webmock
161
160
 
162
161
  BUNDLED WITH
163
- 1.10.6
162
+ 1.13.6
data/README.md CHANGED
@@ -1,43 +1,43 @@
1
- Reviewlette
2
- ===========
3
-
4
- [![Coverage Status](https://img.shields.io/coveralls/jschmid1/reviewlette.svg)](https://coveralls.io/r/jschmid1/reviewlette)
5
- [![Code Climate](https://codeclimate.com/github/jschmid1/reviewlette.png)](https://codeclimate.com/github/jschmid1/reviewlette)
6
-
7
- Tool to automatically assign a "Reviewer" to a GitHub Issue and to the attached Trello Card.
1
+ [![Code Climate](https://codeclimate.com/github/SUSE/reviewlette.png)](https://codeclimate.com/github/SUSE/reviewlette)
2
+ [![Build Status](https://secure.travis-ci.org/SUSE/reviewlette.png?branch=master)](https://travis-ci.org/SUSE/reviewlette)
8
3
 
4
+ # Reviewlette
5
+ Tool to automatically assign reviewers to GitHub pull requests and to move and comment on their Trello cards.
9
6
 
10
7
  What it does:
11
8
 
12
- - Finds unassigned issues on GitHub.
13
- - Assigns a member of your team.
14
- - Locates the right Card on Trello.
15
- - Checks if the assignee is on vacation(using tel).
16
- - Adds the assigned member to the Card.
17
- - Move the card to 'In review'
18
-
9
+ - Finds pull requests with missing reviewers in your GitHub repos.
10
+ - Assigns random members of your team.
11
+ - Locates the right card in your Trello board.
12
+ - Mentions the assigned reviewer in a comment on the card.
13
+ - Moves the card to the 'In review' column.
19
14
 
20
15
  ## Installation
16
+ For the latest and greatest version you should `git clone https://github.com/SUSE/reviewlette`
21
17
 
18
+ ## Usage
19
+ ```ruby
20
+ Reviewlette.new(members: User.all, github_config: {}, trello_config: {}).run
22
21
  ```
23
- gem install reviewlette
24
- reviewlette
25
- ```
26
-
27
22
 
28
- ## Setup
23
+ Users must respond to `trello_handle` and `github_handle` methods.
29
24
 
30
- #### Name your pullrequest like so:
31
- #### Review_#23_name_of_review_42 <= trello card number
25
+ Examples for `github_config` and `trello_config` can be found in `config/`.
32
26
 
33
- Fill `config/.trello.yml` (instructions in the file)
34
- Fill `config/.github.yml` (instructions in the file
27
+ ### Matching Trello cards
28
+ To match a Trello card to a pull request, its title has to end with the card number (not the id)
35
29
 
30
+ #### Example:
36
31
 
37
- ---
32
+ URL of the Trello card: _https://trello.com/c/cardid/4242-fix-everything_
38
33
 
39
- [Using Octokit as a GitHub api wrapper](https://github.com/octokit/octokit.rb)
40
- [Using ruby-trello as a Trello api wrapper](https://github.com/jeremytregunna/ruby-trello)
34
+ Pull request title should be: `Fix almost everything 4242`
41
35
 
36
+ __Note:__ Pull requests without a matching Trello card get skipped and won't be assigned to a reviewer.
42
37
 
38
+ ### Labels
39
+ You can tweak Reviewlette's behavior by adding special labels to your pull request:
43
40
 
41
+ | Label | Description |
42
+ |-------------|----------------------|
43
+ | 2 reviewers | Assign two reviewers |
@@ -1,5 +1,4 @@
1
- # generate the token here: https://github.com/settings/tokens/new
2
-
3
- token:
4
- repos: ["SUSE/connect", "SUSE/happy-customer", "SUSE/reviewlette", "SUSE/scc-docker-images",
5
- "SUSE/scc-provisioning", "SUSE/scc-token", "SUSE/TeamDashboard" ]
1
+ token: # generate the token here: https://github.com/settings/tokens/new
2
+ repos:
3
+ - user/repo1
4
+ - org/repo2
@@ -1,15 +1,12 @@
1
1
  require 'reviewlette/trello_connection'
2
2
  require 'reviewlette/github_connection'
3
- require 'reviewlette/vacations'
4
3
  require 'yaml'
5
4
 
6
- VERSION = '0.0.9'
7
-
8
5
  class Reviewlette
9
- def initialize
10
- @trello = TrelloConnection.new
11
- @members = YAML.load_file("#{File.dirname(__FILE__)}/../config/members.yml")
12
- @github = YAML.load_file("#{File.dirname(__FILE__)}/../config/github.yml")
6
+ def initialize(members:, github_config: nil, trello_config: nil)
7
+ @trello = TrelloConnection.new(trello_config)
8
+ @github = github_config || YAML.load_file("#{File.dirname(__FILE__)}/../config/github.yml")
9
+ @members = members
13
10
  end
14
11
 
15
12
  def run
@@ -27,12 +24,20 @@ class Reviewlette
27
24
  return
28
25
  end
29
26
 
30
- repo.unassigned_pull_requests.each do |issue|
31
- issue_id = issue[:number]
27
+ repo.pull_requests.each do |issue|
28
+ issue_id = issue[:number]
32
29
  issue_title = issue[:title]
30
+ issue_labels = repo.labels(issue_id)
31
+
32
+ puts "*** Checking GitHub pull request: #{issue_title}"
33
+ matched = issue_title.match(/\d+[_'"]?$/)
34
+
35
+ unless matched
36
+ puts 'Pull request not assigned to a trello card'
37
+ next
38
+ end
33
39
 
34
- puts "*** Checking unassigned github pull request: #{issue_title}"
35
- card_id = issue_title.split(/[_ -#\.]/).last.to_i
40
+ card_id = matched[0].to_i
36
41
  card = @trello.find_card_by_id(card_id)
37
42
 
38
43
  unless card
@@ -41,35 +46,38 @@ class Reviewlette
41
46
  end
42
47
 
43
48
  puts "Found matching trello card: #{card.name}"
44
- reviewer = select_reviewer(issue, card)
45
49
 
46
- unless reviewer
47
- puts "Could not find a reviewer for card: #{card.name}"
48
- next
50
+ assignees = issue[:assignees].map(&:login)
51
+ already_assigned_members = @members.select { |m| assignees.include? m.github_handle }
52
+ wanted_number = how_many_should_review(issue_labels)
53
+
54
+ if assignees.size < wanted_number
55
+ reviewers = select_reviewers(card, wanted_number, already_assigned_members)
56
+ if reviewers.empty?
57
+ puts "Could not find a reviewer for card: #{card.name}"
58
+ next
59
+ end
60
+ repo.add_assignees(issue_id, reviewers.map { |r| r.github_handle } )
61
+ repo.comment_reviewers(issue_id, reviewers, card)
62
+ @trello.comment_reviewers(card, repo_name, issue_id, reviewers)
63
+ @trello.move_card_to_list(card, 'In review')
64
+ already_assigned_members
49
65
  end
50
66
 
51
- repo.add_assignee(issue_id, reviewer['github_username'])
52
- repo.reviewer_comment(issue_id, reviewer['github_username'], card)
53
- comment = "@#{reviewer['trello_username']} will review https://github.com/#{repo_name}/issues/#{issue_id}"
54
67
 
55
- @trello.comment_on_card(comment, card)
56
- @trello.move_card_to_list(card, 'In review')
57
68
  end
58
69
  end
59
70
 
60
- def select_reviewer(issue, card)
61
- reviewers = @members['members']
62
-
63
- # remove people on vacation
64
- members_on_vacation = Vacations.members_on_vacation(reviewers)
71
+ def select_reviewers(card, number = 1, already_assigned = [])
72
+ reviewers = @members
73
+ reviewers.reject! { |r| card.members.map(&:username).include? r.trello_handle }
74
+ reviewers -= already_assigned
65
75
 
66
- reviewers = reviewers.reject {|r| members_on_vacation.include? r['suse_username'] }
67
-
68
- # remove trello card owner
69
- reviewers = reviewers.reject {|r| card.members.map(&:username).include? r['trello_username'] }
70
- reviewer = reviewers.sample
71
- puts "Selected reviewer: #{reviewer['name']} from pool #{reviewers.map {|r| r['name'] }}" if reviewer
72
- reviewer
76
+ reviewers.sample(number - already_assigned.size) + already_assigned
73
77
  end
74
78
 
79
+ def how_many_should_review(labels)
80
+ return 2 if labels.include? '2 reviewers'
81
+ 1
82
+ end
75
83
  end