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 +4 -4
- data/README.md +55 -6
- data/lib/gitlab/triage/action/comment.rb +5 -0
- data/lib/gitlab/triage/action/delete.rb +56 -0
- data/lib/gitlab/triage/action.rb +3 -1
- data/lib/gitlab/triage/command_builders/text_content_builder.rb +2 -1
- data/lib/gitlab/triage/engine.rb +21 -2
- data/lib/gitlab/triage/filters/branch_date_filter.rb +67 -0
- data/lib/gitlab/triage/filters/branch_protected_filter.rb +26 -0
- data/lib/gitlab/triage/network.rb +4 -0
- data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +20 -0
- data/lib/gitlab/triage/policies/base_policy.rb +5 -1
- data/lib/gitlab/triage/resource/branch.rb +13 -0
- data/lib/gitlab/triage/resource/context.rb +1 -0
- data/lib/gitlab/triage/rest_api_network.rb +15 -0
- data/lib/gitlab/triage/url_builders/url_builder.rb +1 -0
- data/lib/gitlab/triage/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42c73b8dcb5e94e895ba0daa399105f8111584523001f233a3b5344dd52e8d13
|
4
|
+
data.tar.gz: 0f9c38c9aa9de8c6210cca84d6224af7647bfeec4c7fa8a73562cb4e035205e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
176
|
-
| --------- | ----
|
177
|
-
| `attribute` | string | `created_at`, `updated_at`, `merged_at` | yes |
|
178
|
-
| `condition` | string | `older_than`, `newer_than`
|
179
|
-
| `interval_type` | string | `days`, `weeks`, `months`, `years`
|
180
|
-
| `interval` | integer | integer
|
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
|
data/lib/gitlab/triage/action.rb
CHANGED
@@ -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
|
data/lib/gitlab/triage/engine.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -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
|
@@ -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
|
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.
|
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-
|
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
|