diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/stylesheets/framework/filters.scss | 6 | ||||
-rw-r--r-- | app/models/error_tracking/project_error_tracking_setting.rb | 4 | ||||
-rw-r--r-- | app/models/sentry_issue.rb | 6 | ||||
-rw-r--r-- | app/views/admin/runners/index.html.haml | 2 | ||||
-rw-r--r-- | app/views/shared/issuable/_search_bar.html.haml | 2 | ||||
-rw-r--r-- | app/workers/all_queues.yml | 1 | ||||
-rw-r--r-- | app/workers/error_tracking_issue_link_worker.rb | 85 |
7 files changed, 100 insertions, 6 deletions
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index b5d1c3f6732..4b45a169a31 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -190,6 +190,7 @@ min-width: 0; border: 1px solid $border-color; background-color: $white-light; + border-radius: $border-radius-default 0 0 $border-radius-default; @include media-breakpoint-down(sm) { flex: 1 1 auto; @@ -287,7 +288,7 @@ .filtered-search-history-dropdown-toggle-button { flex: 1; width: auto; - border-radius: 0; + border-radius: $border-radius-default 0 0 $border-radius-default; border: 0; border-right: 1px solid $border-color; color: $gl-text-color-secondary; @@ -296,8 +297,7 @@ &:hover, &:focus { color: $gl-text-color; - border-color: $blue-300; - outline: none; + border-color: $border-color; } svg { diff --git a/app/models/error_tracking/project_error_tracking_setting.rb b/app/models/error_tracking/project_error_tracking_setting.rb index a904cf4ac46..5b13d0b628a 100644 --- a/app/models/error_tracking/project_error_tracking_setting.rb +++ b/app/models/error_tracking/project_error_tracking_setting.rb @@ -73,7 +73,9 @@ module ErrorTracking end def sentry_client - Sentry::Client.new(api_url, token) + strong_memoize(:sentry_client) do + Sentry::Client.new(api_url, token) + end end def sentry_external_url diff --git a/app/models/sentry_issue.rb b/app/models/sentry_issue.rb index e60ad6015a5..1325bce6c43 100644 --- a/app/models/sentry_issue.rb +++ b/app/models/sentry_issue.rb @@ -6,9 +6,15 @@ class SentryIssue < ApplicationRecord validates :issue, uniqueness: true, presence: true validates :sentry_issue_identifier, presence: true + after_create_commit :enqueue_sentry_sync_job + def self.for_project_and_identifier(project, identifier) joins(:issue) .where(issues: { project_id: project.id }) .find_by_sentry_issue_identifier(identifier) end + + def enqueue_sentry_sync_job + ErrorTrackingIssueLinkWorker.perform_async(issue.id) + end end diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml index 818d265c767..59e28a3b244 100644 --- a/app/views/admin/runners/index.html.haml +++ b/app/views/admin/runners/index.html.haml @@ -47,7 +47,7 @@ .filtered-search-box = dropdown_tag(_('Recent searches'), options: { wrapper_class: 'filtered-search-history-dropdown-wrapper', - toggle_class: 'filtered-search-history-dropdown-toggle-button', + toggle_class: 'btn filtered-search-history-dropdown-toggle-button', dropdown_class: 'filtered-search-history-dropdown', content_class: 'filtered-search-history-dropdown-content' }) do .js-filtered-search-history-dropdown{ data: { full_path: admin_runners_path } } diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index c3960ec5026..a27ceaff782 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -21,7 +21,7 @@ - if type != :boards_modal && type != :boards = dropdown_tag(_('Recent searches'), options: { wrapper_class: "filtered-search-history-dropdown-wrapper", - toggle_class: "filtered-search-history-dropdown-toggle-button", + toggle_class: "btn filtered-search-history-dropdown-toggle-button", dropdown_class: "filtered-search-history-dropdown", content_class: "filtered-search-history-dropdown-content" }) do .js-filtered-search-history-dropdown{ data: { full_path: search_history_storage_prefix } } diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 62b37f52cce..502e7976ef2 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -143,6 +143,7 @@ - delete_user - email_receiver - emails_on_push +- error_tracking_issue_link - expire_build_instance_artifacts - git_garbage_collect - gitlab_shell diff --git a/app/workers/error_tracking_issue_link_worker.rb b/app/workers/error_tracking_issue_link_worker.rb new file mode 100644 index 00000000000..5048f361c31 --- /dev/null +++ b/app/workers/error_tracking_issue_link_worker.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +# Creates a link in Sentry between a Sentry issue and a GitLab issue. +# If the link already exists, no changes will occur. +# If a link to a different GitLab issue exists, a new link +# will still be created, but will not be visible in Sentry +# until the prior link is deleted. +class ErrorTrackingIssueLinkWorker + include ApplicationWorker + include ExclusiveLeaseGuard + include Gitlab::Utils::StrongMemoize + + feature_category :error_tracking + worker_has_external_dependencies! + + LEASE_TIMEOUT = 15.minutes + + attr_reader :issue + + def perform(issue_id) + @issue = Issue.find_by_id(issue_id) + + return unless issue && error_tracking && sentry_issue_id + + try_obtain_lease do + logger.info("Linking Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}") + + if integration_id.nil? + logger.info("Sentry integration unavailable for #{error_tracking.api_url}") + + break + end + + sentry_client.create_issue_link(integration_id, sentry_issue_id, issue) + rescue Sentry::Client::Error + logger.info("Failed to link Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}") + end + end + + private + + def error_tracking + strong_memoize(:error_tracking) do + issue.project.error_tracking_setting + end + end + + def sentry_issue_id + strong_memoize(:sentry_issue_id) do + issue.sentry_issue.sentry_issue_identifier + end + end + + def sentry_client + error_tracking.sentry_client + end + + def integration_id + strong_memoize(:integration_id) do + repo&.integration_id + end + end + + def repo + sentry_client + .repos(organization_slug) + .find { |repo| repo.project_id == issue.project_id && repo.status == 'active' } + end + + def organization_slug + error_tracking.organization_slug + end + + def project_url + ::Gitlab::Routing.url_helpers.project_url(issue.project) + end + + def lease_key + "link_sentry_issue_#{sentry_issue_id}_gitlab_#{issue.id}" + end + + def lease_timeout + LEASE_TIMEOUT + end +end |