gitlab-triage 1.24.0 → 1.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +1 -1
- data/README.md +69 -10
- 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 +25 -12
- 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/graphql_queries/query_builder.rb +6 -2
- data/lib/gitlab/triage/network.rb +4 -0
- data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +20 -0
- data/lib/gitlab/triage/option_parser.rb +3 -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/resource/issue.rb +16 -0
- data/lib/gitlab/triage/rest_api_network.rb +16 -2
- data/lib/gitlab/triage/url_builders/url_builder.rb +1 -0
- data/lib/gitlab/triage/version.rb +1 -1
- data/support/.gitlab-ci.example.yml +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: dfb91844acb53e2543200eae19db3c5abaf9cd79106add7fa5ca7ca9585215dd
|
4
|
+
data.tar.gz: eba68ca3b8a0539f2428e63d71f86fe28ac1e292e89141fa3312192f9a21a2fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa86c82d57b8e4e9986039098b1c7f8f5b031dae68080bb38a84808ae6df26af48ebf0790d47558e8c9ecf6fad8ba2d7d8208ccb54a6b33cb753e0fac02139c5
|
7
|
+
data.tar.gz: cacc6bc349fa41819c5b163cd67165983021bfee35bc9f607f5a64cb283d1372db51740e4c851238e68ff15776ec6289dc280ee2ca1d11f5714c0d36f7e68013
|
data/.gitlab-ci.yml
CHANGED
@@ -126,7 +126,7 @@ dry-run:gitlab-triage:
|
|
126
126
|
- gitlab-triage --version
|
127
127
|
- gitlab-triage --help
|
128
128
|
- gitlab-triage --init
|
129
|
-
- gitlab-triage --dry-run --debug --
|
129
|
+
- gitlab-triage --dry-run --debug --source-id $CI_PROJECT_PATH
|
130
130
|
|
131
131
|
# This job requires allows to override the `CI_PROJECT_PATH` variable when triggered.
|
132
132
|
dry-run:custom:
|
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
|
@@ -155,7 +169,7 @@ Available condition types:
|
|
155
169
|
- [`milestone` condition](#milestone-condition)
|
156
170
|
- [`iteration` condition](#iteration-condition)
|
157
171
|
- [`state` condition](#state-condition)
|
158
|
-
- [`
|
172
|
+
- [`votes` condition](#votes-condition)
|
159
173
|
- [`labels` condition](#labels-condition)
|
160
174
|
- [`forbidden_labels` condition](#forbidden-labels-condition)
|
161
175
|
- [`no_additional_labels` condition](#no-additional-labels-condition)
|
@@ -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
|
|
@@ -248,7 +264,7 @@ conditions:
|
|
248
264
|
state: opened
|
249
265
|
```
|
250
266
|
|
251
|
-
#####
|
267
|
+
##### Votes condition
|
252
268
|
|
253
269
|
Accepts a hash of fields.
|
254
270
|
|
@@ -262,7 +278,7 @@ Example:
|
|
262
278
|
|
263
279
|
```yml
|
264
280
|
conditions:
|
265
|
-
|
281
|
+
votes:
|
266
282
|
attribute: upvotes
|
267
283
|
condition: less_than
|
268
284
|
threshold: 10
|
@@ -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
|
@@ -1146,6 +1195,7 @@ Here's a list of currently available Ruby expression API:
|
|
1146
1195
|
| related_merge_requests | [MergeRequest] | The list of merge requests related to the issue |
|
1147
1196
|
| closed_by | [MergeRequest] | The list of merge requests that close the issue |
|
1148
1197
|
| linked_issues | [LinkedIssue] | The list of issues that are linked to the issue |
|
1198
|
+
| due_date | Date | The due date of the issue. Could be `nil` |
|
1149
1199
|
|
1150
1200
|
##### Methods for `LinkedIssue`
|
1151
1201
|
|
@@ -1357,4 +1407,13 @@ Please refer to the [Contributing Guide](CONTRIBUTING.md).
|
|
1357
1407
|
|
1358
1408
|
## Release Process
|
1359
1409
|
|
1360
|
-
|
1410
|
+
We release `gitlab-triage` on an ad-hoc basis. There is no regularity to when
|
1411
|
+
we release, we just release when we make a change - no matter the size of the
|
1412
|
+
change.
|
1413
|
+
|
1414
|
+
To release a new version:
|
1415
|
+
|
1416
|
+
1. Create a Merge Request.
|
1417
|
+
1. Use Merge Request template [Release.md](https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/blob/master/.gitlab/merge_request_templates/Release.md).
|
1418
|
+
1. Follow the instructions.
|
1419
|
+
1. After the Merge Request has been merged, a new gem version is [published automatically](https://gitlab.com/gitlab-org/quality/pipeline-common/-/blob/master/ci/gem-release.yml)
|
@@ -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'
|
@@ -55,7 +57,6 @@ module Gitlab
|
|
55
57
|
|
56
58
|
assert_all!
|
57
59
|
assert_project_id!
|
58
|
-
assert_token!
|
59
60
|
require_ruby_files
|
60
61
|
end
|
61
62
|
|
@@ -99,12 +100,6 @@ module Gitlab
|
|
99
100
|
raise ArgumentError, 'A project_id is needed (pass it with the `--source-id` option)!'
|
100
101
|
end
|
101
102
|
|
102
|
-
def assert_token!
|
103
|
-
return if options.token
|
104
|
-
|
105
|
-
raise ArgumentError, 'A token is needed (pass it with the `--token` option)!'
|
106
|
-
end
|
107
|
-
|
108
103
|
def assert_all!
|
109
104
|
raise ArgumentError, '--all-projects option cannot be used in conjunction with --source and --source-id option!' if
|
110
105
|
options.all && (options.source || options.source_id)
|
@@ -333,17 +328,27 @@ module Gitlab
|
|
333
328
|
puts
|
334
329
|
end
|
335
330
|
|
336
|
-
def filter_resources(resources, conditions)
|
331
|
+
def filter_resources(resources, conditions) # rubocop:disable Metrics/CyclomaticComplexity
|
337
332
|
resources.select do |resource|
|
338
333
|
results = []
|
339
334
|
|
340
335
|
# rubocop:disable Style/IfUnlessModifier
|
341
336
|
if conditions[:date]
|
342
|
-
|
337
|
+
case resource[:type]
|
338
|
+
when 'branches'
|
339
|
+
results << Filters::BranchDateFilter.new(resource, conditions[:date]).calculate
|
340
|
+
when 'merge_requests'
|
341
|
+
results << Filters::MergeRequestDateConditionsFilter.new(resource, conditions[:date]).calculate
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
if resource[:type] == 'branches'
|
346
|
+
results << Filters::BranchProtectedFilter.new(resource, conditions[:protected]).calculate
|
343
347
|
end
|
344
348
|
|
345
|
-
|
346
|
-
|
349
|
+
votes_condition = conditions[:votes] || conditions[:upvotes]
|
350
|
+
if votes_condition
|
351
|
+
results << Filters::VotesConditionsFilter.new(resource, votes_condition).calculate
|
347
352
|
end
|
348
353
|
|
349
354
|
if conditions[:no_additional_labels]
|
@@ -402,7 +407,7 @@ module Gitlab
|
|
402
407
|
|
403
408
|
condition_builders << milestone_condition_builder(resource_type, conditions[:milestone]) if conditions[:milestone]
|
404
409
|
|
405
|
-
if conditions[:date] && APIQueryBuilders::DateQueryParamBuilder.applicable?(conditions[:date])
|
410
|
+
if conditions[:date] && APIQueryBuilders::DateQueryParamBuilder.applicable?(conditions[:date]) && resource_type&.to_sym != :branches
|
406
411
|
condition_builders << APIQueryBuilders::DateQueryParamBuilder.new(conditions.delete(:date))
|
407
412
|
end
|
408
413
|
|
@@ -411,6 +416,8 @@ module Gitlab
|
|
411
416
|
condition_builders.concat(issues_resource_query(conditions))
|
412
417
|
when :merge_requests
|
413
418
|
condition_builders.concat(merge_requests_resource_query(conditions))
|
419
|
+
when :branches
|
420
|
+
condition_builders.concat(branches_resource_query(conditions))
|
414
421
|
end
|
415
422
|
|
416
423
|
condition_builders.compact.each do |condition_builder|
|
@@ -468,6 +475,12 @@ module Gitlab
|
|
468
475
|
end
|
469
476
|
end
|
470
477
|
|
478
|
+
def branches_resource_query(conditions)
|
479
|
+
[].tap do |condition_builders|
|
480
|
+
condition_builders << APIQueryBuilders::SingleQueryParamBuilder.new('search', conditions[:name]) if conditions[:name]
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
471
484
|
def draft_condition_builder(draft_condittion)
|
472
485
|
# Issues API only accepts 'yes' and 'no' as strings: https://docs.gitlab.com/ee/api/merge_requests.html
|
473
486
|
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
|
@@ -54,6 +54,10 @@ module Gitlab
|
|
54
54
|
}
|
55
55
|
GRAPHQL
|
56
56
|
|
57
|
+
def vote_attribute
|
58
|
+
@vote_attribute ||= (conditions.dig(:votes, :attribute) || conditions.dig(:upvotes, :attribute)).to_s
|
59
|
+
end
|
60
|
+
|
57
61
|
def resource_fields
|
58
62
|
fields = []
|
59
63
|
|
@@ -64,8 +68,8 @@ module Gitlab
|
|
64
68
|
fields << 'labels { nodes { title } }'
|
65
69
|
fields << 'author { id name username }'
|
66
70
|
fields << 'assignees { nodes { id name username } }' if conditions.key?(:assignee_member)
|
67
|
-
fields << 'upvotes' if
|
68
|
-
fields << 'downvotes' if
|
71
|
+
fields << 'upvotes' if vote_attribute == 'upvotes'
|
72
|
+
fields << 'downvotes' if vote_attribute == 'downvotes'
|
69
73
|
fields.push('draft', 'mergedAt') if resource_type == 'merge_requests'
|
70
74
|
end
|
71
75
|
|
@@ -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)
|
@@ -8,6 +8,7 @@ module Gitlab
|
|
8
8
|
module Triage
|
9
9
|
class OptionParser
|
10
10
|
class << self
|
11
|
+
# rubocop:disable Metrics/AbcSize
|
11
12
|
def parse(argv)
|
12
13
|
options = Options.new
|
13
14
|
options.host_url = 'https://gitlab.com'
|
@@ -89,9 +90,11 @@ module Gitlab
|
|
89
90
|
parser.parse!(argv)
|
90
91
|
|
91
92
|
options.source = nil if options.all
|
93
|
+
options.token ||= ''
|
92
94
|
|
93
95
|
options
|
94
96
|
end
|
97
|
+
# rubocop:enable Metrics/AbcSize
|
95
98
|
end
|
96
99
|
end
|
97
100
|
end
|
@@ -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
|
@@ -9,6 +9,18 @@ module Gitlab
|
|
9
9
|
class Issue < Base
|
10
10
|
include Shared::Issuable
|
11
11
|
|
12
|
+
DATE_FIELDS = %i[
|
13
|
+
due_date
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
DATE_FIELDS.each do |field|
|
17
|
+
define_field(field) do
|
18
|
+
value = resource[field]
|
19
|
+
|
20
|
+
Date.parse(value) if value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
def merge_requests_count
|
13
25
|
@merge_requests_count ||= resource.dig(:merge_requests_count)
|
14
26
|
end
|
@@ -30,6 +42,10 @@ module Gitlab
|
|
30
42
|
resource_url(sub_resource_type: 'links'))
|
31
43
|
.map { |issue| LinkedIssue.new(issue, parent: self) }
|
32
44
|
end
|
45
|
+
|
46
|
+
def expired?(today = Date.today)
|
47
|
+
due_date && due_date < today
|
48
|
+
end
|
33
49
|
end
|
34
50
|
end
|
35
51
|
end
|
@@ -10,7 +10,6 @@ module Gitlab
|
|
10
10
|
class RestAPINetwork
|
11
11
|
include Retryable
|
12
12
|
|
13
|
-
TokenNotFound = Class.new(StandardError)
|
14
13
|
MINIMUM_RATE_LIMIT = 25
|
15
14
|
|
16
15
|
attr_reader :options, :adapter
|
@@ -85,10 +84,25 @@ module Gitlab
|
|
85
84
|
{}
|
86
85
|
end
|
87
86
|
|
87
|
+
def delete_api(url)
|
88
|
+
response = execute_with_retry(
|
89
|
+
exception_types: Net::ReadTimeout,
|
90
|
+
backoff_exceptions: Errors::Network::TooManyRequests) do
|
91
|
+
puts Gitlab::Triage::UI.debug "delete_api: #{url}" if options.debug
|
92
|
+
|
93
|
+
@adapter.delete(token, url)
|
94
|
+
end
|
95
|
+
|
96
|
+
rate_limit_debug(response) if options.debug
|
97
|
+
rate_limit_wait(response)
|
98
|
+
rescue Net::ReadTimeout
|
99
|
+
{}
|
100
|
+
end
|
101
|
+
|
88
102
|
private
|
89
103
|
|
90
104
|
def token
|
91
|
-
options.token
|
105
|
+
options.token
|
92
106
|
end
|
93
107
|
|
94
108
|
def rate_limit_debug(response)
|
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.26.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-11-24 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
|