gitlab-triage 1.24.0 → 1.25.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
  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