gitlab-triage 1.53.0 → 1.54.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 +4 -4
- data/Gemfile +3 -0
- data/Gemfile.lock +10 -9
- data/README.md +159 -1
- data/gitlab-triage.gemspec +1 -2
- data/lib/gitlab/triage/action/base.rb +62 -0
- data/lib/gitlab/triage/action/comment.rb +1 -9
- data/lib/gitlab/triage/action/comment_on_summary.rb +0 -6
- data/lib/gitlab/triage/action/issue.rb +31 -3
- data/lib/gitlab/triage/action/summarize.rb +21 -1
- data/lib/gitlab/triage/action/update.rb +432 -0
- data/lib/gitlab/triage/action/work_item.rb +0 -27
- data/lib/gitlab/triage/action.rb +18 -2
- data/lib/gitlab/triage/command_builders/cc_command_builder.rb +0 -4
- data/lib/gitlab/triage/entity_builders/issue_builder.rb +8 -0
- data/lib/gitlab/triage/entity_builders/issue_fields.rb +52 -0
- data/lib/gitlab/triage/entity_builders/summary_builder.rb +8 -0
- data/lib/gitlab/triage/graphql_network.rb +12 -2
- data/lib/gitlab/triage/network.rb +4 -0
- data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +24 -0
- data/lib/gitlab/triage/network_adapters/test_adapter.rb +8 -0
- data/lib/gitlab/triage/policies/base_policy.rb +10 -2
- data/lib/gitlab/triage/policies/rule_policy.rb +18 -8
- data/lib/gitlab/triage/policies/summary_policy.rb +9 -0
- data/lib/gitlab/triage/rest_api_network.rb +22 -0
- data/lib/gitlab/triage/validators/policy_validator.rb +1 -3
- data/lib/gitlab/triage/version.rb +1 -1
- metadata +14 -10
- data/lib/gitlab/triage/command_builders/label_command_builder.rb +0 -42
- data/lib/gitlab/triage/command_builders/move_command_builder.rb +0 -21
- data/lib/gitlab/triage/command_builders/remove_label_command_builder.rb +0 -17
- data/lib/gitlab/triage/command_builders/status_command_builder.rb +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c2e36c5b7ecfbf719e3a7ac2282fc01d0e2f0af214eaeead7d60c913456090f8
|
|
4
|
+
data.tar.gz: 3da3785a4e850948e45ce922f6169a1dc9faa2d817eb3ebbd5285476c0290aee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e4b4c9e46c33d13f835e62e3c0638aa0663d4ab5f0ff9d64b0d404fb64cf738895cc1708346c92a8103cba4b41a089f7c746292baab3c46e04518ac09339aac9
|
|
7
|
+
data.tar.gz: cd9dd8c10b7381c41858c1f0de7a64205c87c79669e2e475e2748c40300536469369e05744545f5b55b2aed89d1384b329abaf733bbe4db837bb0a5f0d9732a5
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
gitlab-triage (1.
|
|
4
|
+
gitlab-triage (1.54.0)
|
|
5
5
|
activesupport (>= 5.1)
|
|
6
6
|
globalid (~> 1.0, >= 1.0.1)
|
|
7
7
|
graphql (< 2.1.0)
|
|
8
8
|
graphql-client (~> 0.16)
|
|
9
|
-
httparty (
|
|
9
|
+
httparty (>= 0.21.0, < 1.0)
|
|
10
10
|
|
|
11
11
|
GEM
|
|
12
12
|
remote: https://rubygems.org/
|
|
@@ -40,6 +40,7 @@ GEM
|
|
|
40
40
|
crack (1.0.0)
|
|
41
41
|
bigdecimal
|
|
42
42
|
rexml
|
|
43
|
+
csv (3.3.6)
|
|
43
44
|
danger (9.4.3)
|
|
44
45
|
claide (~> 1.0)
|
|
45
46
|
claide-plugins (>= 0.9.2)
|
|
@@ -57,7 +58,7 @@ GEM
|
|
|
57
58
|
danger
|
|
58
59
|
gitlab (~> 4.2, >= 4.2.0)
|
|
59
60
|
diff-lcs (1.5.1)
|
|
60
|
-
drb (2.2.
|
|
61
|
+
drb (2.2.3)
|
|
61
62
|
faraday (2.9.1)
|
|
62
63
|
faraday-net_http (>= 2.0, < 3.2)
|
|
63
64
|
faraday-http-cache (2.5.1)
|
|
@@ -104,8 +105,9 @@ GEM
|
|
|
104
105
|
guard-compat (~> 1.1)
|
|
105
106
|
rspec (>= 2.99.0, < 4.0)
|
|
106
107
|
hashdiff (1.1.0)
|
|
107
|
-
httparty (0.
|
|
108
|
-
|
|
108
|
+
httparty (0.24.2)
|
|
109
|
+
csv
|
|
110
|
+
mini_mime (>= 1.0.0)
|
|
109
111
|
multi_xml (>= 0.5.2)
|
|
110
112
|
i18n (1.14.5)
|
|
111
113
|
concurrent-ruby (~> 1.0)
|
|
@@ -121,10 +123,8 @@ GEM
|
|
|
121
123
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
122
124
|
lumberjack (1.2.10)
|
|
123
125
|
method_source (1.1.0)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
mime-types-data (3.2024.0305)
|
|
127
|
-
minitest (5.23.1)
|
|
126
|
+
mini_mime (1.1.5)
|
|
127
|
+
minitest (5.26.1)
|
|
128
128
|
multi_xml (0.6.0)
|
|
129
129
|
mutex_m (0.2.0)
|
|
130
130
|
nap (1.1.0)
|
|
@@ -230,6 +230,7 @@ DEPENDENCIES
|
|
|
230
230
|
gitlab-triage!
|
|
231
231
|
guard-rspec (~> 4.7.3)
|
|
232
232
|
lefthook (~> 1.3)
|
|
233
|
+
minitest (= 5.26.1)
|
|
233
234
|
rake (~> 13.2)
|
|
234
235
|
rspec (~> 3.8)
|
|
235
236
|
webmock (~> 3.4)
|
data/README.md
CHANGED
|
@@ -903,6 +903,15 @@ Used to declare an action to be carried out on a resource if **all** conditions
|
|
|
903
903
|
Available action types:
|
|
904
904
|
- [`labels` action](#labels-action)
|
|
905
905
|
- [`remove_labels` action](#remove-labels-action)
|
|
906
|
+
- [`assignees` action](#assignees-action)
|
|
907
|
+
- [`reviewers` action](#reviewers-action)
|
|
908
|
+
- [`remove_assignees` and `remove_reviewers` actions](#remove-assignees-and-remove-reviewers-actions)
|
|
909
|
+
- [`milestone` action](#milestone-action)
|
|
910
|
+
- [`due_date` action](#due-date-action)
|
|
911
|
+
- [`weight` action](#weight-action)
|
|
912
|
+
- [`health_status` action](#health-status-action)
|
|
913
|
+
- [`title` action](#title-action)
|
|
914
|
+
- [`discussion_locked` action](#discussion-locked-action)
|
|
906
915
|
- [`status` action](#status-action)
|
|
907
916
|
- [`work_item_status` action](#work-item-status-action)
|
|
908
917
|
- [`mention` action](#mention-action)
|
|
@@ -934,6 +943,16 @@ actions:
|
|
|
934
943
|
- awaiting feedback
|
|
935
944
|
```
|
|
936
945
|
|
|
946
|
+
Each entry supports Ruby string interpolation. An entry that interpolates to an
|
|
947
|
+
empty string is dropped, so a label can be made conditional on the resource:
|
|
948
|
+
|
|
949
|
+
```yml
|
|
950
|
+
actions:
|
|
951
|
+
labels:
|
|
952
|
+
- Community contribution
|
|
953
|
+
- "#{'1st contribution' if first_contribution?}"
|
|
954
|
+
```
|
|
955
|
+
|
|
937
956
|
##### Remove labels action
|
|
938
957
|
|
|
939
958
|
Removes a number of labels from the resource.
|
|
@@ -953,6 +972,142 @@ actions:
|
|
|
953
972
|
- awaiting feedback
|
|
954
973
|
```
|
|
955
974
|
|
|
975
|
+
##### Assignees action
|
|
976
|
+
|
|
977
|
+
Sets the assignees on the resource. Applies to issues and merge requests.
|
|
978
|
+
|
|
979
|
+
Accepts an array of usernames (without the leading `@`). If any username does not exist, the automation stops immediately.
|
|
980
|
+
|
|
981
|
+
Setting an empty array (`[]`) removes all assignees.
|
|
982
|
+
|
|
983
|
+
Example:
|
|
984
|
+
|
|
985
|
+
```yml
|
|
986
|
+
actions:
|
|
987
|
+
assignees:
|
|
988
|
+
- username1
|
|
989
|
+
- username2
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
##### Reviewers action
|
|
993
|
+
|
|
994
|
+
Sets the reviewers on the resource. Applies to merge requests only.
|
|
995
|
+
|
|
996
|
+
Accepts an array of usernames (without the leading `@`). If any username does not exist, the automation stops immediately.
|
|
997
|
+
|
|
998
|
+
Setting an empty array (`[]`) removes all reviewers.
|
|
999
|
+
|
|
1000
|
+
Example:
|
|
1001
|
+
|
|
1002
|
+
```yml
|
|
1003
|
+
actions:
|
|
1004
|
+
reviewers:
|
|
1005
|
+
- username1
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
Both actions replace the whole list rather than adding to it, and both support Ruby string interpolation in each entry. An entry that interpolates to a comma-separated list is expanded, so a policy can compute the list from the resource.
|
|
1009
|
+
|
|
1010
|
+
Entries that interpolate to nothing are dropped. If every entry drops out, the action is skipped rather than clearing the list, so a conditional assignee cannot unassign by accident. Only a literal `[]` clears.
|
|
1011
|
+
|
|
1012
|
+
##### Remove assignees and remove reviewers actions
|
|
1013
|
+
|
|
1014
|
+
Removes the named users and keeps the rest. `remove_assignees` applies to issues and merge requests, `remove_reviewers` to merge requests only.
|
|
1015
|
+
|
|
1016
|
+
Accepts an array of usernames (without the leading `@`), with the same interpolation and comma expansion as the actions above. Names that are not on the resource are ignored, and a resource with nobody assigned is left alone.
|
|
1017
|
+
|
|
1018
|
+
Example:
|
|
1019
|
+
|
|
1020
|
+
```yml
|
|
1021
|
+
actions:
|
|
1022
|
+
remove_reviewers:
|
|
1023
|
+
- some-bot
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
Prefer these over computing the surviving list yourself: they read the ids straight off the resource, so they cost no extra API call and cannot clear the list by accident.
|
|
1027
|
+
|
|
1028
|
+
##### Milestone action
|
|
1029
|
+
|
|
1030
|
+
Sets the milestone on the resource. Applies to issues and merge requests.
|
|
1031
|
+
|
|
1032
|
+
Accepts a string containing the milestone title. If the milestone does not exist, the automation stops immediately.
|
|
1033
|
+
|
|
1034
|
+
Supports Ruby string interpolation in the value.
|
|
1035
|
+
|
|
1036
|
+
Example:
|
|
1037
|
+
|
|
1038
|
+
```yml
|
|
1039
|
+
actions:
|
|
1040
|
+
milestone: "17.0"
|
|
1041
|
+
```
|
|
1042
|
+
|
|
1043
|
+
##### Due date action
|
|
1044
|
+
|
|
1045
|
+
Sets the due date on the resource. Applies to issues only. The epics endpoint takes `due_date_fixed` and `due_date_is_fixed` instead, and merge requests have no due date.
|
|
1046
|
+
|
|
1047
|
+
Accepts a string in `YYYY-MM-DD` format. Supports Ruby string interpolation.
|
|
1048
|
+
|
|
1049
|
+
Example:
|
|
1050
|
+
|
|
1051
|
+
```yml
|
|
1052
|
+
actions:
|
|
1053
|
+
due_date: "#{(Date.today + 7).iso8601}"
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
##### Weight action
|
|
1057
|
+
|
|
1058
|
+
Sets the weight on an issue. Issues only.
|
|
1059
|
+
|
|
1060
|
+
Accepts an integer, or `~` (YAML null) to clear the weight.
|
|
1061
|
+
|
|
1062
|
+
Example:
|
|
1063
|
+
|
|
1064
|
+
```yml
|
|
1065
|
+
actions:
|
|
1066
|
+
weight: 3
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
##### Health status action
|
|
1070
|
+
|
|
1071
|
+
Sets the health status on an issue. Issues only.
|
|
1072
|
+
|
|
1073
|
+
Accepts one of `on_track`, `needs_attention`, or `at_risk`, or `~` (YAML null) to clear it.
|
|
1074
|
+
|
|
1075
|
+
This one goes through the work item GraphQL API, because the REST issue update
|
|
1076
|
+
endpoint does not accept a health status parameter.
|
|
1077
|
+
|
|
1078
|
+
Example:
|
|
1079
|
+
|
|
1080
|
+
```yml
|
|
1081
|
+
actions:
|
|
1082
|
+
health_status: needs_attention
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
##### Title action
|
|
1086
|
+
|
|
1087
|
+
Updates the title of the resource.
|
|
1088
|
+
|
|
1089
|
+
Accepts a string. Supports Ruby string interpolation.
|
|
1090
|
+
|
|
1091
|
+
Example:
|
|
1092
|
+
|
|
1093
|
+
```yml
|
|
1094
|
+
actions:
|
|
1095
|
+
title: "#{resource[:title]} [archived]"
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
##### Discussion locked action
|
|
1099
|
+
|
|
1100
|
+
Locks or unlocks discussions on the resource. Applies to issues and merge requests.
|
|
1101
|
+
|
|
1102
|
+
Accepts `true` or `false`.
|
|
1103
|
+
|
|
1104
|
+
Example:
|
|
1105
|
+
|
|
1106
|
+
```yml
|
|
1107
|
+
actions:
|
|
1108
|
+
discussion_locked: true
|
|
1109
|
+
```
|
|
1110
|
+
|
|
956
1111
|
##### Status action
|
|
957
1112
|
|
|
958
1113
|
Changes the open or closed state of the resource.
|
|
@@ -999,7 +1154,7 @@ actions:
|
|
|
999
1154
|
|
|
1000
1155
|
##### Mention action
|
|
1001
1156
|
|
|
1002
|
-
Mentions a number of users.
|
|
1157
|
+
Mentions a number of users. The usernames are appended to the comment body as `@username` references. Prior to 1.54.0 they were emitted as `/cc @username`; the mention effect is identical but the rendered text differs.
|
|
1003
1158
|
|
|
1004
1159
|
Accepts an array of strings. Each element is the username of a user to mention.
|
|
1005
1160
|
|
|
@@ -1018,6 +1173,9 @@ Moves an issue (merge request is not supported yet) to the specified project.
|
|
|
1018
1173
|
|
|
1019
1174
|
Accepts a string containing the target project path.
|
|
1020
1175
|
|
|
1176
|
+
When combined with other update actions, the move runs last, because it gives the
|
|
1177
|
+
issue a new internal ID at the destination.
|
|
1178
|
+
|
|
1021
1179
|
Example:
|
|
1022
1180
|
|
|
1023
1181
|
```yml
|
data/gitlab-triage.gemspec
CHANGED
|
@@ -40,8 +40,7 @@ Gem::Specification.new do |spec|
|
|
|
40
40
|
# see: https://github.com/github/graphql-client/pull/314
|
|
41
41
|
# We can remove this check once PR 314 is merged and released
|
|
42
42
|
spec.add_dependency 'graphql', '< 2.1.0'
|
|
43
|
-
|
|
44
|
-
spec.add_dependency 'httparty', '~> 0.20.0'
|
|
43
|
+
spec.add_dependency 'httparty', '>= 0.21.0', '< 1.0'
|
|
45
44
|
|
|
46
45
|
spec.add_development_dependency 'gitlab-dangerfiles', '~> 2.11.0'
|
|
47
46
|
spec.add_development_dependency 'gitlab-styles', '~> 12.0'
|
|
@@ -1,15 +1,77 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'cgi'
|
|
4
|
+
|
|
5
|
+
require_relative '../url_builders/url_builder'
|
|
6
|
+
require_relative '../resource/label'
|
|
7
|
+
|
|
3
8
|
module Gitlab
|
|
4
9
|
module Triage
|
|
5
10
|
module Action
|
|
6
11
|
class Base
|
|
12
|
+
AssigneeDoesntExistError = Class.new(StandardError)
|
|
13
|
+
MilestoneDoesntExistError = Class.new(StandardError)
|
|
14
|
+
|
|
7
15
|
attr_reader :policy, :network
|
|
8
16
|
|
|
9
17
|
def initialize(**args)
|
|
10
18
|
@policy = args[:policy]
|
|
11
19
|
@network = args[:network]
|
|
12
20
|
end
|
|
21
|
+
|
|
22
|
+
# Action.process calls this on every active action before any of them
|
|
23
|
+
# writes. Actions with nothing to look up have nothing to check.
|
|
24
|
+
def verify!; end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def ensure_labels_exist!(labels, source_id, source_id_key: :project_id)
|
|
29
|
+
labels.each do |label|
|
|
30
|
+
label_opts = { source_id_key => source_id, name: label }
|
|
31
|
+
next if Resource::Label.new(label_opts, network: network).exist?
|
|
32
|
+
|
|
33
|
+
raise Resource::Label::LabelDoesntExistError, "Label `#{label}` doesn't exist!"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def resolve_user_ids(usernames, error_class = AssigneeDoesntExistError)
|
|
38
|
+
Array(usernames).map do |username|
|
|
39
|
+
id = resolve_user_id(username)
|
|
40
|
+
raise error_class, "User `#{username}` doesn't exist!" unless id
|
|
41
|
+
|
|
42
|
+
id
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
alias_method :resolve_assignee_ids, :resolve_user_ids
|
|
46
|
+
|
|
47
|
+
def resolve_user_id(username)
|
|
48
|
+
users = network.query_api_cached(users_url(username))
|
|
49
|
+
users.first&.dig(:id)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def users_url(username)
|
|
53
|
+
opts = network.options
|
|
54
|
+
"#{opts.host_url}/api/#{opts.api_version}/users?username=#{CGI.escape(username)}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# include_ancestors matches the /milestone quick action, which also resolves
|
|
58
|
+
# milestones defined on a parent group.
|
|
59
|
+
def milestones_url(source_id, title, source: 'projects')
|
|
60
|
+
UrlBuilders::UrlBuilder.new(
|
|
61
|
+
network_options: network.options,
|
|
62
|
+
source: source,
|
|
63
|
+
source_id: source_id,
|
|
64
|
+
resource_type: 'milestones',
|
|
65
|
+
params: { title: title, include_ancestors: true }
|
|
66
|
+
).build
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def resolve_milestone_id(source_id, title, source: 'projects')
|
|
70
|
+
milestone = network.query_api_cached(milestones_url(source_id, title, source: source)).first
|
|
71
|
+
raise MilestoneDoesntExistError, "Milestone `#{title}` doesn't exist!" unless milestone
|
|
72
|
+
|
|
73
|
+
milestone[:id]
|
|
74
|
+
end
|
|
13
75
|
end
|
|
14
76
|
end
|
|
15
77
|
end
|
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
require_relative 'base'
|
|
4
4
|
require_relative '../command_builders/text_content_builder'
|
|
5
5
|
require_relative '../command_builders/comment_command_builder'
|
|
6
|
-
require_relative '../command_builders/label_command_builder'
|
|
7
|
-
require_relative '../command_builders/remove_label_command_builder'
|
|
8
6
|
require_relative '../command_builders/cc_command_builder'
|
|
9
|
-
require_relative '../command_builders/status_command_builder'
|
|
10
|
-
require_relative '../command_builders/move_command_builder'
|
|
11
7
|
|
|
12
8
|
module Gitlab
|
|
13
9
|
module Triage
|
|
@@ -51,11 +47,7 @@ module Gitlab
|
|
|
51
47
|
network: network,
|
|
52
48
|
redact_confidentials: policy.actions.fetch(:redact_confidential_resources, true)
|
|
53
49
|
).build_command,
|
|
54
|
-
CommandBuilders::
|
|
55
|
-
CommandBuilders::RemoveLabelCommandBuilder.new(policy.actions[:remove_labels], resource: resource, network: network).build_command,
|
|
56
|
-
CommandBuilders::CcCommandBuilder.new(policy.actions[:mention]).build_command,
|
|
57
|
-
CommandBuilders::MoveCommandBuilder.new(policy.actions[:move]).build_command,
|
|
58
|
-
CommandBuilders::StatusCommandBuilder.new(policy.actions[:status]).build_command
|
|
50
|
+
CommandBuilders::CcCommandBuilder.new(policy.actions[:mention]).build_command
|
|
59
51
|
]
|
|
60
52
|
).build_command
|
|
61
53
|
end
|
|
@@ -2,12 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'base'
|
|
4
4
|
require_relative '../command_builders/text_content_builder'
|
|
5
|
-
require_relative '../command_builders/comment_command_builder'
|
|
6
|
-
require_relative '../command_builders/label_command_builder'
|
|
7
|
-
require_relative '../command_builders/remove_label_command_builder'
|
|
8
|
-
require_relative '../command_builders/cc_command_builder'
|
|
9
|
-
require_relative '../command_builders/status_command_builder'
|
|
10
|
-
require_relative '../command_builders/move_command_builder'
|
|
11
5
|
|
|
12
6
|
module Gitlab
|
|
13
7
|
module Triage
|
|
@@ -19,11 +19,30 @@ module Gitlab
|
|
|
19
19
|
puts ">>>"
|
|
20
20
|
puts "* Project: #{issue.destination || resource[policy.source_id_sym]}"
|
|
21
21
|
puts "* Title: #{issue.title}"
|
|
22
|
+
puts "* Labels: #{issue.labels.join(', ')}" if issue.labels.any?
|
|
23
|
+
puts "* Assignees: #{issue.assignee_usernames.join(', ')}" if issue.assignee_usernames&.any?
|
|
24
|
+
puts "* Due date: #{issue.due_date}" if issue.due_date
|
|
25
|
+
puts "* Milestone: #{issue.milestone_title}" if issue.milestone_title
|
|
22
26
|
puts "* Description: #{issue.description}"
|
|
23
27
|
puts ">>>"
|
|
24
28
|
end
|
|
25
29
|
end
|
|
26
30
|
|
|
31
|
+
# Resolving the assignees and milestone here too keeps a rule naming an
|
|
32
|
+
# unknown one from failing after Comment has already posted.
|
|
33
|
+
def verify!
|
|
34
|
+
policy.resources.each do |resource|
|
|
35
|
+
issue = policy.build_issue(resource)
|
|
36
|
+
next unless issue.valid?
|
|
37
|
+
|
|
38
|
+
destination_id = issue.destination || resource[policy.source_id_sym]
|
|
39
|
+
|
|
40
|
+
ensure_labels_exist!(issue.labels, destination_id)
|
|
41
|
+
resolve_assignee_ids(issue.assignee_usernames) if issue.assignee_usernames.any?
|
|
42
|
+
resolve_milestone_id(destination_id, issue.milestone_title) if issue.milestone_title
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
27
46
|
def act
|
|
28
47
|
policy.resources.each do |resource|
|
|
29
48
|
issue = policy.build_issue(resource)
|
|
@@ -35,7 +54,7 @@ module Gitlab
|
|
|
35
54
|
private
|
|
36
55
|
|
|
37
56
|
def perform(resource, issue)
|
|
38
|
-
network.post_api(build_post_url(resource, issue), post_issue_body(issue))
|
|
57
|
+
network.post_api(build_post_url(resource, issue), post_issue_body(resource, issue))
|
|
39
58
|
end
|
|
40
59
|
|
|
41
60
|
def build_post_url(resource, issue)
|
|
@@ -52,11 +71,20 @@ module Gitlab
|
|
|
52
71
|
post_url
|
|
53
72
|
end
|
|
54
73
|
|
|
55
|
-
def post_issue_body(issue)
|
|
56
|
-
|
|
74
|
+
def post_issue_body(resource, issue)
|
|
75
|
+
destination_id = issue.destination || resource[policy.source_id_sym]
|
|
76
|
+
|
|
77
|
+
body = {
|
|
57
78
|
title: issue.title,
|
|
58
79
|
description: issue.description
|
|
59
80
|
}
|
|
81
|
+
|
|
82
|
+
body[:labels] = issue.labels.join(',') if issue.labels.any?
|
|
83
|
+
body[:assignee_ids] = resolve_assignee_ids(issue.assignee_usernames) if issue.assignee_usernames.any?
|
|
84
|
+
body[:due_date] = issue.due_date if issue.due_date
|
|
85
|
+
body[:milestone_id] = resolve_milestone_id(destination_id, issue.milestone_title) if issue.milestone_title
|
|
86
|
+
|
|
87
|
+
body
|
|
60
88
|
end
|
|
61
89
|
end
|
|
62
90
|
end
|
|
@@ -27,11 +27,24 @@ module Gitlab
|
|
|
27
27
|
puts "The following issue would be created in project `#{destination}` for the rule **#{policy.name}**:\n\n"
|
|
28
28
|
puts ">>>"
|
|
29
29
|
puts "* Title: #{issue.title}"
|
|
30
|
+
puts "* Labels: #{issue.labels.join(', ')}" if issue.labels.any?
|
|
31
|
+
puts "* Assignees: #{issue.assignee_usernames.join(', ')}" if issue.assignee_usernames&.any?
|
|
32
|
+
puts "* Due date: #{issue.due_date}" if issue.due_date
|
|
33
|
+
puts "* Milestone: #{issue.milestone_title}" if issue.milestone_title
|
|
30
34
|
puts "* Description: #{issue.description}"
|
|
31
35
|
puts ">>>"
|
|
32
36
|
end
|
|
33
37
|
end
|
|
34
38
|
|
|
39
|
+
def verify!
|
|
40
|
+
return unless issue.valid?
|
|
41
|
+
return if group_summary_without_destination?
|
|
42
|
+
|
|
43
|
+
ensure_labels_exist!(issue.labels, destination)
|
|
44
|
+
resolve_assignee_ids(issue.assignee_usernames) if issue.assignee_usernames.any?
|
|
45
|
+
resolve_milestone_id(destination, issue.milestone_title) if issue.milestone_title
|
|
46
|
+
end
|
|
47
|
+
|
|
35
48
|
def act
|
|
36
49
|
perform if issue.valid?
|
|
37
50
|
end
|
|
@@ -75,10 +88,17 @@ module Gitlab
|
|
|
75
88
|
end
|
|
76
89
|
|
|
77
90
|
def post_issue_body
|
|
78
|
-
{
|
|
91
|
+
body = {
|
|
79
92
|
title: issue.title,
|
|
80
93
|
description: issue.description
|
|
81
94
|
}
|
|
95
|
+
|
|
96
|
+
body[:labels] = issue.labels.join(',') if issue.labels.any?
|
|
97
|
+
body[:assignee_ids] = resolve_assignee_ids(issue.assignee_usernames) if issue.assignee_usernames.any?
|
|
98
|
+
body[:due_date] = issue.due_date if issue.due_date
|
|
99
|
+
body[:milestone_id] = resolve_milestone_id(destination, issue.milestone_title) if issue.milestone_title
|
|
100
|
+
|
|
101
|
+
body
|
|
82
102
|
end
|
|
83
103
|
end
|
|
84
104
|
end
|