1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
# frozen_string_literal: true
module Integrations
class BaseIssueTracker < Integration
validate :one_issue_tracker, if: :activated?, on: :manual_change
# TODO: we can probably just delegate as part of
# https://gitlab.com/gitlab-org/gitlab/issues/29404
data_field :project_url, :issues_url, :new_issue_url
default_value_for :category, 'issue_tracker'
before_validation :handle_properties
before_validation :set_default_data, on: :create
# Pattern used to extract links from comments
# Override this method on services that uses different patterns
# This pattern does not support cross-project references
# The other code assumes that this pattern is a superset of all
# overridden patterns. See ReferenceRegexes.external_pattern
def self.reference_pattern(only_long: false)
if only_long
/(\b[A-Z][A-Z0-9_]*-)#{Gitlab::Regex.issue}/
else
/(\b[A-Z][A-Z0-9_]*-|#{Issue.reference_prefix})#{Gitlab::Regex.issue}/
end
end
def handle_properties
# this has been moved from initialize_properties and should be improved
# as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
return unless properties
@legacy_properties_data = properties.dup
data_values = properties.slice!('title', 'description')
data_values.reject! { |key| data_fields.changed.include?(key) }
data_values.slice!(*data_fields.attributes.keys)
data_fields.assign_attributes(data_values) if data_values.present?
self.properties = {}
end
def legacy_properties_data
@legacy_properties_data ||= {}
end
def supports_data_fields?
true
end
def data_fields
issue_tracker_data || self.build_issue_tracker_data
end
def default?
default
end
def issue_url(iid)
issues_url.gsub(':id', iid.to_s)
end
def issue_tracker_path
project_url
end
def new_issue_path
new_issue_url
end
def issue_path(iid)
issue_url(iid)
end
def fields
[
{ type: 'text', name: 'project_url', title: _('Project URL'), help: s_('IssueTracker|The URL to the project in the external issue tracker.'), required: true },
{ type: 'text', name: 'issues_url', title: s_('IssueTracker|Issue URL'), help: s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.') % { colon_id: '<code>:id</code>'.html_safe }, required: true },
{ type: 'text', name: 'new_issue_url', title: s_('IssueTracker|New issue URL'), help: s_('IssueTracker|The URL to create an issue in the external issue tracker.'), required: true }
]
end
def initialize_properties
{}
end
# Initialize with default properties values
def set_default_data
return unless issues_tracker.present?
# we don't want to override if we have set something
return if project_url || issues_url || new_issue_url
data_fields.project_url = issues_tracker['project_url']
data_fields.issues_url = issues_tracker['issues_url']
data_fields.new_issue_url = issues_tracker['new_issue_url']
end
def self.supported_events
%w(push)
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
message = "#{self.type} was unable to reach #{self.project_url}. Check the url and try again."
result = false
begin
response = Gitlab::HTTP.head(self.project_url, verify: true, use_read_total_timeout: true)
if response
message = "#{self.type} received response #{response.code} when attempting to connect to #{self.project_url}"
result = true
end
rescue Gitlab::HTTP::Error, Timeout::Error, SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, OpenSSL::SSL::SSLError => error
message = "#{self.type} had an error when trying to connect to #{self.project_url}: #{error.message}"
end
log_info(message)
result
end
def support_close_issue?
false
end
def support_cross_reference?
false
end
def create_cross_reference_note(external_issue, mentioned_in, author)
# implement inside child
end
private
def enabled_in_gitlab_config
Gitlab.config.issues_tracker &&
Gitlab.config.issues_tracker.values.any? &&
issues_tracker
end
def issues_tracker
Gitlab.config.issues_tracker[to_param]
end
def one_issue_tracker
return if template? || instance?
return if project.blank?
if project.integrations.external_issue_trackers.where.not(id: id).any?
errors.add(:base, _('Another issue tracker is already in use. Only one issue tracker service can be active at a time'))
end
end
end
end
|