gitlab-triage 1.11.0 → 1.14.2

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
  SHA256:
3
- metadata.gz: e02cd169e252e4656441f6e9268314c2b968935957dbcb906ae3048ee7045da4
4
- data.tar.gz: 3b58c8b37e3f82878272641ad848239c74623499f0e309ba0ac9aaaf6803cf0f
3
+ metadata.gz: c40a53d7edad2e8472cb3a7a503af2d45d31dfb4b7192e12b170016cd47b0b23
4
+ data.tar.gz: 35c4cfc534faee10e6d1d02b6108d3300ad4cee20883e6e1299d97c5315a0cde
5
5
  SHA512:
6
- metadata.gz: 181a6a5055a61b5d8c78f36d047dfef269a92a7d0173598a490e5420ab04fb267c9c42be2ae9bef31a815eb7730a15b921dde2b1834e49dcc20d0969d4986f54
7
- data.tar.gz: 621d6e208ad9dcdd034931ca0656778e5247c6aa3f3e6fa8edf53ed401795452f0d136eec259df8a377e36589de866fc7ee949a792cd1fa5b2c07257cab577ee
6
+ metadata.gz: 27424e4cab78096d186c11b9508340b50f70b04fdf9ee942bc1063dd3e4a0b14e4f10ebe7651947f3e32bd891cff98eb33db2315cd021aaef86e1f38e3dc9552
7
+ data.tar.gz: 3c4e60ac07b46c9c755d8b85c39fed6addc39370b268885090e7cf822456877e1f3bf241adf7288c5f5df6cda802284ca05cfa8c91d79d92dc04086c36d8a182
@@ -1,2 +1,2 @@
1
1
  # The official maintainers
2
- * @rymai @godfat @markglenfletcher
2
+ * @rymai @godfat-gitlab @markglenfletcher
@@ -32,4 +32,4 @@ with the latest commit from https://gitlab.com/gitlab-org/gitlab-triage/commits/
32
32
  - Checklist after merging:
33
33
  - [ ] [Update the release notes for the newly created tag](docs/release_process.md#how-to).
34
34
 
35
- /label ~"Engineering Productivity" ~"ep::triage" ~"tooling::workflow"
35
+ /label ~"Engineering Productivity" ~"ep::triage" ~tooling ~"tooling::workflow"
data/README.md CHANGED
@@ -141,6 +141,8 @@ Available condition types:
141
141
  - [`assignee_member` condition](#assignee-member-condition)
142
142
  - [`source_branch` condition](#source-branch-condition)
143
143
  - [`target_branch` condition](#target-branch-condition)
144
+ - [`weight` condition](#weight-condition)
145
+ - [`discussions` condition](#discussions-condition)
144
146
  - [`ruby` condition](#ruby-condition)
145
147
 
146
148
  ##### Date condition
@@ -467,6 +469,44 @@ conditions:
467
469
  target_branch: 'master'
468
470
  ```
469
471
 
472
+ ##### Weight condition
473
+
474
+ Accepts a string per the [API documentation](https://docs.gitlab.com/ee/api/issues.html#list-issues).
475
+ This condition is only applicable for issues (not merge requests).
476
+
477
+ | State | Type | Value |
478
+ | --------- | ---- | ------ |
479
+ | Any weight | string | `Any` |
480
+ | No weight | string | `None` |
481
+ | Specific weight | integer | integer |
482
+
483
+ Example:
484
+
485
+ ```yml
486
+ conditions:
487
+ weight: Any
488
+ ```
489
+
490
+ ##### Discussions condition
491
+
492
+ Accepts a hash of fields.
493
+
494
+ | Field | Type | Values | Required |
495
+ | --------- | ---- | ---- | -------- |
496
+ | `attribute` | string | `threads`, `notes` | yes |
497
+ | `condition` | string | `less_than`, `greater_than` | yes |
498
+ | `threshold` | integer | integer | yes |
499
+
500
+ Example:
501
+
502
+ ```yml
503
+ conditions:
504
+ discussions:
505
+ attribute: threads
506
+ condition: greater_than
507
+ threshold: 15
508
+ ```
509
+
470
510
  ##### Ruby condition
471
511
 
472
512
  This condition allows users to write a Ruby expression to be evaluated for
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
 
22
22
  spec.add_dependency 'activesupport', '~> 5.1'
23
+ spec.add_dependency 'globalid', '~> 0.4'
24
+ spec.add_dependency 'graphql-client', '~> 0.16'
23
25
  spec.add_dependency 'httparty', '~> 0.17'
24
26
 
25
27
  spec.add_development_dependency 'bundler'
@@ -2,16 +2,25 @@ module Gitlab
2
2
  module Triage
3
3
  module APIQueryBuilders
4
4
  class BaseQueryParamBuilder
5
- attr_reader :param_name, :param_contents
5
+ attr_reader :param_name, :param_contents, :allowed_values
6
6
 
7
- def initialize(param_name, param_contents)
7
+ def initialize(param_name, param_contents, allowed_values: nil)
8
8
  @param_name = param_name
9
9
  @param_contents = param_contents
10
+ @allowed_values = allowed_values
11
+
12
+ validate_allowed_values! if allowed_values
10
13
  end
11
14
 
12
15
  def build_param
13
16
  "&#{param_name}=#{param_content.strip}"
14
17
  end
18
+
19
+ private
20
+
21
+ def validate_allowed_values!
22
+ ParamsValidator.new([{ name: param_name, type: String, values: allowed_values }], { param_name => param_contents }).validate!
23
+ end
15
24
  end
16
25
  end
17
26
  end
@@ -6,14 +6,22 @@ module Gitlab
6
6
  class MultiQueryParamBuilder < BaseQueryParamBuilder
7
7
  attr_reader :separator
8
8
 
9
- def initialize(param_name, param_contents, separator)
9
+ def initialize(param_name, param_contents, separator, allowed_values: nil)
10
10
  @separator = separator
11
- super(param_name, param_contents)
11
+ super(param_name, Array(param_contents), allowed_values: allowed_values)
12
12
  end
13
13
 
14
14
  def param_content
15
15
  param_contents.map(&:strip).join(separator)
16
16
  end
17
+
18
+ private
19
+
20
+ def validate_allowed_values!
21
+ param_contents.each do |param|
22
+ ParamsValidator.new([{ name: param_name, type: String, values: allowed_values }], { param_name => param }).validate!
23
+ end
24
+ end
17
25
  end
18
26
  end
19
27
  end
@@ -7,6 +7,7 @@ require_relative 'filters/votes_conditions_filter'
7
7
  require_relative 'filters/no_additional_labels_conditions_filter'
8
8
  require_relative 'filters/author_member_conditions_filter'
9
9
  require_relative 'filters/assignee_member_conditions_filter'
10
+ require_relative 'filters/discussions_conditions_filter'
10
11
  require_relative 'filters/ruby_conditions_filter'
11
12
  require_relative 'limiters/date_field_limiter'
12
13
  require_relative 'action'
@@ -19,7 +20,10 @@ require_relative 'api_query_builders/single_query_param_builder'
19
20
  require_relative 'api_query_builders/multi_query_param_builder'
20
21
  require_relative 'url_builders/url_builder'
21
22
  require_relative 'network'
23
+ require_relative 'graphql_network'
22
24
  require_relative 'network_adapters/httparty_adapter'
25
+ require_relative 'network_adapters/graphql_adapter'
26
+ require_relative 'graphql_queries/query_builder'
23
27
  require_relative 'ui'
24
28
 
25
29
  module Gitlab
@@ -27,7 +31,14 @@ module Gitlab
27
31
  class Engine
28
32
  attr_reader :per_page, :policies, :options
29
33
 
30
- def initialize(policies:, options:, network_adapter_class: Gitlab::Triage::NetworkAdapters::HttpartyAdapter)
34
+ DEFAULT_NETWORK_ADAPTER = Gitlab::Triage::NetworkAdapters::HttpartyAdapter
35
+ DEFAULT_GRAPHQL_ADAPTER = Gitlab::Triage::NetworkAdapters::GraphqlAdapter
36
+ ALLOWED_STATE_VALUES = {
37
+ issues: %w[opened closed],
38
+ merge_requests: %w[opened closed merged]
39
+ }.with_indifferent_access.freeze
40
+
41
+ def initialize(policies:, options:, network_adapter_class: DEFAULT_NETWORK_ADAPTER, graphql_network_adapter_class: DEFAULT_GRAPHQL_ADAPTER)
31
42
  options.host_url = policies.delete(:host_url) { options.host_url }
32
43
  options.api_version = policies.delete(:api_version) { 'v4' }
33
44
  options.dry_run = ENV['TEST'] == 'true' if options.dry_run.nil?
@@ -36,6 +47,7 @@ module Gitlab
36
47
  @policies = policies
37
48
  @options = options
38
49
  @network_adapter_class = network_adapter_class
50
+ @graphql_network_adapter_class = graphql_network_adapter_class
39
51
 
40
52
  assert_all!
41
53
  assert_project_id!
@@ -62,6 +74,10 @@ module Gitlab
62
74
  @network ||= Network.new(network_adapter)
63
75
  end
64
76
 
77
+ def graphql_network
78
+ @graphql_network ||= GraphqlNetwork.new(graphql_network_adapter)
79
+ end
80
+
65
81
  private
66
82
 
67
83
  def assert_project_id!
@@ -94,6 +110,10 @@ module Gitlab
94
110
  @network_adapter ||= @network_adapter_class.new(options)
95
111
  end
96
112
 
113
+ def graphql_network_adapter
114
+ @graphql_network_adapter ||= @graphql_network_adapter_class.new(options)
115
+ end
116
+
97
117
  def rule_conditions(rule)
98
118
  rule.fetch(:conditions) { {} }
99
119
  end
@@ -158,8 +178,13 @@ module Gitlab
158
178
  # retrieving the resources for every rule is inefficient
159
179
  # however, previous rules may affect those upcoming
160
180
  resources = network.query_api(build_get_url(resource_type, conditions))
181
+ iids = resources.pluck('iid').map(&:to_s)
182
+
183
+ graphql_query = build_graphql_query(resource_type, conditions)
184
+ graphql_resources = graphql_network.query(graphql_query, source: options.source_id, iids: iids) if graphql_query.present?
161
185
  # In some filters/actions we want to know which resource type it is
162
186
  attach_resource_type(resources, resource_type)
187
+ decorate_resources_with_graphql_data(resources, graphql_resources)
163
188
 
164
189
  puts "\n\n* Found #{resources.count} resources..."
165
190
  print "* Filtering resources..."
@@ -180,6 +205,13 @@ module Gitlab
180
205
  resources.each { |resource| resource[:type] ||= resource_type }
181
206
  end
182
207
 
208
+ def decorate_resources_with_graphql_data(resources, graphql_resources)
209
+ return if graphql_resources.nil?
210
+
211
+ graphql_resources_by_id = graphql_resources.to_h { |resource| [resource[:id], resource] }
212
+ resources.each { |resource| resource.merge!(graphql_resources_by_id[resource[:id]].to_h) }
213
+ end
214
+
183
215
  def process_action(policy)
184
216
  Action.process(
185
217
  policy: policy,
@@ -213,6 +245,10 @@ module Gitlab
213
245
  results << Filters::AssigneeMemberConditionsFilter.new(resource, conditions[:assignee_member], network).calculate
214
246
  end
215
247
 
248
+ if conditions[:discussions]
249
+ results << Filters::DiscussionsConditionsFilter.new(resource, conditions[:discussions]).calculate
250
+ end
251
+
216
252
  if conditions[:ruby]
217
253
  results << Filters::RubyConditionsFilter.new(resource, conditions, network).calculate
218
254
  end
@@ -244,7 +280,13 @@ module Gitlab
244
280
  condition_builders << APIQueryBuilders::MultiQueryParamBuilder.new('not[labels]', conditions[:forbidden_labels], ',')
245
281
  end
246
282
 
247
- condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('state', conditions[:state]) if conditions[:state]
283
+ if conditions[:state]
284
+ condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new(
285
+ 'state',
286
+ conditions[:state],
287
+ allowed_values: ALLOWED_STATE_VALUES[resource_type])
288
+ end
289
+
248
290
  condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('milestone', Array(conditions[:milestone])[0]) if conditions[:milestone]
249
291
  condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('source_branch', conditions[:source_branch]) if conditions[:source_branch]
250
292
  condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('target_branch', conditions[:target_branch]) if conditions[:target_branch]
@@ -253,6 +295,10 @@ module Gitlab
253
295
  condition_builders << APIQueryBuilders::DateQueryParamBuilder.new(conditions.delete(:date))
254
296
  end
255
297
 
298
+ if conditions[:weight] && resource_type.to_sym == :issues
299
+ condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('weight', conditions[:weight])
300
+ end
301
+
256
302
  condition_builders.each do |condition_builder|
257
303
  params[condition_builder.param_name] = condition_builder.param_content
258
304
  end
@@ -266,6 +312,11 @@ module Gitlab
266
312
  params: params
267
313
  ).build
268
314
  end
315
+
316
+ def build_graphql_query(resource_type, conditions)
317
+ Gitlab::Triage::GraphqlQueries::QueryBuilder
318
+ .new(options.source, resource_type, conditions)
319
+ end
269
320
  end
270
321
  end
271
322
  end
@@ -0,0 +1,60 @@
1
+ require_relative 'base_conditions_filter'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module Filters
6
+ class DiscussionsConditionsFilter < BaseConditionsFilter
7
+ ATTRIBUTES = %w[notes threads].freeze
8
+ CONDITIONS = %w[greater_than less_than].freeze
9
+
10
+ def self.filter_parameters
11
+ [
12
+ {
13
+ name: :attribute,
14
+ type: String,
15
+ values: ATTRIBUTES
16
+ },
17
+ {
18
+ name: :condition,
19
+ type: String,
20
+ values: CONDITIONS
21
+ },
22
+ {
23
+ name: :threshold,
24
+ type: Numeric
25
+ }
26
+ ]
27
+ end
28
+
29
+ def initialize_variables(condition)
30
+ @attribute = condition[:attribute].to_sym
31
+ @condition = condition[:condition].to_sym
32
+ @threshold = condition[:threshold]
33
+ end
34
+
35
+ def resource_value
36
+ if @attribute == :notes
37
+ @resource[:user_notes_count]
38
+ else
39
+ @resource.dig(:discussions, :nodes)&.count do |node|
40
+ !node&.dig(:notes, :nodes, 0, :system)
41
+ end
42
+ end
43
+ end
44
+
45
+ def condition_value
46
+ @threshold
47
+ end
48
+
49
+ def calculate
50
+ case @condition
51
+ when :greater_than
52
+ resource_value.to_i > condition_value
53
+ when :less_than
54
+ resource_value.to_i < condition_value
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,54 @@
1
+ require 'active_support/all'
2
+ require 'net/protocol'
3
+ require 'globalid'
4
+
5
+ require_relative 'retryable'
6
+ require_relative 'ui'
7
+ require_relative 'errors'
8
+
9
+ module Gitlab
10
+ module Triage
11
+ class GraphqlNetwork
12
+ attr_reader :options, :adapter
13
+
14
+ def initialize(adapter)
15
+ @adapter = adapter
16
+ @options = adapter.options
17
+ end
18
+
19
+ def query(graphql_query, variables = {})
20
+ return if graphql_query.blank?
21
+
22
+ response = {}
23
+ resources = []
24
+
25
+ parsed_graphql_query = adapter.parse(graphql_query.query)
26
+
27
+ begin
28
+ print '.'
29
+
30
+ response = adapter.query(
31
+ parsed_graphql_query,
32
+ resource_path: graphql_query.resource_path,
33
+ variables: variables.merge(after: response.delete(:end_cursor))
34
+ )
35
+
36
+ resources.concat(Array.wrap(response.delete(:results)))
37
+ end while response.delete(:more_pages)
38
+
39
+ resources
40
+ .map { |resource| resource.deep_transform_keys(&:underscore) }
41
+ .map(&:with_indifferent_access)
42
+ .map { |resource| resource.merge(id: extract_id_from_global_id(resource[:id])) }
43
+ end
44
+
45
+ private
46
+
47
+ def extract_id_from_global_id(global_id)
48
+ return if global_id.blank?
49
+
50
+ GlobalID.parse(global_id).model_id.to_i
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'user_notes_query'
2
+ require_relative 'threads_query'
3
+
4
+ module Gitlab
5
+ module Triage
6
+ module GraphqlQueries
7
+ class QueryBuilder
8
+ def initialize(source_type, resource_type, conditions)
9
+ @source_type = source_type.to_s.singularize
10
+ @resource_type = resource_type
11
+ @conditions = conditions
12
+ end
13
+
14
+ def resource_path
15
+ [source_type, resource_type]
16
+ end
17
+
18
+ def query
19
+ return if query_template.nil?
20
+
21
+ format(query_template, source_type: source_type, resource_type: resource_type.to_s.camelize(:lower), group_query: group_query)
22
+ end
23
+
24
+ delegate :present?, to: :query_template
25
+
26
+ private
27
+
28
+ attr_reader :source_type, :resource_type, :conditions
29
+
30
+ def query_template
31
+ case conditions.dig(:discussions, :attribute).to_s
32
+ when 'notes'
33
+ UserNotesQuery
34
+ when 'threads'
35
+ ThreadsQuery
36
+ end
37
+ end
38
+
39
+ def group_query
40
+ return if source_type != 'group'
41
+
42
+ ', includeSubgroups: true'
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ module Gitlab
2
+ module Triage
3
+ module GraphqlQueries
4
+ ThreadsQuery = <<-GRAPHQL.freeze # rubocop:disable Naming/ConstantName
5
+ query($source: ID!, $after: String, $iids: [String!]) {
6
+ %{source_type}(fullPath: $source) {
7
+ id
8
+ %{resource_type}(after: $after, iids: $iids%{group_query}) {
9
+ pageInfo {
10
+ hasNextPage
11
+ endCursor
12
+ }
13
+ nodes {
14
+ id
15
+ discussions {
16
+ nodes {
17
+ notes {
18
+ nodes {
19
+ system
20
+ }
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ GRAPHQL
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Gitlab
2
+ module Triage
3
+ module GraphqlQueries
4
+ UserNotesQuery = <<-GRAPHQL.freeze # rubocop:disable Naming/ConstantName
5
+ query($source: ID!, $after: String, $iids: [String!]) {
6
+ %{source_type}(fullPath: $source) {
7
+ id
8
+ %{resource_type}(after: $after, iids: $iids%{group_query}) {
9
+ pageInfo {
10
+ hasNextPage
11
+ endCursor
12
+ }
13
+ nodes {
14
+ id
15
+ userNotesCount
16
+ }
17
+ }
18
+ }
19
+ }
20
+ GRAPHQL
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,69 @@
1
+ require 'graphql/client'
2
+ require 'graphql/client/http'
3
+
4
+ require_relative 'base_adapter'
5
+ require_relative '../ui'
6
+ require_relative '../errors'
7
+
8
+ module Gitlab
9
+ module Triage
10
+ module NetworkAdapters
11
+ class GraphqlAdapter < BaseAdapter
12
+ Client = GraphQL::Client
13
+
14
+ def query(graphql_query, resource_path: [], variables: {})
15
+ response = client.query(graphql_query, variables: variables, context: { token: options.token })
16
+
17
+ raise_on_error!(response)
18
+
19
+ parsed_response = parse_response(response, resource_path)
20
+
21
+ return { results: {} } if parsed_response.nil?
22
+ return { results: parsed_response.map(&:to_h) } if parsed_response.is_a?(Client::List)
23
+ return { results: parsed_response.to_h } unless parsed_response.nodes?
24
+
25
+ {
26
+ more_pages: parsed_response.page_info.has_next_page,
27
+ end_cursor: parsed_response.page_info.end_cursor,
28
+ results: parsed_response.nodes.map(&:to_h)
29
+ }
30
+ end
31
+
32
+ delegate :parse, to: :client
33
+
34
+ private
35
+
36
+ def parse_response(response, resource_path)
37
+ resource_path.reduce(response.data) { |data, resource| data&.send(resource) }
38
+ end
39
+
40
+ def raise_on_error!(response)
41
+ return if response.errors.blank?
42
+
43
+ puts Gitlab::Triage::UI.debug response.inspect if options.debug
44
+
45
+ raise "There was an error: #{response.errors.messages.to_json}"
46
+ end
47
+
48
+ def http_client
49
+ Client::HTTP.new("#{options.host_url}/api/graphql") do
50
+ def headers(context) # rubocop:disable Lint/NestedMethodDefinition
51
+ {
52
+ 'Content-type' => 'application/json',
53
+ 'PRIVATE-TOKEN' => context[:token]
54
+ }
55
+ end
56
+ end
57
+ end
58
+
59
+ def schema
60
+ @schema ||= Client.load_schema(http_client)
61
+ end
62
+
63
+ def client
64
+ @client ||= Client.new(schema: schema, execute: http_client).tap { |client| client.allow_dynamic_queries = true }
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,20 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
3
+ require 'delegate'
4
4
 
5
5
  module Gitlab
6
6
  module Triage
7
7
  module PoliciesResources
8
- class RuleResources
9
- include Enumerable
10
- extend Forwardable
11
-
12
- def initialize(new_resources)
13
- @resources = new_resources
14
- end
15
-
16
- def_delegator :@resources, :each
17
- end
8
+ RuleResources = Class.new(SimpleDelegator)
18
9
  end
19
10
  end
20
11
  end
@@ -1,20 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
3
+ require 'delegate'
4
4
 
5
5
  module Gitlab
6
6
  module Triage
7
7
  module PoliciesResources
8
- class SummaryResources
9
- include Enumerable
10
- extend Forwardable
11
-
12
- def initialize(new_rule_to_resources)
13
- @rule_to_resources = new_rule_to_resources
14
- end
15
-
16
- def_delegator :@rule_to_resources, :each
17
- end
8
+ SummaryResources = Class.new(SimpleDelegator)
18
9
  end
19
10
  end
20
11
  end
@@ -17,7 +17,7 @@ module Gitlab
17
17
 
18
18
  def build
19
19
  url = base_url
20
- url << "/#{CGI.escape(@resource_id.to_s)}" if @resource_id
20
+ url << "/#{percent_encode(@resource_id.to_s)}" if @resource_id
21
21
  url << "/#{@sub_resource_type}" if @sub_resource_type
22
22
  url << params_string if @params
23
23
  url
@@ -31,16 +31,20 @@ module Gitlab
31
31
 
32
32
  def base_url
33
33
  url = host_with_api_url
34
- url << "/#{@source}/#{CGI.escape(@source_id.to_s)}" unless @all
34
+ url << "/#{@source}/#{percent_encode(@source_id.to_s)}" unless @all
35
35
  url << "/#{@resource_type}" if @resource_type
36
36
  url
37
37
  end
38
38
 
39
39
  def params_string
40
40
  "?" << @params.map do |k, v|
41
- "#{k}=#{v}"
41
+ "#{percent_encode(k.to_s)}=#{percent_encode(v.to_s)}"
42
42
  end.join("&")
43
43
  end
44
+
45
+ def percent_encode(str)
46
+ CGI.escape(str).gsub('+', '%20')
47
+ end
44
48
  end
45
49
  end
46
50
  end
@@ -34,7 +34,7 @@ module Gitlab
34
34
  def validate_parameter_content(value)
35
35
  @parameter_definitions.each do |param|
36
36
  if param[:values]
37
- raise InvalidParameter, "#{param[:name]} must be of one of #{param[:values].join(',')}" unless param[:values].include?(value[param[:name]])
37
+ raise InvalidParameter, "#{param[:name]} must be one of #{param[:values].join(',')}" unless param[:values].include?(value[param[:name]])
38
38
  end
39
39
  end
40
40
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module Triage
5
- VERSION = '1.11.0'
5
+ VERSION = '1.14.2'
6
6
  end
7
7
  end
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.11.0
4
+ version: 1.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-29 00:00:00.000000000 Z
11
+ date: 2020-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: globalid
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: graphql-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.16'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.16'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: httparty
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -158,16 +186,22 @@ files:
158
186
  - lib/gitlab/triage/filters/assignee_member_conditions_filter.rb
159
187
  - lib/gitlab/triage/filters/author_member_conditions_filter.rb
160
188
  - lib/gitlab/triage/filters/base_conditions_filter.rb
189
+ - lib/gitlab/triage/filters/discussions_conditions_filter.rb
161
190
  - lib/gitlab/triage/filters/member_conditions_filter.rb
162
191
  - lib/gitlab/triage/filters/merge_request_date_conditions_filter.rb
163
192
  - lib/gitlab/triage/filters/name_conditions_filter.rb
164
193
  - lib/gitlab/triage/filters/no_additional_labels_conditions_filter.rb
165
194
  - lib/gitlab/triage/filters/ruby_conditions_filter.rb
166
195
  - lib/gitlab/triage/filters/votes_conditions_filter.rb
196
+ - lib/gitlab/triage/graphql_network.rb
197
+ - lib/gitlab/triage/graphql_queries/query_builder.rb
198
+ - lib/gitlab/triage/graphql_queries/threads_query.rb
199
+ - lib/gitlab/triage/graphql_queries/user_notes_query.rb
167
200
  - lib/gitlab/triage/limiters/base_limiter.rb
168
201
  - lib/gitlab/triage/limiters/date_field_limiter.rb
169
202
  - lib/gitlab/triage/network.rb
170
203
  - lib/gitlab/triage/network_adapters/base_adapter.rb
204
+ - lib/gitlab/triage/network_adapters/graphql_adapter.rb
171
205
  - lib/gitlab/triage/network_adapters/httparty_adapter.rb
172
206
  - lib/gitlab/triage/network_adapters/test_adapter.rb
173
207
  - lib/gitlab/triage/option_parser.rb
@@ -213,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
213
247
  - !ruby/object:Gem::Version
214
248
  version: '0'
215
249
  requirements: []
216
- rubygems_version: 3.1.2
250
+ rubygems_version: 3.1.4
217
251
  signing_key:
218
252
  specification_version: 4
219
253
  summary: GitLab triage automation project.