gitlab-triage 1.7.1 → 1.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.gitlab-ci.yml +57 -41
  4. data/.gitlab/merge_request_templates/Release.md +35 -0
  5. data/.rubocop.yml +3 -0
  6. data/Gemfile +1 -1
  7. data/Guardfile +1 -1
  8. data/README.md +105 -8
  9. data/gitlab-triage.gemspec +1 -1
  10. data/lib/gitlab/triage/action/comment.rb +16 -3
  11. data/lib/gitlab/triage/api_query_builders/date_query_param_builder.rb +78 -0
  12. data/lib/gitlab/triage/command_builders/base_command_builder.rb +7 -3
  13. data/lib/gitlab/triage/command_builders/label_command_builder.rb +17 -0
  14. data/lib/gitlab/triage/command_builders/move_command_builder.rb +19 -0
  15. data/lib/gitlab/triage/command_builders/text_content_builder.rb +18 -6
  16. data/lib/gitlab/triage/engine.rb +42 -17
  17. data/lib/gitlab/triage/errors.rb +1 -1
  18. data/lib/gitlab/triage/filters/merge_request_date_conditions_filter.rb +51 -5
  19. data/lib/gitlab/triage/option_parser.rb +10 -0
  20. data/lib/gitlab/triage/options.rb +2 -0
  21. data/lib/gitlab/triage/policies/rule_policy.rb +1 -1
  22. data/lib/gitlab/triage/policies/summary_policy.rb +1 -1
  23. data/lib/gitlab/triage/policies_resources/rule_resources.rb +5 -6
  24. data/lib/gitlab/triage/policies_resources/summary_resources.rb +5 -6
  25. data/lib/gitlab/triage/resource/base.rb +10 -1
  26. data/lib/gitlab/triage/resource/label.rb +15 -0
  27. data/lib/gitlab/triage/resource/merge_request.rb +9 -0
  28. data/lib/gitlab/triage/url_builders/url_builder.rb +10 -9
  29. data/lib/gitlab/triage/validators/limiter_validator.rb +3 -1
  30. data/lib/gitlab/triage/validators/params_validator.rb +5 -3
  31. data/lib/gitlab/triage/version.rb +3 -1
  32. data/support/.gitlab-ci.example.yml +2 -2
  33. data/support/.triage-policies.example.yml +2 -2
  34. metadata +6 -5
  35. data/lib/gitlab/triage/filters/forbidden_labels_conditions_filter.rb +0 -32
  36. data/lib/gitlab/triage/filters/issuable_date_conditions_filter.rb +0 -65
@@ -23,6 +23,10 @@ module Gitlab
23
23
  options.policies_files << value
24
24
  end
25
25
 
26
+ opts.on('--all-projects', 'Process all projects the token has access to') do |value|
27
+ options.all = value
28
+ end
29
+
26
30
  opts.on('-s', '--source [type]', [:projects, :groups], 'The source type between [ projects or groups ], default value: projects') do |value|
27
31
  options.source = value
28
32
  end
@@ -59,6 +63,12 @@ module Gitlab
59
63
  exit # rubocop:disable Rails/Exit
60
64
  end
61
65
 
66
+ opts.on('-v', '--version', 'Print version') do
67
+ require_relative 'version'
68
+ $stdout.puts Gitlab::Triage::VERSION
69
+ exit # rubocop:disable Rails/Exit
70
+ end
71
+
62
72
  opts.on('--init', 'Initialize the project with a policy file') do
63
73
  example_path =
64
74
  File.expand_path('../../../support/.triage-policies.example.yml', __dir__)
@@ -3,6 +3,7 @@ module Gitlab
3
3
  Options = Struct.new(
4
4
  :dry_run,
5
5
  :policies_files,
6
+ :all,
6
7
  :source,
7
8
  :source_id,
8
9
  :token,
@@ -17,6 +18,7 @@ module Gitlab
17
18
  # Defaults
18
19
  self.host_url ||= 'https://gitlab.com'
19
20
  self.api_version ||= 'v4'
21
+ self.all ||= false
20
22
  self.source ||= 'projects'
21
23
  self.require_files ||= []
22
24
  self.policies_files ||= Set.new
@@ -15,7 +15,7 @@ module Gitlab
15
15
  type: type,
16
16
  policy_spec: policy_spec,
17
17
  action: action,
18
- resources: resources.resources,
18
+ resources: resources,
19
19
  network: network)
20
20
  end
21
21
  end
@@ -10,7 +10,7 @@ module Gitlab
10
10
  # Build an issue from several rules policies
11
11
  def build_issue
12
12
  action = actions[:summarize]
13
- issues = resources.build_issues do |inner_policy_spec, inner_resources|
13
+ issues = resources.map do |inner_policy_spec, inner_resources|
14
14
  Policies::RulePolicy.new(
15
15
  type, inner_policy_spec, inner_resources, network)
16
16
  .build_issue
@@ -1,20 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module Gitlab
4
6
  module Triage
5
7
  module PoliciesResources
6
8
  class RuleResources
7
- attr_reader :resources
9
+ include Enumerable
10
+ extend Forwardable
8
11
 
9
12
  def initialize(new_resources)
10
13
  @resources = new_resources
11
14
  end
12
15
 
13
- def each
14
- resources.each do |resource|
15
- yield(resource)
16
- end
17
- end
16
+ def_delegator :@resources, :each
18
17
  end
19
18
  end
20
19
  end
@@ -1,20 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module Gitlab
4
6
  module Triage
5
7
  module PoliciesResources
6
8
  class SummaryResources
7
- attr_reader :rule_to_resources
9
+ include Enumerable
10
+ extend Forwardable
8
11
 
9
12
  def initialize(new_rule_to_resources)
10
13
  @rule_to_resources = new_rule_to_resources
11
14
  end
12
15
 
13
- def build_issues
14
- rule_to_resources.map do |inner_policy_spec, inner_resources|
15
- yield(inner_policy_spec, inner_resources)
16
- end
17
- end
16
+ def_delegator :@rule_to_resources, :each
18
17
  end
19
18
  end
20
19
  end
@@ -41,6 +41,11 @@ module Gitlab
41
41
 
42
42
  private
43
43
 
44
+ def expand_resource!(params: {})
45
+ resource.merge!(
46
+ network.query_api_cached(resource_url(params: params)).first)
47
+ end
48
+
44
49
  def source_resource
45
50
  @source_resource ||= network.query_api_cached(source_url).first
46
51
  end
@@ -53,11 +58,15 @@ module Gitlab
53
58
  build_url(params: params)
54
59
  end
55
60
 
61
+ def resource_id
62
+ resource[:iid]
63
+ end
64
+
56
65
  def resource_url(params: {}, sub_resource_type: nil)
57
66
  build_url(
58
67
  params: params,
59
68
  options: {
60
- resource_id: resource[:iid],
69
+ resource_id: resource_id,
61
70
  sub_resource_type: sub_resource_type
62
71
  }
63
72
  )
@@ -8,6 +8,8 @@ module Gitlab
8
8
  module Triage
9
9
  module Resource
10
10
  class Label < Base
11
+ LabelDoesntExistError = Class.new(StandardError)
12
+
11
13
  FIELDS = %i[
12
14
  id
13
15
  project_id
@@ -35,6 +37,19 @@ module Gitlab
35
37
  Time.parse(value) if value
36
38
  end
37
39
  end
40
+
41
+ def exist?
42
+ label = network.query_api_cached(resource_url).first
43
+ return false unless label
44
+
45
+ label[:name] == name
46
+ end
47
+
48
+ private
49
+
50
+ def resource_id
51
+ name
52
+ end
38
53
  end
39
54
  end
40
55
  end
@@ -12,6 +12,15 @@ module Gitlab
12
12
  def reference
13
13
  '!'
14
14
  end
15
+
16
+ def first_contribution?
17
+ if resource.key?(:first_contribution)
18
+ resource[:first_contribution]
19
+ else
20
+ expanded = expand_resource!
21
+ expanded[:first_contribution]
22
+ end
23
+ end
15
24
  end
16
25
  end
17
26
  end
@@ -6,6 +6,7 @@ module Gitlab
6
6
  @network_options = options.fetch(:network_options)
7
7
  @host_url = @network_options.host_url
8
8
  @api_version = @network_options.api_version
9
+ @all = options.fetch(:all, false)
9
10
  @source = options.fetch(:source, 'projects')
10
11
  @source_id = options.fetch(:source_id)
11
12
  @resource_type = options.fetch(:resource_type, nil)
@@ -15,11 +16,11 @@ module Gitlab
15
16
  end
16
17
 
17
18
  def build
18
- base_url.tap do |url|
19
- url << "/#{@resource_id}" if @resource_id
20
- url << "/#{@sub_resource_type}" if @sub_resource_type
21
- url << params_string if @params
22
- end
19
+ url = base_url
20
+ url << "/#{CGI.escape(@resource_id.to_s)}" if @resource_id
21
+ url << "/#{@sub_resource_type}" if @sub_resource_type
22
+ url << params_string if @params
23
+ url
23
24
  end
24
25
 
25
26
  private
@@ -29,10 +30,10 @@ module Gitlab
29
30
  end
30
31
 
31
32
  def base_url
32
- "#{host_with_api_url}/#{@source}/#{CGI.escape(@source_id.to_s)}"
33
- .tap do |url|
34
- url << "/#{@resource_type}" if @resource_type
35
- end
33
+ url = host_with_api_url
34
+ url << "/#{@source}/#{CGI.escape(@source_id.to_s)}" unless @all
35
+ url << "/#{@resource_type}" if @resource_type
36
+ url
36
37
  end
37
38
 
38
39
  def params_string
@@ -12,7 +12,9 @@ module Gitlab
12
12
  end
13
13
 
14
14
  def validate_required_parameters(value)
15
- raise ArgumentError, "For the limits field, please specify one of: `#{params_limiter_names.join('`, `')}`" unless value.keys.map(&:to_sym).one? { |key| params_limiter_names.include?(key) }
15
+ return if value.keys.one? { |key| params_limiter_names.include?(key.to_sym) }
16
+
17
+ raise ArgumentError, "For the limits field, please specify one of: `#{params_limiter_names.join('`, `')}`"
16
18
  end
17
19
  end
18
20
  end
@@ -1,6 +1,8 @@
1
1
  module Gitlab
2
2
  module Triage
3
3
  class ParamsValidator
4
+ InvalidParameter = Class.new(ArgumentError)
5
+
4
6
  def initialize(parameter_definitions, value)
5
7
  @parameter_definitions = parameter_definitions
6
8
  @value = value
@@ -16,7 +18,7 @@ module Gitlab
16
18
 
17
19
  def validate_required_parameters(value)
18
20
  @parameter_definitions.each do |param|
19
- raise ArgumentError, "#{param[:name]} is a required parameter" unless value[param[:name]]
21
+ raise InvalidParameter, "#{param[:name]} is a required parameter" unless value[param[:name]]
20
22
  end
21
23
  end
22
24
 
@@ -24,7 +26,7 @@ module Gitlab
24
26
  @parameter_definitions.each do |param|
25
27
  if value.has_key?(param[:name])
26
28
  param_types = Array(param[:type]).flatten
27
- raise ArgumentError, "#{param[:name]} must be of type #{param[:type]}" unless param_types.any? { |type| value[param[:name]].is_a?(type) }
29
+ raise InvalidParameter, "#{param[:name]} must be of type #{param[:type]}" unless param_types.any? { |type| value[param[:name]].is_a?(type) }
28
30
  end
29
31
  end
30
32
  end
@@ -32,7 +34,7 @@ module Gitlab
32
34
  def validate_parameter_content(value)
33
35
  @parameter_definitions.each do |param|
34
36
  if param[:values]
35
- raise ArgumentError, "#{param[:name]} must be of one of #{param[:values].join(',')}" unless param[:values].include?(value[param[:name]])
37
+ raise InvalidParameter, "#{param[:name]} must be of one of #{param[:values].join(',')}" unless param[:values].include?(value[param[:name]])
36
38
  end
37
39
  end
38
40
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Gitlab
2
4
  module Triage
3
- VERSION = '1.7.1'.freeze
5
+ VERSION = '1.11.0'
4
6
  end
5
7
  end
@@ -8,7 +8,7 @@ dry-run:triage:
8
8
  script:
9
9
  - gem install gitlab-triage
10
10
  - gitlab-triage --help
11
- - gitlab-triage --dry-run --token $API_TOKEN --source projects --source-id $CI_PROJECT_PATH
11
+ - gitlab-triage --dry-run --token $GITLAB_API_TOKEN --source projects --source-id $CI_PROJECT_PATH
12
12
  when: manual
13
13
  except:
14
14
  - schedules
@@ -17,6 +17,6 @@ run:triage:
17
17
  stage: triage
18
18
  script:
19
19
  - gem install gitlab-triage
20
- - gitlab-triage --token $API_TOKEN --source projects --source-id $CI_PROJECT_PATH
20
+ - gitlab-triage --token $GITLAB_API_TOKEN --source projects --source-id $CI_PROJECT_PATH
21
21
  only:
22
22
  - schedules
@@ -6,10 +6,10 @@ resource_rules:
6
6
  date:
7
7
  attribute: created_at
8
8
  condition: older_than
9
- interval_type: week
9
+ interval_type: weeks
10
10
  interval: 1
11
11
  labels:
12
- - No label
12
+ - None
13
13
  state: opened
14
14
  actions:
15
15
  comment: |
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-triage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-01 00:00:00.000000000 Z
11
+ date: 2020-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -120,6 +120,7 @@ files:
120
120
  - ".gitignore"
121
121
  - ".gitlab-ci.yml"
122
122
  - ".gitlab/CODEOWNERS"
123
+ - ".gitlab/merge_request_templates/Release.md"
123
124
  - ".rubocop.yml"
124
125
  - CONTRIBUTING.md
125
126
  - Gemfile
@@ -135,12 +136,14 @@ files:
135
136
  - lib/gitlab/triage/action/comment.rb
136
137
  - lib/gitlab/triage/action/summarize.rb
137
138
  - lib/gitlab/triage/api_query_builders/base_query_param_builder.rb
139
+ - lib/gitlab/triage/api_query_builders/date_query_param_builder.rb
138
140
  - lib/gitlab/triage/api_query_builders/multi_query_param_builder.rb
139
141
  - lib/gitlab/triage/api_query_builders/single_query_param_builder.rb
140
142
  - lib/gitlab/triage/command_builders/base_command_builder.rb
141
143
  - lib/gitlab/triage/command_builders/cc_command_builder.rb
142
144
  - lib/gitlab/triage/command_builders/comment_command_builder.rb
143
145
  - lib/gitlab/triage/command_builders/label_command_builder.rb
146
+ - lib/gitlab/triage/command_builders/move_command_builder.rb
144
147
  - lib/gitlab/triage/command_builders/remove_label_command_builder.rb
145
148
  - lib/gitlab/triage/command_builders/status_command_builder.rb
146
149
  - lib/gitlab/triage/command_builders/text_content_builder.rb
@@ -155,8 +158,6 @@ files:
155
158
  - lib/gitlab/triage/filters/assignee_member_conditions_filter.rb
156
159
  - lib/gitlab/triage/filters/author_member_conditions_filter.rb
157
160
  - lib/gitlab/triage/filters/base_conditions_filter.rb
158
- - lib/gitlab/triage/filters/forbidden_labels_conditions_filter.rb
159
- - lib/gitlab/triage/filters/issuable_date_conditions_filter.rb
160
161
  - lib/gitlab/triage/filters/member_conditions_filter.rb
161
162
  - lib/gitlab/triage/filters/merge_request_date_conditions_filter.rb
162
163
  - lib/gitlab/triage/filters/name_conditions_filter.rb
@@ -212,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
213
  - !ruby/object:Gem::Version
213
214
  version: '0'
214
215
  requirements: []
215
- rubygems_version: 3.0.3
216
+ rubygems_version: 3.1.2
216
217
  signing_key:
217
218
  specification_version: 4
218
219
  summary: GitLab triage automation project.
@@ -1,32 +0,0 @@
1
- require_relative 'base_conditions_filter'
2
-
3
- module Gitlab
4
- module Triage
5
- module Filters
6
- class ForbiddenLabelsConditionsFilter < BaseConditionsFilter
7
- def validate_condition(condition)
8
- raise ArgumentError, 'condition must be an array containing forbidden label values' unless condition.is_a?(Array)
9
- end
10
-
11
- def initialize_variables(forbidden_labels)
12
- @attribute = :labels
13
- @forbidden_labels = forbidden_labels
14
- end
15
-
16
- def resource_value
17
- @resource[@attribute]
18
- end
19
-
20
- def calculate
21
- label_intersection.empty?
22
- end
23
-
24
- private
25
-
26
- def label_intersection
27
- resource_value & @forbidden_labels
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,65 +0,0 @@
1
- require_relative 'base_conditions_filter'
2
-
3
- module Gitlab
4
- module Triage
5
- module Filters
6
- class IssuableDateConditionsFilter < BaseConditionsFilter
7
- ATTRIBUTES = %w[updated_at created_at].freeze
8
- CONDITIONS = %w[older_than newer_than].freeze
9
- INTERVAL_TYPES = %w[days weeks months years].freeze
10
-
11
- def self.allowed_attributes
12
- self::ATTRIBUTES
13
- end
14
-
15
- def self.filter_parameters
16
- [
17
- {
18
- name: :attribute,
19
- type: String,
20
- values: allowed_attributes
21
- },
22
- {
23
- name: :condition,
24
- type: String,
25
- values: CONDITIONS
26
- },
27
- {
28
- name: :interval_type,
29
- type: String,
30
- values: INTERVAL_TYPES
31
- },
32
- {
33
- name: :interval,
34
- type: Numeric
35
- }
36
- ]
37
- end
38
-
39
- def initialize_variables(condition)
40
- @attribute = condition[:attribute].to_sym
41
- @condition = condition[:condition].to_sym
42
- @interval_type = condition[:interval_type].to_sym
43
- @interval = condition[:interval]
44
- end
45
-
46
- def resource_value
47
- @resource[@attribute].to_date
48
- end
49
-
50
- def condition_value
51
- @interval.public_send(@interval_type).ago.to_date # rubocop:disable GitlabSecurity/PublicSend
52
- end
53
-
54
- def calculate
55
- case @condition
56
- when :older_than
57
- resource_value < condition_value
58
- when :newer_than
59
- resource_value > condition_value
60
- end
61
- end
62
- end
63
- end
64
- end
65
- end