diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-20 09:10:30 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-20 09:10:30 +0000 |
commit | b794758ce4c96fa13c4eefdb97f0852641604081 (patch) | |
tree | ae33ca92627b7271d503fec0994da4a3ee63bf82 /app/models/integrations/issue_tracker.rb | |
parent | 763dd8a47a4e353119f54de0919e10a4fa1de879 (diff) | |
download | gitlab-ce-b794758ce4c96fa13c4eefdb97f0852641604081.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/integrations/issue_tracker.rb')
-rw-r--r-- | app/models/integrations/issue_tracker.rb | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/app/models/integrations/issue_tracker.rb b/app/models/integrations/issue_tracker.rb new file mode 100644 index 00000000000..f63dfa6aace --- /dev/null +++ b/app/models/integrations/issue_tracker.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +module Integrations + class IssueTracker < 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) + + 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 + + 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 + +Integrations::IssueTracker.prepend_mod_with('Integrations::IssueTracker') |