gitlab-triage 1.24.0 → 1.25.0

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: 0d4dafafa454a68a9258f5753ef3df345e0a0f13c104158bc1243ecb561d408a
4
- data.tar.gz: c0d12641e77a6865e0f5569d405e2548b03884e61280dc262a922ff38b786c84
3
+ metadata.gz: 42c73b8dcb5e94e895ba0daa399105f8111584523001f233a3b5344dd52e8d13
4
+ data.tar.gz: 0f9c38c9aa9de8c6210cca84d6224af7647bfeec4c7fa8a73562cb4e035205e9
5
5
  SHA512:
6
- metadata.gz: ea2b0d33abf1eb19403519f264ab25d249a9992e97e08f830505f497a50cc91ae0f9210db270b87d45649ef41c1d1248fcf2ef13b6820991455cfe4d09e8247f
7
- data.tar.gz: 063b0a7ec5503f55ee4971e84cc1ddeb81b1ce83997a41dbd48a9c730ada4b402693fc1e4f2be6a955cc9de57c283ed4ee1b37e059633bec355a95c2a55efe3b
6
+ metadata.gz: 264e37c9838cff91100494a72a791828e555afcac5e028a83cd0de7b86c19f9d206d1ffe0486983cd990cd51686719c660b7b04f530bd633118bc85f734a9960
7
+ data.tar.gz: dd4e5b974bdf3496ee8a40eca9d69d17a3882cf40e6ac24fb8b452c500ad2fe17c8a40bd32ff1a97ad5639f7837cbdc24c993ea96d264a07a2a58985af6744b8
data/README.md CHANGED
@@ -21,6 +21,7 @@ Triage policies are defined on a resource level basis, resources being:
21
21
  - Epics
22
22
  - Issues
23
23
  - Merge Requests
24
+ - Branches
24
25
 
25
26
  Each policy can declare a number of conditions that must all be satisfied before
26
27
  a number of actions are carried out.
@@ -42,6 +43,7 @@ Select which resource to add the policy to:
42
43
  - `epics`
43
44
  - `issues`
44
45
  - `merge_requests`
46
+ - `branches`
45
47
 
46
48
  And create an array of `rules` to define your policies:
47
49
 
@@ -120,6 +122,18 @@ resource_rules:
120
122
  comment_type: thread
121
123
  comment: |
122
124
  {{author}} This issue is unlabelled. Please add one or more labels.
125
+ branches:
126
+ rules:
127
+ - name: My branch policy
128
+ conditions:
129
+ date:
130
+ attribute: committed_date
131
+ condition: older_than
132
+ interval_type: 6
133
+ interval: months
134
+ name: ^feature
135
+ actions:
136
+ delete: true
123
137
  ```
124
138
 
125
139
  ### Real world example
@@ -166,21 +180,23 @@ Available condition types:
166
180
  - [`target_branch` condition](#target-branch-condition)
167
181
  - [`weight` condition](#weight-condition)
168
182
  - [`discussions` condition](#discussions-condition)
183
+ - [`protected` condition](#protected-condition)
169
184
  - [`ruby` condition](#ruby-condition)
170
185
 
171
186
  ##### Date condition
172
187
 
173
188
  Accepts a hash of fields.
174
189
 
175
- | Field | Type | Values | Required |
176
- | --------- | ---- | ---- | -------- |
177
- | `attribute` | string | `created_at`, `updated_at`, `merged_at` | yes |
178
- | `condition` | string | `older_than`, `newer_than` | yes |
179
- | `interval_type` | string | `days`, `weeks`, `months`, `years` | yes |
180
- | `interval` | integer | integer | yes |
190
+ | Field | Type | Values | Required |
191
+ | --------- | ---- |--------------------------------------------------------------------------| -------- |
192
+ | `attribute` | string | `created_at`, `updated_at`, `merged_at`, `authored_date`, `committed_date` | yes |
193
+ | `condition` | string | `older_than`, `newer_than` | yes |
194
+ | `interval_type` | string | `days`, `weeks`, `months`, `years` | yes |
195
+ | `interval` | integer | integer | yes |
181
196
  > **Note:**
182
197
  > - `merged_at` only works on merge requests.
183
198
  > - `closed_at` is not supported in the GitLab API, but can be used in a [`ruby` condition](#ruby-condition).
199
+ > - `committed_date` and `authored_date` only works for branches.
184
200
 
185
201
  Example:
186
202
 
@@ -575,6 +591,13 @@ conditions:
575
591
  threshold: 15
576
592
  ```
577
593
 
594
+ ##### Protected condition
595
+
596
+ ** This condition is only applicable for branches**
597
+
598
+ Accept a boolean.
599
+ If not specified, default to `false` to filter out protected branches.
600
+
578
601
  ##### Ruby condition
579
602
 
580
603
  This condition allows users to write a Ruby expression to be evaluated for
@@ -661,6 +684,8 @@ Available action types:
661
684
  - [`comment_type` action option](#comment-type-action-option)
662
685
  - [`summarize` action](#summarize-action)
663
686
  - [`comment_on_summary` action](#comment-on-summary-action)
687
+ - [`issue` action](#create-a-new-issue-from-each-resource)
688
+ - [`delete` action](#delete-action)
664
689
 
665
690
  ##### Labels action
666
691
 
@@ -1032,6 +1057,30 @@ resource_rules:
1032
1057
  /label ~"needs attention"
1033
1058
  ```
1034
1059
 
1060
+ ##### Delete action
1061
+
1062
+ **This action is only applicable for branches.**
1063
+
1064
+ Delete the resource.
1065
+
1066
+ Accept a boolean. Set to `true` to enable.
1067
+
1068
+ Example :
1069
+ ```yaml
1070
+ resource_rules:
1071
+ branches:
1072
+ rules:
1073
+ - name: My branch policy
1074
+ conditions:
1075
+ date:
1076
+ attribute: committed_date
1077
+ condition: older_than
1078
+ interval_type: months
1079
+ interval: 30
1080
+ actions:
1081
+ delete: true
1082
+ ```
1083
+
1035
1084
  ### Summary policies
1036
1085
 
1037
1086
  Summary policies are special policies that join multiple rule policies together
@@ -28,6 +28,11 @@ module Gitlab
28
28
  end
29
29
 
30
30
  def act
31
+ if policy.type == 'branches'
32
+ puts Gitlab::Triage::UI.warn "Comment actions are not available for branches. They will NOT be performed\n\n"
33
+ return
34
+ end
35
+
31
36
  policy.resources.each do |resource|
32
37
  comment = build_comment(resource).strip
33
38
 
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Gitlab
6
+ module Triage
7
+ module Action
8
+ class Delete < Base
9
+ class Dry < Delete
10
+ def act
11
+ puts "The following resources will be deleted by the rule **#{policy.name}**:\n\n"
12
+ super
13
+ end
14
+
15
+ private
16
+
17
+ def perform(resource)
18
+ puts "DELETE resource with type: #{resource[:type]} and id: #{resource_id(resource)}"
19
+ end
20
+ end
21
+
22
+ def act
23
+ return unless policy.type&.to_sym == :branches
24
+
25
+ policy.resources.each do |resource|
26
+ perform(resource)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def perform(resource)
33
+ network.delete_api(build_delete_url(resource))
34
+ end
35
+
36
+ def build_delete_url(resource)
37
+ delete_url = UrlBuilders::UrlBuilder.new(
38
+ source: policy.source,
39
+ source_id: network.options.source_id,
40
+ resource_type: policy.type,
41
+ resource_id: resource_id(resource),
42
+ network_options: network.options
43
+ ).build
44
+
45
+ puts Gitlab::Triage::UI.debug "delete_url: #{delete_url}" if network.options.debug
46
+
47
+ delete_url
48
+ end
49
+
50
+ def resource_id(resource)
51
+ resource[:name]
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -2,6 +2,7 @@ require_relative 'action/summarize'
2
2
  require_relative 'action/comment'
3
3
  require_relative 'action/comment_on_summary'
4
4
  require_relative 'action/issue'
5
+ require_relative 'action/delete'
5
6
 
6
7
  module Gitlab
7
8
  module Triage
@@ -13,7 +14,8 @@ module Gitlab
13
14
  [Summarize, policy.summarize?],
14
15
  [Comment, policy.comment?],
15
16
  [CommentOnSummary, policy.comment_on_summary?],
16
- [Issue, policy.issue?]
17
+ [Issue, policy.issue?],
18
+ [Delete, policy.delete?]
17
19
  ].each do |action, active|
18
20
  act(action: action, policy: policy, **args) if active
19
21
  end
@@ -31,7 +31,8 @@ module Gitlab
31
31
  web_url: "{{web_url}}",
32
32
  full_reference: "{{references.full}}",
33
33
  type: "{{type}}",
34
- items: "{{items}}"
34
+ items: "{{items}}",
35
+ name: "{{name}}"
35
36
  }.freeze
36
37
  PLACEHOLDER_REGEX = /{{([\w\.]+)}}/.freeze
37
38
 
@@ -3,6 +3,8 @@ require 'active_support/inflector'
3
3
 
4
4
  require_relative 'expand_condition'
5
5
  require_relative 'filters/merge_request_date_conditions_filter'
6
+ require_relative 'filters/branch_date_filter'
7
+ require_relative 'filters/branch_protected_filter'
6
8
  require_relative 'filters/votes_conditions_filter'
7
9
  require_relative 'filters/no_additional_labels_conditions_filter'
8
10
  require_relative 'filters/author_member_conditions_filter'
@@ -339,7 +341,16 @@ module Gitlab
339
341
 
340
342
  # rubocop:disable Style/IfUnlessModifier
341
343
  if conditions[:date]
342
- results << Filters::MergeRequestDateConditionsFilter.new(resource, conditions[:date]).calculate
344
+ case resource[:type]
345
+ when 'branches'
346
+ results << Filters::BranchDateFilter.new(resource, conditions[:date]).calculate
347
+ when 'merge_requests'
348
+ results << Filters::MergeRequestDateConditionsFilter.new(resource, conditions[:date]).calculate
349
+ end
350
+ end
351
+
352
+ if resource[:type] == 'branches'
353
+ results << Filters::BranchProtectedFilter.new(resource, conditions[:protected]).calculate
343
354
  end
344
355
 
345
356
  if conditions[:upvotes]
@@ -402,7 +413,7 @@ module Gitlab
402
413
 
403
414
  condition_builders << milestone_condition_builder(resource_type, conditions[:milestone]) if conditions[:milestone]
404
415
 
405
- if conditions[:date] && APIQueryBuilders::DateQueryParamBuilder.applicable?(conditions[:date])
416
+ if conditions[:date] && APIQueryBuilders::DateQueryParamBuilder.applicable?(conditions[:date]) && resource_type&.to_sym != :branches
406
417
  condition_builders << APIQueryBuilders::DateQueryParamBuilder.new(conditions.delete(:date))
407
418
  end
408
419
 
@@ -411,6 +422,8 @@ module Gitlab
411
422
  condition_builders.concat(issues_resource_query(conditions))
412
423
  when :merge_requests
413
424
  condition_builders.concat(merge_requests_resource_query(conditions))
425
+ when :branches
426
+ condition_builders.concat(branches_resource_query(conditions))
414
427
  end
415
428
 
416
429
  condition_builders.compact.each do |condition_builder|
@@ -468,6 +481,12 @@ module Gitlab
468
481
  end
469
482
  end
470
483
 
484
+ def branches_resource_query(conditions)
485
+ [].tap do |condition_builders|
486
+ condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('search', conditions[:name]) if conditions[:name]
487
+ end
488
+ end
489
+
471
490
  def draft_condition_builder(draft_condittion)
472
491
  # Issues API only accepts 'yes' and 'no' as strings: https://docs.gitlab.com/ee/api/merge_requests.html
473
492
  wip =
@@ -0,0 +1,67 @@
1
+ require_relative 'base_conditions_filter'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module Filters
6
+ class BranchDateFilter < BaseConditionsFilter
7
+ ATTRIBUTES = %w[committed_date authored_date].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[:commit][@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
+ return false unless resource_value
56
+
57
+ case @condition
58
+ when :older_than
59
+ resource_value < condition_value
60
+ when :newer_than
61
+ resource_value > condition_value
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'base_conditions_filter'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module Filters
6
+ class BranchProtectedFilter < BaseConditionsFilter
7
+ def initialize_variables(config_value)
8
+ @attribute = :protected
9
+ @condition = config_value.nil? ? true : config_value
10
+ end
11
+
12
+ def resource_value
13
+ @resource[:protected]
14
+ end
15
+
16
+ def condition_value
17
+ @condition
18
+ end
19
+
20
+ def calculate
21
+ resource_value == condition_value
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -30,6 +30,10 @@ module Gitlab
30
30
  def post_api(...)
31
31
  restapi.post_api(...)
32
32
  end
33
+
34
+ def delete_api(...)
35
+ restapi.delete_api(...)
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -53,6 +53,26 @@ module Gitlab
53
53
  }
54
54
  end
55
55
 
56
+ def delete(token, url)
57
+ response = HTTParty.delete(
58
+ url,
59
+ headers: {
60
+ 'User-Agent' => USER_AGENT,
61
+ 'PRIVATE-TOKEN' => token
62
+ }
63
+ )
64
+
65
+ raise_on_unauthorized_error!(response)
66
+ raise_on_internal_server_error!(response)
67
+ raise_on_too_many_requests!(response)
68
+
69
+ {
70
+ results: response.parsed_response,
71
+ ratelimit_remaining: response.headers["ratelimit-remaining"].to_i,
72
+ ratelimit_reset_at: Time.at(response.headers["ratelimit-reset"].to_i)
73
+ }
74
+ end
75
+
56
76
  private
57
77
 
58
78
  def raise_on_unauthorized_error!(response)
@@ -56,13 +56,17 @@ module Gitlab
56
56
 
57
57
  def comment?
58
58
  # The actual keys are strings
59
- (actions.keys.map(&:to_sym) - [:summarize, :comment_on_summary]).any?
59
+ (actions.keys.map(&:to_sym) - [:summarize, :comment_on_summary, :delete, :issue]).any?
60
60
  end
61
61
 
62
62
  def issue?
63
63
  actions.key?(:issue)
64
64
  end
65
65
 
66
+ def delete?
67
+ actions.key?(:delete) && actions[:delete]
68
+ end
69
+
66
70
  def build_issue
67
71
  raise NotImplementedError
68
72
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+ require_relative 'shared/issuable'
5
+
6
+ module Gitlab
7
+ module Triage
8
+ module Resource
9
+ class Branch < Base
10
+ end
11
+ end
12
+ end
13
+ end
@@ -6,6 +6,7 @@ require_relative 'issue'
6
6
  require_relative 'linked_issue'
7
7
  require_relative 'merge_request'
8
8
  require_relative 'instance_version'
9
+ require_relative 'branch'
9
10
 
10
11
  module Gitlab
11
12
  module Triage
@@ -85,6 +85,21 @@ module Gitlab
85
85
  {}
86
86
  end
87
87
 
88
+ def delete_api(url)
89
+ response = execute_with_retry(
90
+ exception_types: Net::ReadTimeout,
91
+ backoff_exceptions: Errors::Network::TooManyRequests) do
92
+ puts Gitlab::Triage::UI.debug "delete_api: #{url}" if options.debug
93
+
94
+ @adapter.delete(token, url)
95
+ end
96
+
97
+ rate_limit_debug(response) if options.debug
98
+ rate_limit_wait(response)
99
+ rescue Net::ReadTimeout
100
+ {}
101
+ end
102
+
88
103
  private
89
104
 
90
105
  def token
@@ -34,6 +34,7 @@ module Gitlab
34
34
  def base_url
35
35
  url = host_with_api_url
36
36
  url << "/#{@source}/#{percent_encode(@source_id.to_s)}" unless @all
37
+ url << "/repository" if @resource_type == 'branches'
37
38
  url << "/#{@resource_type}" if @resource_type
38
39
  url
39
40
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module Triage
5
- VERSION = '1.24.0'
5
+ VERSION = '1.25.0'
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.24.0
4
+ version: 1.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-21 00:00:00.000000000 Z
11
+ date: 2022-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -171,6 +171,7 @@ files:
171
171
  - lib/gitlab/triage/action/base.rb
172
172
  - lib/gitlab/triage/action/comment.rb
173
173
  - lib/gitlab/triage/action/comment_on_summary.rb
174
+ - lib/gitlab/triage/action/delete.rb
174
175
  - lib/gitlab/triage/action/issue.rb
175
176
  - lib/gitlab/triage/action/summarize.rb
176
177
  - lib/gitlab/triage/api_query_builders/base_query_param_builder.rb
@@ -197,6 +198,8 @@ files:
197
198
  - lib/gitlab/triage/filters/assignee_member_conditions_filter.rb
198
199
  - lib/gitlab/triage/filters/author_member_conditions_filter.rb
199
200
  - lib/gitlab/triage/filters/base_conditions_filter.rb
201
+ - lib/gitlab/triage/filters/branch_date_filter.rb
202
+ - lib/gitlab/triage/filters/branch_protected_filter.rb
200
203
  - lib/gitlab/triage/filters/discussions_conditions_filter.rb
201
204
  - lib/gitlab/triage/filters/member_conditions_filter.rb
202
205
  - lib/gitlab/triage/filters/merge_request_date_conditions_filter.rb
@@ -225,6 +228,7 @@ files:
225
228
  - lib/gitlab/triage/policies_resources/rule_resources.rb
226
229
  - lib/gitlab/triage/policies_resources/summary_resources.rb
227
230
  - lib/gitlab/triage/resource/base.rb
231
+ - lib/gitlab/triage/resource/branch.rb
228
232
  - lib/gitlab/triage/resource/context.rb
229
233
  - lib/gitlab/triage/resource/epic.rb
230
234
  - lib/gitlab/triage/resource/instance_version.rb