danger-gitlab_reviewbot 1.1.4 → 1.1.9

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: f2886d84d0e6fb6e296379feeb66e4e183d5aa8bd8598a3f4e2713aa5b4b5927
4
- data.tar.gz: 0b1aa53383e71c481256c8893064ca54cda389c8dad6f2dcad014d48117c8edb
3
+ metadata.gz: 67b82907ad367877d16780bff37695983a3235649eb5751564f80af6b3741eac
4
+ data.tar.gz: b35596f4f8d498cfdbb5dc873a99418782558ace2680980900735ede0f7f1825
5
5
  SHA512:
6
- metadata.gz: 5a4d8a9e9da4ce0883efae5cd949d18497b0e571b916443c4276a884b1fe6be2fe35a143c803665bb0d6f810a16b1687032fde49585a92066d381811ed52507a
7
- data.tar.gz: '03528aa2084af65294610316cdff1a584c6507ccd88ed407270d87ed27029d6734e73a0ef06f4c9af5b60ce2bd68292debc456187c48107b015760b5f8a1393f'
6
+ metadata.gz: 0c9ca5a7f734c3c0a86c08d80309a58049b538bf546aaa6d47f74ac18fe248593383e7977c70d8aa1cc7b4501b6610e129d7e8c7d941de03746ede64739699fc
7
+ data.tar.gz: 4e0234da0471bba9284fbc70d618fc96b0f931e7eba63d3f0e555e08918d6dd06ec23f09fa8cd0639fd75d664d6b691163dcb67810f414e4dd471720820cd9a2
data/.gitlab-ci.yml CHANGED
@@ -4,16 +4,31 @@ cache:
4
4
  paths:
5
5
  - vendor/bundle/
6
6
 
7
+ stages:
8
+ - test
9
+ - deploy
10
+
7
11
  test:
8
12
  stage: test
9
13
  script:
10
14
  - gem install bundler
11
15
  - bundle --path vendor/bundle
12
16
  - bundle exec rake spec
13
- - bundle exec rake build
14
17
  artifacts:
15
18
  paths:
16
19
  - rspec.xml
17
20
  reports:
18
21
  junit: rspec.xml
19
22
 
23
+ deploy:
24
+ stage: deploy
25
+ only:
26
+ - tags
27
+ before_script:
28
+ - 'mkdir ~/.gem && echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials && chmod 0600 ~/.gem/credentials'
29
+ script:
30
+ - gem install bundler
31
+ - bundle --path vendor/bundle
32
+ - bundle exec rake build
33
+ - gem push pkg/danger-gitlab_reviewbot-${CI_COMMIT_TAG}.gem
34
+
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- danger-gitlab_reviewbot (1.1.3)
4
+ danger-gitlab_reviewbot (1.1.7)
5
5
  danger-gitlab
6
6
  danger-plugin-api (~> 1.0)
7
7
 
@@ -21,26 +21,26 @@ GEM
21
21
  colored2 (3.1.2)
22
22
  cork (0.3.0)
23
23
  colored2 (~> 3.1)
24
- danger (6.3.2)
24
+ danger (8.0.1)
25
25
  claide (~> 1.0)
26
26
  claide-plugins (>= 0.9.2)
27
27
  colored2 (~> 3.1)
28
28
  cork (~> 0.1)
29
- faraday (~> 0.9)
29
+ faraday (>= 0.9.0, < 2.0)
30
30
  faraday-http-cache (~> 2.0)
31
- git (~> 1.6)
31
+ git (~> 1.7)
32
32
  kramdown (~> 2.0)
33
33
  kramdown-parser-gfm (~> 1.0)
34
34
  no_proxy_fix
35
35
  octokit (~> 4.7)
36
36
  terminal-table (~> 1)
37
- danger-gitlab (7.0.0)
38
- danger (~> 6.0)
37
+ danger-gitlab (8.0.0)
38
+ danger
39
39
  gitlab (~> 4.2, >= 4.2.0)
40
40
  danger-plugin-api (1.0.0)
41
41
  danger (> 2.0)
42
42
  diff-lcs (1.3)
43
- faraday (0.17.3)
43
+ faraday (1.0.1)
44
44
  multipart-post (>= 1.2, < 3)
45
45
  faraday-http-cache (2.2.0)
46
46
  faraday (>= 0.8)
@@ -48,7 +48,7 @@ GEM
48
48
  formatador (0.2.5)
49
49
  git (1.7.0)
50
50
  rchardet (~> 1.8)
51
- gitlab (4.14.1)
51
+ gitlab (4.15.0)
52
52
  httparty (~> 0.14, >= 0.14.0)
53
53
  terminal-table (~> 1.5, >= 1.5.1)
54
54
  guard (2.16.2)
@@ -65,7 +65,7 @@ GEM
65
65
  guard (~> 2.1)
66
66
  guard-compat (~> 1.1)
67
67
  rspec (>= 2.99.0, < 4.0)
68
- httparty (0.18.0)
68
+ httparty (0.18.1)
69
69
  mime-types (~> 3.0)
70
70
  multi_xml (>= 0.5.2)
71
71
  kramdown (2.2.1)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GitlabReviewbot
4
- VERSION = "1.1.4"
4
+ VERSION = "1.1.9"
5
5
  end
@@ -19,12 +19,33 @@ module Gitlab
19
19
  end
20
20
  end
21
21
 
22
- class Client < API
22
+ class ClientHelper
23
+ def initialize(client)
24
+ @client = client
25
+ end
26
+
27
+ def users_with_pending_mr_review(project_id)
28
+ outstanding_mrs = fetch_mrs_requiring_review(project_id)
29
+ all_assignees = outstanding_mrs.reduce([]) { |acc, mr| acc + mr.assignees - assignees_with_review(project_id, mr.id, mr.assignees)}
30
+ assignees_id_map = all_assignees.each_with_object({}) do |a, acc|
31
+ aid = a["id"]
32
+ ausername = a["username"]
33
+ assignee = acc[aid] || User.new(aid, ausername)
34
+ assignee.review_count += 1
35
+ acc[aid] = assignee
36
+ end
37
+ assignees_id_map.values
38
+ end
39
+
40
+ def fetch_mrs_requiring_review(project_id)
41
+ @client.merge_requests(project_id, state: "opened", per_page: "100")
42
+ end
43
+
23
44
  def fetch_users_for_group(group_name)
24
- group_id = search_group(group_name)
45
+ group_id = search_group_with_path(group_name)
25
46
  return nil if group_id.nil?
26
47
 
27
- res = group_members(group_id)
48
+ res = @client.group_members(group_id, :per_page => 100)
28
49
 
29
50
  developer_access_level = 30
30
51
  res.select { |u| u.state == "active" && u.access_level >= developer_access_level }.map { |u| User.new(u.id, u.username) }
@@ -32,44 +53,28 @@ module Gitlab
32
53
 
33
54
  def assign_mr_to_users(project_id, mr_iid, users)
34
55
  user_ids = users.map(&:id)
35
- update_merge_request(project_id, mr_iid, "assignee_ids" => user_ids)
56
+ @client.update_merge_request(project_id, mr_iid, "assignee_ids" => user_ids)
57
+
36
58
  end
37
59
 
38
60
  def fetch_author_for_mr(project_id, mr_iid)
39
- res = merge_request(project_id, mr_iid)
61
+ res = @client.merge_request(project_id, mr_iid)
40
62
  User.new(res.author.id, res.author.name)
41
63
  end
42
64
 
43
- def fetch_mrs_requiring_review(project_id)
44
- merge_requests(project_id, state: "opened", per_page: "100").reject { |mr| mr.merge_status == "can_be_merged" }
45
- end
46
-
47
65
  def find_user_with_username(username)
48
- users({ username: username }).map { |u| User.new(u.id, u.username) }
49
- end
50
-
51
- def users_with_pending_mr_review(project_id)
52
- outstanding_mrs = fetch_mrs_requiring_review(project_id)
53
- all_assignees = outstanding_mrs.reduce([]) { |acc, mr| acc + mr.assignees }
54
- assignees_id_map = all_assignees.each_with_object({}) do |a, acc|
55
- aid = a["id"]
56
- ausername = a["username"]
57
- assignee = acc[aid] || User.new(aid, ausername)
58
- assignee.review_count += 1
59
- acc[aid] = assignee
60
- end
61
- assignees_id_map.values
66
+ @client.users({ username: username }).map { |u| User.new(u.id, u.username) }
62
67
  end
63
68
 
64
69
  def fetch_mr_reviewers(project_id, mr_iid)
65
- merge_request(project_id, mr_iid).assignees.map { |u| User.new(u["id"], u["username"]) }
70
+ @client.merge_request(project_id, mr_iid).assignees.map { |u| User.new(u["id"], u["username"]) }
66
71
  end
67
72
 
68
73
  private
69
74
 
70
- def search_group(group_name)
75
+ def search_group_with_path(group_name)
71
76
  short_name = group_name.split("/").last
72
- res = group_search(short_name)
77
+ res = @client.group_search(short_name)
73
78
  res = res.find { |i| i.full_path == group_name }
74
79
 
75
80
  if res.nil?
@@ -78,5 +83,28 @@ module Gitlab
78
83
  res.id
79
84
  end
80
85
  end
86
+
87
+ def assignees_with_review(project_id, mr_iid, gusers)
88
+ approvals = @client.merge_request_approval_state(project_id, mr_iid)
89
+ approved_by = approvals.rules.reduce([]) { |acc, r| acc + r['approved_by'] }
90
+ gusers.filter { |u| approved_by.index { |au| au['id'] == u['id'] } != nil }
91
+ end
92
+
93
+ end
94
+
95
+ class Client < API
96
+
97
+ def client_helper
98
+ @client_helper ||= ClientHelper.new(self)
99
+ end
100
+
101
+ def method_missing(method, *args)
102
+ if client_helper.respond_to?(method)
103
+ client_helper.send(method, *args)
104
+ else
105
+ super
106
+ end
107
+ end
108
+
81
109
  end
82
110
  end
@@ -13,9 +13,8 @@ module Danger
13
13
  group_users_with_reviews_pending = client.users_with_pending_mr_review(project_id).filter { |u| users_in_group.include? u }
14
14
  group_users_without_reviews_pending = users_in_group.filter { |u| !group_users_with_reviews_pending.include? u }
15
15
 
16
- (group_users_with_reviews_pending + group_users_without_reviews_pending).filter { |u| !invalid_assignees.include? u }
17
- .sort_by(&:review_count)
18
- .first(amount)
16
+ candidates = (group_users_with_reviews_pending + group_users_without_reviews_pending).filter { |u| !invalid_assignees.include? u }
17
+ candidates.shuffle.sort_by(&:review_count).first(amount)
19
18
  end
20
19
  end
21
20
  end
@@ -27,7 +27,7 @@ module Danger
27
27
  all_assignees.map(&:username)
28
28
  end
29
29
 
30
- def assignees(_amount)
30
+ def assignees(amount)
31
31
  raise "To be implemented in the subclasses"
32
32
  end
33
33
 
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
4
+
5
+
6
+ module Danger
7
+ describe Gitlab::Client do
8
+ before do
9
+ #
10
+ # @sam = Gitlab::User.new(1, "Sam")
11
+ # @tom = Gitlab::User.new(2, "Tom")
12
+ # @nic = Gitlab::User.new(3, "Nic")
13
+ # @luke = Gitlab::User.new(4, "Luke")
14
+ @mock_client = double(Gitlab::Client)
15
+ @client_helper = Gitlab::ClientHelper.new(@mock_client)
16
+ @sam = Gitlab::User.new(1, "Sam")
17
+ @tom = Gitlab::User.new(2, "Tom")
18
+ @nic = Gitlab::User.new(3, "Nic")
19
+ @assignees = [{'id' => 1, 'username' => "Sam"},
20
+ {'id' => 2, 'username' => "Tom"},
21
+ {'id' => 3, 'username' => "Nic"}]
22
+ end
23
+
24
+ it "Correctly calculates users with pending reviews" do
25
+ already_reviewed = [@assignees[0]]
26
+
27
+ allow(@mock_client).to receive(:merge_requests).with(10, {:per_page=>"100", :state=>"opened"}).and_return([Gitlab::ObjectifiedHash.new({'id' => 110, 'assignees' => @assignees})])
28
+ allow(@mock_client).to receive(:merge_request_approval_state).with(10, 110).and_return(Gitlab::ObjectifiedHash.new({'rules' => [{'approved_by' => already_reviewed}]}))
29
+
30
+ expect(@client_helper.users_with_pending_mr_review(10)).to be == [@tom, @nic]
31
+ end
32
+
33
+ it "Correctly calculates users with pending reviews (multi rule)" do
34
+ allow(@mock_client).to receive(:merge_requests).with(10, {:per_page=>"100", :state=>"opened"}).and_return([Gitlab::ObjectifiedHash.new({'id' => 110, 'assignees' => @assignees})])
35
+ allow(@mock_client).to receive(:merge_request_approval_state).with(10, 110).and_return(Gitlab::ObjectifiedHash.new({'rules' => [{'approved_by' => [{'id' => 1, 'username' => "Sam"}]}, {'approved_by' => [{'id' => 2, 'username' => "Tom"}]}]}))
36
+
37
+ expect(@client_helper.users_with_pending_mr_review(10)).to be == [@nic]
38
+ end
39
+
40
+ it "Fetches only active developer users for group" do
41
+ active_users = [Gitlab::ObjectifiedHash.new({'id' => 1, 'username' => 'Sam', 'state' => 'active', 'access_level' => 30}),
42
+ Gitlab::ObjectifiedHash.new({'id' => 2, 'username' => 'Tom', 'state' => 'active', 'access_level' => 50})]
43
+ inactive_users = [Gitlab::ObjectifiedHash.new({'id' => 3, 'username' => 'OldSam', 'state' => 'inactive', 'access_level' => 30})]
44
+ non_developer_users = [Gitlab::ObjectifiedHash.new({'id' => 4, 'username' => 'Reporter', 'state' => 'active', 'access_level' => 20})]
45
+ allow(@mock_client).to receive(:group_search).with("mygroup").and_return([Gitlab::ObjectifiedHash.new({'id' => 10, 'full_path' => "mygroup"})])
46
+ allow(@mock_client).to receive(:group_members).with(10).and_return(active_users + inactive_users + non_developer_users)
47
+ expect(@client_helper.fetch_users_for_group("mygroup")).to be == [@sam, @tom]
48
+ end
49
+ end
50
+ end
51
+
data/spec/spec_helper.rb CHANGED
@@ -10,6 +10,7 @@ require "pry"
10
10
 
11
11
  require "rspec"
12
12
  require "danger"
13
+ require File.expand_path("../lib/gitlab_reviewbot/gitlab", __dir__)
13
14
 
14
15
  if `git remote -v` == ""
15
16
  puts "You cannot run tests without setting a local git remote on this repo"
@@ -59,7 +60,7 @@ def testing_env
59
60
  "CI_API_V4_URL" => "https://git.curve.tools/api/v4",
60
61
  "CI_PROJECT_ID" => "346",
61
62
  "GITLAB_CI" => true,
62
- "DANGER_GITLAB_API_TOKEN" => "jgUhHSk2vGNYYFr3QsPq"
63
+ "DANGER_GITLAB_API_TOKEN" => "token-token-token"
63
64
  }
64
65
  end
65
66
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danger-gitlab_reviewbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Gallonetto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-15 00:00:00.000000000 Z
11
+ date: 2021-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: danger-plugin-api
@@ -218,6 +218,7 @@ files:
218
218
  - lib/gitlab_reviewbot/strategies/least_busy.rb
219
219
  - lib/gitlab_reviewbot/strategies/random.rb
220
220
  - lib/gitlab_reviewbot/strategies/strategy.rb
221
+ - spec/gitlab_ext_spec.rb
221
222
  - spec/gitlab_reviewbot_spec.rb
222
223
  - spec/least_busy_strategy_spec.rb
223
224
  - spec/random_strategy_spec.rb
@@ -246,6 +247,7 @@ signing_key:
246
247
  specification_version: 4
247
248
  summary: A review raffle bot for Gitlab.
248
249
  test_files:
250
+ - spec/gitlab_ext_spec.rb
249
251
  - spec/gitlab_reviewbot_spec.rb
250
252
  - spec/least_busy_strategy_spec.rb
251
253
  - spec/random_strategy_spec.rb