gitlab-triage 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab/CODEOWNERS +2 -0
- data/README.md +78 -1
- data/lib/gitlab/triage/action/comment.rb +5 -3
- data/lib/gitlab/triage/action/summarize/issue_builder.rb +55 -0
- data/lib/gitlab/triage/action/summarize.rb +60 -0
- data/lib/gitlab/triage/action.rb +4 -1
- data/lib/gitlab/triage/command_builders/{comment_body_builder.rb → text_content_builder.rb} +7 -2
- data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +1 -1
- data/lib/gitlab/triage/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29ce6bb293cf3eb96b5c9f11179351472211bc15014fa365235013930ea8e951
|
4
|
+
data.tar.gz: '039d533aace6b86fd0518259e0dc2a5dc73a3b49a5ee87a55b6e4a4fa256fd52'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06273cdd4019d0619648b3b7b0ef8dfaa93f37fd152945faad44f92e119bcedc30c6db8235e5f8ba5c6a7126b1137a0cbad5920efe91bb732b4cb7f0d7899df2
|
7
|
+
data.tar.gz: c0a6940c1eb46580b77a1c0addbb2f6e19bcc69bc36f0bab34de6d36072cfa1111438cbdd057798a803e8bf252dd1acf26395c8e1095fdb57cd0ebc59f44d490
|
data/.gitlab/CODEOWNERS
ADDED
data/README.md
CHANGED
@@ -55,6 +55,18 @@ resource_rules:
|
|
55
55
|
- markglenfletcher
|
56
56
|
comment: |
|
57
57
|
{{author}} This issue is unlabelled after 5 days. It needs attention. Please take care of this before the end of #{2.days.from_now.strftime('%Y-%m-%d')}
|
58
|
+
summarize:
|
59
|
+
title: Issues require labels
|
60
|
+
item: |
|
61
|
+
- [ ] [{{title}}]({{web_url}}) {{labels}}
|
62
|
+
summary: |
|
63
|
+
The following issues require labels:
|
64
|
+
|
65
|
+
{{items}}
|
66
|
+
|
67
|
+
Please take care of them before the end of #{7.days.from_now.strftime('%Y-%m-%d')}
|
68
|
+
|
69
|
+
/label ~"needs attention"
|
58
70
|
merge_requests:
|
59
71
|
rules:
|
60
72
|
[]
|
@@ -395,6 +407,7 @@ Available action types:
|
|
395
407
|
- [`status` action](#status-action)
|
396
408
|
- [`mention` action](#mention-action)
|
397
409
|
- [`comment` action](#comment-action)
|
410
|
+
- [`summarize` action](#summarize-action)
|
398
411
|
|
399
412
|
##### Labels action
|
400
413
|
|
@@ -482,6 +495,8 @@ The following placeholders are supported:
|
|
482
495
|
- `labels`: the resource's labels as `~label1, ~label2`
|
483
496
|
- `upvotes`: the resources's upvotes count
|
484
497
|
- `downvotes`: the resources's downvotes count
|
498
|
+
- `title`: the resource's title
|
499
|
+
- `web_url`: the web URL pointing to the resource
|
485
500
|
|
486
501
|
If the resource doesn't respond to the placeholder, or if the field is `nil`,
|
487
502
|
the placeholder is not replaced.
|
@@ -499,7 +514,7 @@ Example with placeholders:
|
|
499
514
|
```yml
|
500
515
|
actions:
|
501
516
|
comment: |
|
502
|
-
|
517
|
+
{{author}} Are you still interested in finishing this merge request?
|
503
518
|
```
|
504
519
|
|
505
520
|
###### Ruby expression
|
@@ -527,6 +542,68 @@ actions:
|
|
527
542
|
If \} comes first and/or following \{, you'll need to escape them. If it's just { wrapping something } then you don't need to, but it's also fine to escape them like \{ this \} if you prefer.
|
528
543
|
```
|
529
544
|
|
545
|
+
##### Summarize action
|
546
|
+
|
547
|
+
Generates an issue summarizing what was triaged.
|
548
|
+
|
549
|
+
Accepts a hash of fields.
|
550
|
+
|
551
|
+
| Field | Type | Description | Required | Placeholders | Ruby expression |
|
552
|
+
| ---- | ---- | ---- | ---- | ---- | ---- |
|
553
|
+
| `title` | string | The title of the generated issue | yes | no | no |
|
554
|
+
| `item` | string | Template representing each triaged resource | no | yes | yes |
|
555
|
+
| `summary` | string | The description of the generated issue | no | Only `{{items}}` and `{{title}}` | yes |
|
556
|
+
|
557
|
+
**Note:**: Both `item` and `summary` fields act like a
|
558
|
+
[comment action](#comment-action), therefore
|
559
|
+
[Ruby expression](#ruby-expression) is supported.
|
560
|
+
Placeholders work regularly for `item`, but for `summary` only
|
561
|
+
`{{items}}` and `{{title}}` are supported because it's not tied to a
|
562
|
+
particular resource like the comment action.
|
563
|
+
|
564
|
+
The following placeholders are supported for `summary`:
|
565
|
+
|
566
|
+
- `items`: Concatenated markdown separated by a newline for each `item`
|
567
|
+
- `title`: The title of the generated issue
|
568
|
+
|
569
|
+
Example:
|
570
|
+
|
571
|
+
```yml
|
572
|
+
limits:
|
573
|
+
most_recent: 15
|
574
|
+
actions:
|
575
|
+
summarize:
|
576
|
+
title: Issues require labels
|
577
|
+
item: |
|
578
|
+
- [ ] [{{title}}]({{web_url}}) {{labels}}
|
579
|
+
summary: |
|
580
|
+
The following issues require labels:
|
581
|
+
|
582
|
+
{{items}}
|
583
|
+
|
584
|
+
Please take care of them before the end of #{7.days.from_now.strftime('%Y-%m-%d')}
|
585
|
+
|
586
|
+
/label ~"needs attention"
|
587
|
+
```
|
588
|
+
|
589
|
+
Which could generate an issue like:
|
590
|
+
|
591
|
+
* Title:
|
592
|
+
```
|
593
|
+
Issues require labels
|
594
|
+
```
|
595
|
+
* Description:
|
596
|
+
``` markdown
|
597
|
+
The following issues require labels:
|
598
|
+
|
599
|
+
- [ ] [An example issue](http://example.com/group/project/issues/1) ~"label A", ~"label B"
|
600
|
+
- [ ] [Another issue](http://example.com/group/project/issues/2) ~"label B", ~"label C"
|
601
|
+
|
602
|
+
Please take care of them before the end of 2000-01-01
|
603
|
+
|
604
|
+
/label ~"needs attention"
|
605
|
+
```
|
606
|
+
|
530
607
|
### Ruby expression API
|
531
608
|
|
532
609
|
Here's a list of currently available Ruby expression API:
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'base'
|
2
|
-
require_relative '../command_builders/
|
4
|
+
require_relative '../command_builders/text_content_builder'
|
3
5
|
require_relative '../command_builders/comment_command_builder'
|
4
6
|
require_relative '../command_builders/label_command_builder'
|
5
7
|
require_relative '../command_builders/remove_label_command_builder'
|
@@ -37,7 +39,7 @@ module Gitlab
|
|
37
39
|
def build_comment(resource)
|
38
40
|
CommandBuilders::CommentCommandBuilder.new(
|
39
41
|
[
|
40
|
-
CommandBuilders::
|
42
|
+
CommandBuilders::TextContentBuilder.new(rule[:comment], resource: resource, net: net).build_command,
|
41
43
|
CommandBuilders::LabelCommandBuilder.new(rule[:labels]).build_command,
|
42
44
|
CommandBuilders::RemoveLabelCommandBuilder.new(rule[:remove_labels]).build_command,
|
43
45
|
CommandBuilders::CcCommandBuilder.new(rule[:mention]).build_command,
|
@@ -50,7 +52,7 @@ module Gitlab
|
|
50
52
|
net[:network].post_api(
|
51
53
|
net[:token],
|
52
54
|
build_post_url(resource),
|
53
|
-
comment)
|
55
|
+
body: comment)
|
54
56
|
end
|
55
57
|
|
56
58
|
def build_post_url(resource)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../base'
|
4
|
+
require_relative '../../command_builders/text_content_builder'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Triage
|
8
|
+
module Action
|
9
|
+
class IssueBuilder
|
10
|
+
attr_reader :title
|
11
|
+
|
12
|
+
def initialize(action, resources, net)
|
13
|
+
@title = action[:title]
|
14
|
+
@item_template = action[:item]
|
15
|
+
@summary_template = action[:summary]
|
16
|
+
@resources = resources
|
17
|
+
@net = net
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
return '' unless @summary_template
|
22
|
+
|
23
|
+
@description ||= CommandBuilders::TextContentBuilder.new(
|
24
|
+
@summary_template, resource: summary_resource, net: @net)
|
25
|
+
.build_command
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid?
|
29
|
+
title =~ /\S+/
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def summary_resource
|
35
|
+
@summary_resource ||= {
|
36
|
+
'items' => items,
|
37
|
+
'title' => title
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def items
|
42
|
+
return '' unless @item_template
|
43
|
+
|
44
|
+
@items ||= @resources.map(&method(:build_item)).join("\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_item(resource)
|
48
|
+
CommandBuilders::TextContentBuilder.new(
|
49
|
+
@item_template, resource: resource, net: @net)
|
50
|
+
.build_command.chomp
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative 'summarize/issue_builder'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Triage
|
8
|
+
module Action
|
9
|
+
class Summarize < Base
|
10
|
+
class Dry < Summarize
|
11
|
+
private
|
12
|
+
|
13
|
+
def perform
|
14
|
+
puts "\nThe following issue would be created for the rule **#{name}**:\n\n"
|
15
|
+
puts ">>>"
|
16
|
+
puts "* Title: #{issue.title}"
|
17
|
+
puts "* Description: #{issue.description}"
|
18
|
+
puts ">>>"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def act
|
23
|
+
perform if resources.any? && issue.valid?
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def perform
|
29
|
+
net[:network].post_api(net[:token], post_issue_url, post_issue_body)
|
30
|
+
end
|
31
|
+
|
32
|
+
def issue
|
33
|
+
@issue ||= IssueBuilder.new(rule, resources, net)
|
34
|
+
end
|
35
|
+
|
36
|
+
def post_issue_url
|
37
|
+
# POST /projects/:id/issues
|
38
|
+
# https://docs.gitlab.com/ee/api/issues.html#new-issue
|
39
|
+
post_url = UrlBuilders::UrlBuilder.new(
|
40
|
+
host_url: net[:host_url],
|
41
|
+
api_version: net[:api_version],
|
42
|
+
source_id: net[:source_id],
|
43
|
+
resource_type: 'issues'
|
44
|
+
).build
|
45
|
+
|
46
|
+
puts Gitlab::Triage::UI.debug "post_issue_url: #{post_url}" if net[:debug]
|
47
|
+
|
48
|
+
post_url
|
49
|
+
end
|
50
|
+
|
51
|
+
def post_issue_body
|
52
|
+
{
|
53
|
+
title: issue.title,
|
54
|
+
description: issue.description
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/gitlab/triage/action.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
|
+
require_relative 'action/summarize'
|
1
2
|
require_relative 'action/comment'
|
2
3
|
|
3
4
|
module Gitlab
|
4
5
|
module Triage
|
5
6
|
module Action
|
6
7
|
def self.process(rules:, **args)
|
8
|
+
summarize = rules.delete(:summarize)
|
7
9
|
comment = rules.any? && rules
|
8
10
|
|
9
11
|
{
|
12
|
+
Summarize => summarize,
|
10
13
|
Comment => comment
|
11
14
|
}.compact.each do |action, rule|
|
12
|
-
act(action: action, rule: rule, **args)
|
15
|
+
act(action: action, rule: rule, **args) if rule
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_support/core_ext/array/wrap'
|
4
|
+
|
3
5
|
require_relative 'base_command_builder'
|
4
6
|
require_relative '../resource/context'
|
5
7
|
|
6
8
|
module Gitlab
|
7
9
|
module Triage
|
8
10
|
module CommandBuilders
|
9
|
-
class
|
11
|
+
class TextContentBuilder < BaseCommandBuilder
|
10
12
|
SUPPORTED_PLACEHOLDERS = {
|
11
13
|
created_at: "{{created_at}}",
|
12
14
|
updated_at: "{{updated_at}}",
|
@@ -21,7 +23,10 @@ module Gitlab
|
|
21
23
|
milestone: %(%"{{milestone.title}}"),
|
22
24
|
labels: %(~"{{labels}}"),
|
23
25
|
upvotes: "{{upvotes}}",
|
24
|
-
downvotes: "{{downvotes}}"
|
26
|
+
downvotes: "{{downvotes}}",
|
27
|
+
title: "{{title}}",
|
28
|
+
web_url: "{{web_url}}",
|
29
|
+
items: "{{items}}"
|
25
30
|
}.freeze
|
26
31
|
PLACEHOLDER_REGEX = /{{([\w\.]+)}}/
|
27
32
|
|
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: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- ".codeclimate.yml"
|
120
120
|
- ".gitignore"
|
121
121
|
- ".gitlab-ci.yml"
|
122
|
+
- ".gitlab/CODEOWNERS"
|
122
123
|
- ".gitlab/issue_templates/Policy.md"
|
123
124
|
- ".rubocop.yml"
|
124
125
|
- ".triage-policies.yml"
|
@@ -134,16 +135,18 @@ files:
|
|
134
135
|
- lib/gitlab/triage/action.rb
|
135
136
|
- lib/gitlab/triage/action/base.rb
|
136
137
|
- lib/gitlab/triage/action/comment.rb
|
138
|
+
- lib/gitlab/triage/action/summarize.rb
|
139
|
+
- lib/gitlab/triage/action/summarize/issue_builder.rb
|
137
140
|
- lib/gitlab/triage/api_query_builders/base_query_param_builder.rb
|
138
141
|
- lib/gitlab/triage/api_query_builders/multi_query_param_builder.rb
|
139
142
|
- lib/gitlab/triage/api_query_builders/single_query_param_builder.rb
|
140
143
|
- lib/gitlab/triage/command_builders/base_command_builder.rb
|
141
144
|
- lib/gitlab/triage/command_builders/cc_command_builder.rb
|
142
|
-
- lib/gitlab/triage/command_builders/comment_body_builder.rb
|
143
145
|
- lib/gitlab/triage/command_builders/comment_command_builder.rb
|
144
146
|
- lib/gitlab/triage/command_builders/label_command_builder.rb
|
145
147
|
- lib/gitlab/triage/command_builders/remove_label_command_builder.rb
|
146
148
|
- lib/gitlab/triage/command_builders/status_command_builder.rb
|
149
|
+
- lib/gitlab/triage/command_builders/text_content_builder.rb
|
147
150
|
- lib/gitlab/triage/engine.rb
|
148
151
|
- lib/gitlab/triage/expand_condition.rb
|
149
152
|
- lib/gitlab/triage/expand_condition/sequence.rb
|