Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-05 03:07:49 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-05 03:07:49 +0300
commit77237c5a6b9044f58beabc54d3589e5fa09cbfba (patch)
treef43188047fe8955f6cf78e05ae9c2e8f6a019e0b /app
parent2fd92f2dc784ade9cb4e1c33dd60cbfad7b86818 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/broadcast_notification.js10
-rw-r--r--app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js2
-rw-r--r--app/assets/stylesheets/framework/broadcast_messages.scss9
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb1
-rw-r--r--app/controllers/projects/milestones_controller.rb3
-rw-r--r--app/controllers/repositories/git_http_client_controller.rb9
-rw-r--r--app/controllers/repositories/git_http_controller.rb13
-rw-r--r--app/helpers/broadcast_messages_helper.rb6
-rw-r--r--app/helpers/milestones_helper.rb14
-rw-r--r--app/models/concerns/milestoneish.rb20
-rw-r--r--app/models/snippet.rb4
-rw-r--r--app/services/issues/base_service.rb12
-rw-r--r--app/services/issues/close_service.rb2
-rw-r--r--app/services/issues/create_service.rb1
-rw-r--r--app/services/issues/reopen_service.rb1
-rw-r--r--app/services/issues/update_service.rb20
-rw-r--r--app/services/metrics/dashboard/base_embed_service.rb4
-rw-r--r--app/services/metrics/dashboard/custom_metric_embed_service.rb2
-rw-r--r--app/services/metrics/dashboard/default_embed_service.rb2
-rw-r--r--app/services/metrics/dashboard/dynamic_embed_service.rb2
-rw-r--r--app/services/metrics/dashboard/grafana_metric_embed_service.rb4
-rw-r--r--app/services/milestones/closed_issues_count_service.rb17
-rw-r--r--app/services/milestones/issues_count_service.rb17
-rw-r--r--app/services/milestones/transfer_service.rb18
-rw-r--r--app/services/post_receive_service.rb16
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml7
-rw-r--r--app/views/shared/_broadcast_message.html.haml10
-rw-r--r--app/views/shared/milestones/_issuable.html.haml5
-rw-r--r--app/workers/post_receive.rb69
29 files changed, 221 insertions, 79 deletions
diff --git a/app/assets/javascripts/broadcast_notification.js b/app/assets/javascripts/broadcast_notification.js
index b124502506a..dc5401199dc 100644
--- a/app/assets/javascripts/broadcast_notification.js
+++ b/app/assets/javascripts/broadcast_notification.js
@@ -6,16 +6,14 @@ const handleOnDismiss = ({ currentTarget }) => {
dataset: { id },
} = currentTarget;
- Cookies.set(`hide_broadcast_notification_message_${id}`, true);
+ Cookies.set(`hide_broadcast_message_${id}`, true);
const notification = document.querySelector(`.js-broadcast-notification-${id}`);
notification.parentNode.removeChild(notification);
};
export default () => {
- const dismissButton = document.querySelector('.js-dismiss-current-broadcast-notification');
-
- if (dismissButton) {
- dismissButton.addEventListener('click', handleOnDismiss);
- }
+ document
+ .querySelectorAll('.js-dismiss-current-broadcast-notification')
+ .forEach(dismissButton => dismissButton.addEventListener('click', handleOnDismiss));
};
diff --git a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
index d191479b1b4..34a024b1b33 100644
--- a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
+++ b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
@@ -25,9 +25,11 @@ export default () => {
$broadcastMessageType.on('change', () => {
const $broadcastMessageColorFormGroup = $('.js-broadcast-message-background-color-form-group');
+ const $broadcastMessageDismissableFormGroup = $('.js-broadcast-message-dismissable-form-group');
const $broadcastNotificationMessagePreview = $('.js-broadcast-notification-message-preview');
$broadcastMessageColorFormGroup.toggleClass('hidden');
+ $broadcastMessageDismissableFormGroup.toggleClass('hidden');
$broadcastBannerMessagePreview.toggleClass('hidden');
$broadcastNotificationMessagePreview.toggleClass('hidden');
});
diff --git a/app/assets/stylesheets/framework/broadcast_messages.scss b/app/assets/stylesheets/framework/broadcast_messages.scss
index 95ea3d90a0e..359f4681938 100644
--- a/app/assets/stylesheets/framework/broadcast_messages.scss
+++ b/app/assets/stylesheets/framework/broadcast_messages.scss
@@ -17,6 +17,10 @@
@extend .broadcast-message;
@extend .alert-warning;
text-align: center;
+
+ .broadcast-message-dismiss {
+ color: inherit;
+ }
}
.broadcast-notification-message {
@@ -36,6 +40,11 @@
&.preview {
position: static;
}
+
+ .broadcast-message-dismiss {
+ height: 100%;
+ color: $gray-800;
+ }
}
.toggle-colors {
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index 06ba916fc55..3233c765941 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -62,6 +62,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
starts_at
target_path
broadcast_type
+ dismissable
))
end
end
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index f6f61b6e5fb..d301a5be391 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -24,7 +24,6 @@ class Projects::MilestonesController < Projects::ApplicationController
respond_to do |format|
format.html do
- @project_namespace = @project.namespace.becomes(Namespace)
# We need to show group milestones in the JSON response
# so that people can filter by and assign group milestones,
# but we don't need to show them on the project milestones page itself.
@@ -47,8 +46,6 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def show
- @project_namespace = @project.namespace.becomes(Namespace)
-
respond_to do |format|
format.html
end
diff --git a/app/controllers/repositories/git_http_client_controller.rb b/app/controllers/repositories/git_http_client_controller.rb
index 76eb7c67205..d03daa406cf 100644
--- a/app/controllers/repositories/git_http_client_controller.rb
+++ b/app/controllers/repositories/git_http_client_controller.rb
@@ -6,7 +6,7 @@ module Repositories
include KerberosSpnegoHelper
include Gitlab::Utils::StrongMemoize
- attr_reader :authentication_result, :redirected_path
+ attr_reader :authentication_result, :redirected_path, :container
delegate :actor, :authentication_abilities, to: :authentication_result, allow_nil: true
delegate :type, to: :authentication_result, allow_nil: true, prefix: :auth_result
@@ -81,7 +81,7 @@ module Repositories
end
def parse_repo_path
- @project, @repo_type, @redirected_path = Gitlab::RepoPath.parse("#{params[:namespace_id]}/#{params[:repository_id]}")
+ @container, @project, @repo_type, @redirected_path = Gitlab::RepoPath.parse("#{params[:namespace_id]}/#{params[:repository_id]}")
end
def render_missing_personal_access_token
@@ -93,7 +93,7 @@ module Repositories
def repository
strong_memoize(:repository) do
- repo_type.repository_for(project)
+ repo_type.repository_for(container)
end
end
@@ -117,7 +117,8 @@ module Repositories
def http_download_allowed?
Gitlab::ProtocolAccess.allowed?('http') &&
download_request? &&
- project && Guest.can?(:download_code, project)
+ container &&
+ Guest.can?(repo_type.guest_read_ability, container)
end
end
end
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index 5c2b6089bff..5ce2ed77417 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -84,10 +84,10 @@ module Repositories
end
def access
- @access ||= access_klass.new(access_actor, project, 'http',
+ @access ||= access_klass.new(access_actor, container, 'http',
authentication_abilities: authentication_abilities,
namespace_path: params[:namespace_id],
- project_path: project_path,
+ repository_path: repository_path,
redirected_path: redirected_path,
auth_result_type: auth_result_type)
end
@@ -99,15 +99,18 @@ module Repositories
def access_check
access.check(git_command, Gitlab::GitAccess::ANY)
- @project ||= access.project
+
+ if repo_type.project? && !container
+ @project = @container = access.project
+ end
end
def access_klass
@access_klass ||= repo_type.access_checker_class
end
- def project_path
- @project_path ||= params[:repository_id].sub(/\.git$/, '')
+ def repository_path
+ @repository_path ||= params[:repository_id].sub(/\.git$/, '')
end
def log_user_activity
diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb
index 34e65c322c6..7638710a7c2 100644
--- a/app/helpers/broadcast_messages_helper.rb
+++ b/app/helpers/broadcast_messages_helper.rb
@@ -2,12 +2,14 @@
module BroadcastMessagesHelper
def current_broadcast_banner_messages
- BroadcastMessage.current_banner_messages(request.path)
+ BroadcastMessage.current_banner_messages(request.path).select do |message|
+ cookies["hide_broadcast_message_#{message.id}"].blank?
+ end
end
def current_broadcast_notification_message
not_hidden_messages = BroadcastMessage.current_notification_messages(request.path).select do |message|
- cookies["hide_broadcast_notification_message_#{message.id}"].blank?
+ cookies["hide_broadcast_message_#{message.id}"].blank?
end
not_hidden_messages.last
end
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
index b12b39073ef..a723269ea0e 100644
--- a/app/helpers/milestones_helper.rb
+++ b/app/helpers/milestones_helper.rb
@@ -151,18 +151,20 @@ module MilestonesHelper
end
def milestone_issues_tooltip_text(milestone)
- issues = milestone.count_issues_by_state(current_user)
+ total = milestone.total_issues_count(current_user)
+ opened = milestone.opened_issues_count(current_user)
+ closed = milestone.closed_issues_count(current_user)
- return _("Issues") if issues.empty?
+ return _("Issues") if total.zero?
content = []
- if issues["opened"]
- content << n_("1 open issue", "%{issues} open issues", issues["opened"]) % { issues: issues["opened"] }
+ if opened > 0
+ content << n_("1 open issue", "%{issues} open issues", opened) % { issues: opened }
end
- if issues["closed"]
- content << n_("1 closed issue", "%{issues} closed issues", issues["closed"]) % { issues: issues["closed"] }
+ if closed > 0
+ content << n_("1 closed issue", "%{issues} closed issues", closed) % { issues: closed }
end
content.join('<br />').html_safe
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 88e752e51e7..045e893761a 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -2,13 +2,27 @@
module Milestoneish
def total_issues_count(user)
- count_issues_by_state(user).values.sum
+ @total_issues_count ||=
+ if Feature.enabled?(:cached_milestone_issue_counters)
+ Milestones::IssuesCountService.new(self).count
+ else
+ count_issues_by_state(user).values.sum
+ end
end
def closed_issues_count(user)
- closed_state_id = Issue.available_states[:closed]
+ @close_issues_count ||=
+ if Feature.enabled?(:cached_milestone_issue_counters)
+ Milestones::ClosedIssuesCountService.new(self).count
+ else
+ closed_state_id = Issue.available_states[:closed]
+
+ count_issues_by_state(user)[closed_state_id].to_i
+ end
+ end
- count_issues_by_state(user)[closed_state_id].to_i
+ def opened_issues_count(user)
+ total_issues_count(user) - closed_issues_count(user)
end
def complete?(user)
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 201cd719ee9..770d9b5205c 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -160,6 +160,10 @@ class Snippet < ApplicationRecord
@link_reference_pattern ||= super("snippets", /(?<snippet>\d+)/)
end
+ def self.find_by_id_and_project(id:, project:)
+ Snippet.find_by(id: id, project: project)
+ end
+
def initialize(attributes = {})
# We can't use default_value_for because the database has a default
# value of 0 for visibility_level. If someone attempts to create a
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb
index 974f7e598ca..9e72f6dad8d 100644
--- a/app/services/issues/base_service.rb
+++ b/app/services/issues/base_service.rb
@@ -34,6 +34,18 @@ module Issues
def update_project_counter_caches?(issue)
super || issue.confidential_changed?
end
+
+ def delete_milestone_closed_issue_counter_cache(milestone)
+ return unless milestone
+
+ Milestones::ClosedIssuesCountService.new(milestone).delete_cache
+ end
+
+ def delete_milestone_total_issue_counter_cache(milestone)
+ return unless milestone
+
+ Milestones::IssuesCountService.new(milestone).delete_cache
+ end
end
end
diff --git a/app/services/issues/close_service.rb b/app/services/issues/close_service.rb
index ce955b07648..21e9a2210fb 100644
--- a/app/services/issues/close_service.rb
+++ b/app/services/issues/close_service.rb
@@ -38,6 +38,8 @@ module Issues
issue.update_project_counter_caches
store_first_mentioned_in_commit_at(issue, closed_via) if closed_via.is_a?(MergeRequest)
+
+ delete_milestone_closed_issue_counter_cache(issue.milestone)
end
issue
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index e8879d4df66..7869509aa9c 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -29,6 +29,7 @@ module Issues
todo_service.new_issue(issuable, current_user)
user_agent_detail_service.create
resolve_discussions_with_issue(issuable)
+ delete_milestone_total_issue_counter_cache(issuable.milestone)
super
end
diff --git a/app/services/issues/reopen_service.rb b/app/services/issues/reopen_service.rb
index 56d59b235a7..0ffe33dd317 100644
--- a/app/services/issues/reopen_service.rb
+++ b/app/services/issues/reopen_service.rb
@@ -12,6 +12,7 @@ module Issues
execute_hooks(issue, 'reopen')
invalidate_cache_counts(issue, users: issue.assignees)
issue.update_project_counter_caches
+ delete_milestone_closed_issue_counter_cache(issue.milestone)
end
issue
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index 68d1657d881..78ebbd7bff2 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -115,10 +115,26 @@ module Issues
end
def handle_milestone_change(issue)
- return if skip_milestone_email
-
return unless issue.previous_changes.include?('milestone_id')
+ invalidate_milestone_issue_counters(issue)
+ send_milestone_change_notification(issue)
+ end
+
+ def invalidate_milestone_issue_counters(issue)
+ issue.previous_changes['milestone_id'].each do |milestone_id|
+ next unless milestone_id
+
+ milestone = Milestone.find_by_id(milestone_id)
+
+ delete_milestone_closed_issue_counter_cache(milestone)
+ delete_milestone_total_issue_counter_cache(milestone)
+ end
+ end
+
+ def send_milestone_change_notification(issue)
+ return if skip_milestone_email
+
if issue.milestone.nil?
notification_service.async.removed_milestone_issue(issue, current_user)
else
diff --git a/app/services/metrics/dashboard/base_embed_service.rb b/app/services/metrics/dashboard/base_embed_service.rb
index 8aef9873ac1..4c7fa454460 100644
--- a/app/services/metrics/dashboard/base_embed_service.rb
+++ b/app/services/metrics/dashboard/base_embed_service.rb
@@ -5,6 +5,10 @@
module Metrics
module Dashboard
class BaseEmbedService < ::Metrics::Dashboard::BaseService
+ def self.embedded?(embed_param)
+ ActiveModel::Type::Boolean.new.cast(embed_param)
+ end
+
def cache_key
"dynamic_metrics_dashboard_#{identifiers}"
end
diff --git a/app/services/metrics/dashboard/custom_metric_embed_service.rb b/app/services/metrics/dashboard/custom_metric_embed_service.rb
index 9e616f4e379..456074ae6ad 100644
--- a/app/services/metrics/dashboard/custom_metric_embed_service.rb
+++ b/app/services/metrics/dashboard/custom_metric_embed_service.rb
@@ -18,7 +18,7 @@ module Metrics
# custom metrics from the DB.
def valid_params?(params)
[
- params[:embedded],
+ embedded?(params[:embedded]),
valid_dashboard?(params[:dashboard_path]),
valid_group_title?(params[:group]),
params[:title].present?,
diff --git a/app/services/metrics/dashboard/default_embed_service.rb b/app/services/metrics/dashboard/default_embed_service.rb
index 39f7c3943dd..30a8150d6be 100644
--- a/app/services/metrics/dashboard/default_embed_service.rb
+++ b/app/services/metrics/dashboard/default_embed_service.rb
@@ -22,7 +22,7 @@ module Metrics
class << self
def valid_params?(params)
- params[:embedded].present?
+ embedded?(params[:embedded])
end
end
diff --git a/app/services/metrics/dashboard/dynamic_embed_service.rb b/app/services/metrics/dashboard/dynamic_embed_service.rb
index db5b7c9e32a..ff540c30579 100644
--- a/app/services/metrics/dashboard/dynamic_embed_service.rb
+++ b/app/services/metrics/dashboard/dynamic_embed_service.rb
@@ -22,7 +22,7 @@ module Metrics
# for additional info on defining custom dashboards.
def valid_params?(params)
[
- params[:embedded],
+ embedded?(params[:embedded]),
params[:group].present?,
params[:title].present?,
params[:y_label]
diff --git a/app/services/metrics/dashboard/grafana_metric_embed_service.rb b/app/services/metrics/dashboard/grafana_metric_embed_service.rb
index 44b58ad9729..3ad3a2c609e 100644
--- a/app/services/metrics/dashboard/grafana_metric_embed_service.rb
+++ b/app/services/metrics/dashboard/grafana_metric_embed_service.rb
@@ -6,7 +6,7 @@
# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards.
module Metrics
module Dashboard
- class GrafanaMetricEmbedService < ::Metrics::Dashboard::BaseService
+ class GrafanaMetricEmbedService < ::Metrics::Dashboard::BaseEmbedService
include ReactiveCaching
SEQUENCE = [
@@ -24,7 +24,7 @@ module Metrics
# to uniquely identify a grafana dashboard.
def valid_params?(params)
[
- params[:embedded],
+ embedded?(params[:embedded]),
params[:grafana_url]
].all?
end
diff --git a/app/services/milestones/closed_issues_count_service.rb b/app/services/milestones/closed_issues_count_service.rb
new file mode 100644
index 00000000000..80aab235e49
--- /dev/null
+++ b/app/services/milestones/closed_issues_count_service.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Milestones
+ class ClosedIssuesCountService < BaseCountService
+ def initialize(milestone)
+ @milestone = milestone
+ end
+
+ def cache_key
+ "milestone_closed_issues_count_#{@milestone.milestoneish_id}"
+ end
+
+ def relation_for_count
+ @milestone.issues.closed
+ end
+ end
+end
diff --git a/app/services/milestones/issues_count_service.rb b/app/services/milestones/issues_count_service.rb
new file mode 100644
index 00000000000..f8b80fa9aef
--- /dev/null
+++ b/app/services/milestones/issues_count_service.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Milestones
+ class IssuesCountService < BaseCountService
+ def initialize(milestone)
+ @milestone = milestone
+ end
+
+ def cache_key
+ "milestone_total_issues_count_#{@milestone.milestoneish_id}"
+ end
+
+ def relation_for_count
+ @milestone.issues
+ end
+ end
+end
diff --git a/app/services/milestones/transfer_service.rb b/app/services/milestones/transfer_service.rb
index 1efbfed4853..213c6f8f1dd 100644
--- a/app/services/milestones/transfer_service.rb
+++ b/app/services/milestones/transfer_service.rb
@@ -22,7 +22,7 @@ module Milestones
milestones_to_transfer.find_each do |milestone|
new_milestone = find_or_create_milestone(milestone)
- update_issues_milestone(milestone.id, new_milestone&.id)
+ update_issues_milestone(milestone, new_milestone)
update_merge_requests_milestone(milestone.id, new_milestone&.id)
end
end
@@ -68,9 +68,12 @@ module Milestones
end
# rubocop: disable CodeReuse/ActiveRecord
- def update_issues_milestone(old_milestone_id, new_milestone_id)
- Issue.where(project: project, milestone_id: old_milestone_id)
- .update_all(milestone_id: new_milestone_id)
+ def update_issues_milestone(old_milestone, new_milestone)
+ Issue.where(project: project, milestone_id: old_milestone.id)
+ .update_all(milestone_id: new_milestone&.id)
+
+ delete_milestone_issues_caches(old_milestone)
+ delete_milestone_issues_caches(new_milestone)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -80,5 +83,12 @@ module Milestones
.update_all(milestone_id: new_milestone_id)
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ def delete_milestone_issues_caches(milestone)
+ return unless milestone
+
+ Milestones::IssuesCountService.new(milestone).delete_cache
+ Milestones::ClosedIssuesCountService.new(milestone).delete_cache
+ end
end
end
diff --git a/app/services/post_receive_service.rb b/app/services/post_receive_service.rb
index bc5ec22e77f..f12e45d701a 100644
--- a/app/services/post_receive_service.rb
+++ b/app/services/post_receive_service.rb
@@ -4,10 +4,11 @@
#
# Used for scheduling related jobs after a push action has been performed
class PostReceiveService
- attr_reader :user, :project, :params
+ attr_reader :user, :repository, :project, :params
- def initialize(user, project, params)
+ def initialize(user, repository, project, params)
@user = user
+ @repository = repository
@project = project
@params = params
end
@@ -24,7 +25,7 @@ class PostReceiveService
mr_options = push_options.get(:merge_request)
if mr_options.present?
- message = process_mr_push_options(mr_options, project, user, params[:changes])
+ message = process_mr_push_options(mr_options, params[:changes])
response.add_alert_message(message)
end
@@ -46,8 +47,13 @@ class PostReceiveService
response
end
- def process_mr_push_options(push_options, project, user, changes)
+ def process_mr_push_options(push_options, changes)
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/61359')
+ return unless repository
+
+ unless repository.repo_type.project?
+ return push_options_warning('Push options are only supported for projects')
+ end
service = ::MergeRequests::PushOptionsHandlerService.new(
project, user, changes, push_options
@@ -64,6 +70,8 @@ class PostReceiveService
end
def merge_request_urls
+ return [] unless repository&.repo_type&.project?
+
::MergeRequests::GetUrlsService.new(project).execute(params[:changes])
end
end
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index 9577a2a79df..8b86a024a6e 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -46,6 +46,13 @@
= render_suggested_colors
+ .form-group.row.js-broadcast-message-dismissable-form-group{ class: ('hidden' unless @broadcast_message.banner? ) }
+ .col-sm-2.col-form-label.pt-0
+ = f.label :starts_at, _("Dismissable")
+ .col-sm-10
+ = f.check_box :dismissable
+ = f.label :dismissable do
+ = _('Allow users to dismiss the broadcast message')
.form-group.row.js-toggle-colors-container.toggle-colors.hide
.col-sm-2.col-form-label
= f.label :font, "Font Color"
diff --git a/app/views/shared/_broadcast_message.html.haml b/app/views/shared/_broadcast_message.html.haml
index c058b210688..bc4db672938 100644
--- a/app/views/shared/_broadcast_message.html.haml
+++ b/app/views/shared/_broadcast_message.html.haml
@@ -1,8 +1,10 @@
%div{ class: "broadcast-#{message.broadcast_type}-message #{opts[:preview] && 'preview'} js-broadcast-notification-#{message.id} d-flex",
style: broadcast_message_style(message), dir: 'auto' }
- %div
+ .flex-grow-1.text-right.pr-2
= sprite_icon('bullhorn', size: 16, css_class: 'vertical-align-text-top')
+ %div{ class: !fluid_layout && 'container-limited' }
= render_broadcast_message(message)
- - if message.notification? && opts[:preview].blank?
- %button.js-dismiss-current-broadcast-notification.btn.btn-link.text-dark.pl-2.pr-2{ 'aria-label' => _('Close'), :type => 'button', data: { id: message.id } }
- %i.fa.fa-times
+ .flex-grow-1.text-right{ style: 'flex-basis: 0' }
+ - if (message.notification? || message.dismissable?) && opts[:preview].blank?
+ %button.broadcast-message-dismiss.js-dismiss-current-broadcast-notification.btn.btn-link.pl-2.pr-2{ 'aria-label' => _('Close'), :type => 'button', data: { id: message.id } }
+ %i.fa.fa-times
diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml
index 965c72b82ba..0adfe2f0c04 100644
--- a/app/views/shared/milestones/_issuable.html.haml
+++ b/app/views/shared/milestones/_issuable.html.haml
@@ -1,9 +1,8 @@
-# @project is present when viewing Project's milestone
- project = @project || issuable.project
-- namespace = @project_namespace || project.namespace.becomes(Namespace)
- labels = issuable.labels
- assignees = issuable.assignees
-- base_url_args = [namespace, project]
+- base_url_args = [project]
- issuable_type_args = base_url_args + [issuable.class.table_name]
- issuable_url_args = base_url_args + [issuable]
@@ -17,7 +16,7 @@
= confidential_icon(issuable)
= link_to issuable.title, issuable_url_args, title: issuable.title
.issuable-detail
- = link_to [namespace, project, issuable], class: 'issue-link' do
+ = link_to issuable_url_args, class: 'issue-link' do
%span.issuable-number= issuable.to_reference
- labels.each do |label|
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index d0eb188cc42..5178fabb2d8 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -9,9 +9,9 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
weight 5
def perform(gl_repository, identifier, changes, push_options = {})
- project, repo_type = Gitlab::GlRepository.parse(gl_repository)
+ container, project, repo_type = Gitlab::GlRepository.parse(gl_repository)
- if project.nil?
+ if project.nil? && (!repo_type.snippet? || container.is_a?(ProjectSnippet))
log("Triggered hook for non-existing project with gl_repository \"#{gl_repository}\"")
return false
end
@@ -20,12 +20,14 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
# Use Sidekiq.logger so arguments can be correlated with execution
# time and thread ID's.
Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS']
- post_received = Gitlab::GitPostReceive.new(project, identifier, changes, push_options)
+ post_received = Gitlab::GitPostReceive.new(container, identifier, changes, push_options)
if repo_type.wiki?
- process_wiki_changes(post_received)
+ process_wiki_changes(post_received, container)
elsif repo_type.project?
- process_project_changes(post_received)
+ process_project_changes(post_received, container)
+ elsif repo_type.snippet?
+ process_snippet_changes(post_received, container)
else
# Other repos don't have hooks for now
end
@@ -39,24 +41,50 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
end
end
- def process_project_changes(post_received)
+ def process_project_changes(post_received, project)
user = identify_user(post_received)
return false unless user
- project = post_received.project
push_options = post_received.push_options
changes = post_received.changes
# We only need to expire certain caches once per push
- expire_caches(post_received, post_received.project.repository)
- enqueue_repository_cache_update(post_received)
+ expire_caches(post_received, project.repository)
+ enqueue_project_cache_update(post_received, project)
process_ref_changes(project, user, push_options: push_options, changes: changes)
- update_remote_mirrors(post_received)
+ update_remote_mirrors(post_received, project)
after_project_changes_hooks(project, user, changes.refs, changes.repository_data)
end
+ def process_wiki_changes(post_received, project)
+ project.touch(:last_activity_at, :last_repository_updated_at)
+ project.wiki.repository.expire_statistics_caches
+ ProjectCacheWorker.perform_async(project.id, [], [:wiki_size])
+
+ user = identify_user(post_received)
+ return false unless user
+
+ # We only need to expire certain caches once per push
+ expire_caches(post_received, project.wiki.repository)
+
+ ::Git::WikiPushService.new(project, user, changes: post_received.changes).execute
+ end
+
+ def process_snippet_changes(post_received, snippet)
+ user = identify_user(post_received)
+
+ return false unless user
+
+ # At the moment, we only expires the repository caches.
+ # In the future we might need to call ProjectCacheWorker
+ # (or the custom class we create) to update the snippet
+ # repository size or any other key.
+ # We might also need to update the repository statistics.
+ expire_caches(post_received, snippet.repository)
+ end
+
# Expire the repository status, branch, and tag cache once per push.
def expire_caches(post_received, repository)
repository.expire_status_cache if repository.empty?
@@ -65,12 +93,12 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
end
# Schedule an update for the repository size and commit count if necessary.
- def enqueue_repository_cache_update(post_received)
+ def enqueue_project_cache_update(post_received, project)
stats_to_invalidate = [:repository_size]
stats_to_invalidate << :commit_count if post_received.includes_default_branch?
ProjectCacheWorker.perform_async(
- post_received.project.id,
+ project.id,
[],
stats_to_invalidate,
true
@@ -83,10 +111,9 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
Git::ProcessRefChangesService.new(project, user, params).execute
end
- def update_remote_mirrors(post_received)
+ def update_remote_mirrors(post_received, project)
return unless post_received.includes_branches? || post_received.includes_tags?
- project = post_received.project
return unless project.has_remote_mirror?
project.mark_stuck_remote_mirrors_as_failed!
@@ -99,20 +126,6 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
Gitlab::UsageDataCounters::SourceCodeCounter.count(:pushes)
end
- def process_wiki_changes(post_received)
- post_received.project.touch(:last_activity_at, :last_repository_updated_at)
- post_received.project.wiki.repository.expire_statistics_caches
- ProjectCacheWorker.perform_async(post_received.project.id, [], [:wiki_size])
-
- user = identify_user(post_received)
- return false unless user
-
- # We only need to expire certain caches once per push
- expire_caches(post_received, post_received.project.wiki.repository)
-
- ::Git::WikiPushService.new(post_received.project, user, changes: post_received.changes).execute
- end
-
def log(message)
Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
end