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:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/framework/buttons.scss18
-rw-r--r--app/assets/stylesheets/framework/variables.scss5
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss25
-rw-r--r--app/assets/stylesheets/pages/tree.scss13
-rw-r--r--app/controllers/admin/application_settings_controller.rb1
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/jwt_controller.rb2
-rw-r--r--app/controllers/projects/hooks_controller.rb3
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/controllers/projects/wikis_controller.rb4
-rw-r--r--app/controllers/projects_controller.rb4
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/finders/issuable_finder.rb2
-rw-r--r--app/models/ability.rb22
-rw-r--r--app/models/application_setting.rb11
-rw-r--r--app/models/ci/commit.rb4
-rw-r--r--app/models/commit.rb23
-rw-r--r--app/models/commit_range.rb2
-rw-r--r--app/models/concerns/issuable.rb28
-rw-r--r--app/models/concerns/mentionable.rb19
-rw-r--r--app/models/concerns/participable.rb94
-rw-r--r--app/models/issue.rb23
-rw-r--r--app/models/key.rb2
-rw-r--r--app/models/members/project_member.rb7
-rw-r--r--app/models/network/graph.rb8
-rw-r--r--app/models/note.rb24
-rw-r--r--app/models/project.rb10
-rw-r--r--app/models/project_snippet.rb3
-rw-r--r--app/models/project_wiki.rb14
-rw-r--r--app/models/snippet.rb7
-rw-r--r--app/services/auth/container_registry_authentication_service.rb12
-rw-r--r--app/services/wiki_pages/base_service.rb5
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml2
-rw-r--r--app/views/admin/application_settings/_form.html.haml8
-rw-r--r--app/views/devise/sessions/two_factor.html.haml1
-rw-r--r--app/views/events/_commit.html.haml2
-rw-r--r--app/views/events/_event_issue.atom.haml2
-rw-r--r--app/views/events/_event_merge_request.atom.haml2
-rw-r--r--app/views/events/_event_note.atom.haml2
-rw-r--r--app/views/events/_event_push.atom.haml2
-rw-r--r--app/views/events/event/_common.html.haml2
-rw-r--r--app/views/events/event/_push.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_first_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_gap.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_last_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_next_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_paginator.html.haml6
-rw-r--r--app/views/kaminari/gitlab/_prev_page.html.haml2
-rw-r--r--app/views/layouts/nav/_project.html.haml15
-rw-r--r--app/views/notify/_note_message.html.haml2
-rw-r--r--app/views/notify/new_issue_email.html.haml2
-rw-r--r--app/views/notify/new_merge_request_email.html.haml2
-rw-r--r--app/views/projects/builds/index.html.haml1
-rw-r--r--app/views/projects/ci/commits/_commit.html.haml4
-rw-r--r--app/views/projects/commit/_ci_commit.html.haml16
-rw-r--r--app/views/projects/commit/_commit_box.html.haml4
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/hooks/_project_hook.html.haml2
-rw-r--r--app/views/projects/hooks/index.html.haml7
-rw-r--r--app/views/projects/issues/show.html.haml4
-rw-r--r--app/views/projects/merge_requests/show/_mr_box.html.haml4
-rw-r--r--app/views/projects/merge_requests/widget/_open.html.haml2
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/pipelines/_head.html.haml14
-rw-r--r--app/views/projects/pipelines/index.html.haml1
-rw-r--r--app/views/projects/repositories/_feed.html.haml2
-rw-r--r--app/views/search/results/_issue.html.haml2
-rw-r--r--app/views/search/results/_merge_request.html.haml2
-rw-r--r--app/views/search/results/_note.html.haml2
-rw-r--r--app/views/shared/snippets/_header.html.haml4
-rw-r--r--app/workers/emails_on_push_worker.rb1
72 files changed, 375 insertions, 166 deletions
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index eaf85bb17ca..467f3b35d74 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -16,6 +16,19 @@
@include btn-default;
}
+@mixin btn-outline($background, $text, $border, $hover-background, $hover-text, $hover-border) {
+ background-color: $background;
+ color: $text;
+ border-color: $border;
+
+ &:hover,
+ &:focus {
+ background-color: $hover-background;
+ color: $hover-text;
+ border-color: $hover-border;;
+ }
+}
+
@mixin btn-color($light, $border-light, $normal, $border-normal, $dark, $border-dark, $color) {
background-color: $light;
border-color: $border-light;
@@ -106,11 +119,14 @@
@include btn-blue;
}
- &.btn-close,
&.btn-warning {
@include btn-orange;
}
+ &.btn-close {
+ @include btn-outline($white-light, $orange-normal, $orange-normal, $orange-light, $white-light, $orange-light);
+ }
+
&.btn-danger,
&.btn-remove,
&.btn-red {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index c7784e15844..f253da814bc 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -63,7 +63,8 @@ $gl-padding-top: 10px;
/*
* Misc
*/
-$row-hover: #f4f8fe;
+$row-hover: #f7faff;
+$row-hover-border: #b2d7ff;
$progress-color: #c0392b;
$avatar_radius: 50%;
$header-height: 50px;
@@ -104,7 +105,7 @@ $blue-medium-light: #3498cb;
$blue-medium: #2f8ebf;
$blue-medium-dark: #2d86b4;
-$orange-light: rgba(252, 109, 38, 0.80);
+$orange-light: #fc8a51;
$orange-normal: #e75e40;
$orange-dark: #ce5237;
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 4f8a8748d3f..8046e203a99 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -41,7 +41,7 @@
margin: 0;
margin-left: 20px;
padding: 5px;
- padding-top: 12px;
+ padding-top: 8px;
line-height: 20px;
&.right {
@@ -110,6 +110,29 @@
p:last-child {
margin-bottom: 0;
}
+
+ @media (max-width: $screen-sm-max) {
+ h4 {
+ font-size: 15px;
+ }
+
+ p {
+ font-size: 13px;
+ }
+
+ .btn,
+ .btn-group,
+ .accept-action {
+ width: 100%;
+ margin-bottom: 4px;
+ }
+
+ .accept-control {
+ width: 100%;
+ text-align: center;
+ margin: 0;
+ }
+ }
}
.mr-widget-footer {
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index a84fc2e0318..f16fc7f388f 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -15,16 +15,23 @@
margin-bottom: 0;
tr {
- > td, > th {
+ border-bottom: 1px solid $table-border-gray;
+ border-top: 1px solid $table-border-gray;
+
+ td, th {
line-height: 23px;
}
&:hover {
+ cursor: pointer;
+
td {
- background: $row-hover;
+ background-color: $row-hover;
+ border-top: 1px solid $row-hover-border;
+ border-bottom: 1px solid $row-hover-border;
}
- cursor: pointer;
}
+
&.selected {
td {
background: $gray-dark;
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index ff7a5cad2fb..0a34a12e2a7 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -107,6 +107,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:repository_checks_enabled,
:metrics_packet_size,
:send_user_confirmation_email,
+ :container_registry_token_expire_delay,
restricted_visibility_levels: [],
import_sources: [],
disabled_oauth_sign_in_sources: []
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 144febcea12..c28d1ca9e3b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -263,7 +263,7 @@ class ApplicationController < ActionController::Base
# internal repos where you are not a member. Enable this filter
# or improve current implementation to filter only issues you
# created or assigned or mentioned
- #@filter_params[:authorized_only] = true
+ # @filter_params[:authorized_only] = true
end
@filter_params
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 156ab2811d6..cee3b6c43e7 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -32,7 +32,7 @@ class JwtController < ApplicationController
end
def auth_params
- params.permit(:service, :scope, :offline_token, :account, :client_id)
+ params.permit(:service, :scope, :account, :client_id)
end
def authenticate_project(login, password)
diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb
index 47524b1cf0b..a60027ff477 100644
--- a/app/controllers/projects/hooks_controller.rb
+++ b/app/controllers/projects/hooks_controller.rb
@@ -63,7 +63,8 @@ class Projects::HooksController < Projects::ApplicationController
:push_events,
:tag_push_events,
:token,
- :url
+ :url,
+ :wiki_page_events
)
end
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 17ce8e2ad20..d54284d7b20 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -205,7 +205,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def branch_from
- #This is always source
+ # This is always source
@source_project = @merge_request.nil? ? @project : @merge_request.source_project
@commit = @repository.commit(params[:ref]) if params[:ref].present?
render layout: false
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 0d6c32fabd2..4b404eb03fa 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -91,8 +91,8 @@ class Projects::WikisController < Projects::ApplicationController
def markdown_preview
text = params[:text]
- ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
- ext.analyze(text)
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user)
+ ext.analyze(text, author: current_user)
render json: {
body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki),
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 9697b88c032..f94e2a84fa2 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -197,8 +197,8 @@ class ProjectsController < Projects::ApplicationController
def markdown_preview
text = params[:text]
- ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
- ext.analyze(text)
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user)
+ ext.analyze(text, author: current_user)
render json: {
body: view_context.markdown(text),
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index c29f4609e93..d68c2a708e3 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -1,5 +1,6 @@
class SessionsController < Devise::SessionsController
include AuthenticatesWithTwoFactor
+ include Devise::Controllers::Rememberable
include Recaptcha::ClientHelper
skip_before_action :check_2fa_requirement, only: [:destroy]
@@ -96,6 +97,7 @@ class SessionsController < Devise::SessionsController
# Remove any lingering user data from login
session.delete(:otp_user_id)
+ remember_me(user) if user_params[:remember_me] == '1'
sign_in(user) and return
else
flash.now[:alert] = 'Invalid two-factor code.'
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 8ed3ccf1c02..7d8c56f4c22 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -271,7 +271,7 @@ class IssuableFinder
if filter_by_no_label?
items = items.without_label
else
- items = items.with_label(label_names)
+ items = items.with_label(label_names, params[:sort])
if projects
items = items.where(labels: { project_id: projects })
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 8c5b255223d..44515550d9e 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -23,6 +23,28 @@ class Ability
end.concat(global_abilities(user))
end
+ # Given a list of users and a project this method returns the users that can
+ # read the given project.
+ def users_that_can_read_project(users, project)
+ if project.public?
+ users
+ else
+ users.select do |user|
+ if user.admin?
+ true
+ elsif project.internal? && !user.external?
+ true
+ elsif project.owner == user
+ true
+ elsif project.team.members.include?(user)
+ true
+ else
+ false
+ end
+ end
+ end
+ end
+
# List of possible abilities for anonymous user
def anonymous_abilities(user, subject)
if subject.is_a?(PersonalSnippet)
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 9a14954b4a7..42f908aa344 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -51,6 +51,10 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { only_integer: true, greater_than: 0 }
+ validates :container_registry_token_expire_delay,
+ presence: true,
+ numericality: { only_integer: true, greater_than: 0 }
+
validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil?
value.each do |level|
@@ -98,6 +102,10 @@ class ApplicationSetting < ActiveRecord::Base
Rails.cache.delete(CACHE_KEY)
end
+ def self.cached
+ Rails.cache.fetch(CACHE_KEY)
+ end
+
def self.create_from_defaults
create(
default_projects_limit: Settings.gitlab['default_projects_limit'],
@@ -121,7 +129,8 @@ class ApplicationSetting < ActiveRecord::Base
akismet_enabled: false,
repository_checks_enabled: true,
disabled_oauth_sign_in_sources: [],
- send_user_confirmation_email: false
+ send_user_confirmation_email: false,
+ container_registry_token_expire_delay: 5,
)
end
diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb
index 6675a3f5d53..f22b573a94c 100644
--- a/app/models/ci/commit.rb
+++ b/app/models/ci/commit.rb
@@ -66,6 +66,10 @@ module Ci
end
end
+ def cancelable?
+ builds.running_or_pending.any?
+ end
+
def cancel_running
builds.running_or_pending.each(&:cancel)
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 562c3ed15b2..f96c7cb34d0 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -8,7 +8,10 @@ class Commit
include StaticModel
attr_mentionable :safe_message, pipeline: :single_line
- participant :author, :committer, :notes
+
+ participant :author
+ participant :committer
+ participant :notes_with_associations
attr_accessor :project
@@ -194,6 +197,10 @@ class Commit
project.notes.for_commit_id(self.id)
end
+ def notes_with_associations
+ notes.includes(:author, :project)
+ end
+
def method_missing(m, *args, &block)
@raw.send(m, *args, &block)
end
@@ -219,7 +226,7 @@ class Commit
def revert_branch_name
"revert-#{short_id}"
end
-
+
def cherry_pick_branch_name
project.repository.next_branch("cherry-pick-#{short_id}", mild: true)
end
@@ -251,11 +258,13 @@ class Commit
end
def has_been_reverted?(current_user = nil, noteable = self)
- Gitlab::ReferenceExtractor.lazily do
- noteable.notes.system.flat_map do |note|
- note.all_references(current_user).commits
- end
- end.any? { |commit_ref| commit_ref.reverts_commit?(self) }
+ ext = all_references(current_user)
+
+ noteable.notes_with_associations.system.each do |note|
+ note.all_references(current_user, extractor: ext)
+ end
+
+ ext.commits.any? { |commit_ref| commit_ref.reverts_commit?(self) }
end
def change_type_title
diff --git a/app/models/commit_range.rb b/app/models/commit_range.rb
index 51673897d98..4066958f67c 100644
--- a/app/models/commit_range.rb
+++ b/app/models/commit_range.rb
@@ -62,7 +62,7 @@ class CommitRange
def initialize(range_string, project)
@project = project
- range_string.strip!
+ range_string = range_string.strip
unless range_string =~ /\A#{PATTERN}\z/
raise ArgumentError, "invalid CommitRange string format: #{range_string}"
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 91315b3459f..2326a395cb8 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -59,8 +59,12 @@ module Issuable
prefix: true
attr_mentionable :title, pipeline: :single_line
- attr_mentionable :description, cache: true
- participant :author, :assignee, :notes_with_associations
+ attr_mentionable :description
+
+ participant :author
+ participant :assignee
+ participant :notes_with_associations
+
strip_attributes :title
acts_as_paranoid
@@ -126,13 +130,29 @@ module Issuable
joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC")
end
- def with_label(title)
+ def with_label(title, sort = nil)
if title.is_a?(Array) && title.size > 1
- joins(:labels).where(labels: { title: title }).group(arel_table[:id]).having("COUNT(DISTINCT labels.title) = #{title.size}")
+ joins(:labels).where(labels: { title: title }).group(*grouping_columns(sort)).having("COUNT(DISTINCT labels.title) = #{title.size}")
else
joins(:labels).where(labels: { title: title })
end
end
+
+ # Includes table keys in group by clause when sorting
+ # preventing errors in postgres
+ #
+ # Returns an array of arel columns
+ def grouping_columns(sort)
+ grouping_columns = [arel_table[:id]]
+
+ if ["milestone_due_desc", "milestone_due_asc"].include?(sort)
+ milestone_table = Milestone.arel_table
+ grouping_columns << milestone_table[:id]
+ grouping_columns << milestone_table[:due_date]
+ end
+
+ grouping_columns
+ end
end
def today?
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index b381d225485..f00b5b8497c 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -23,7 +23,7 @@ module Mentionable
included do
if self < Participable
- participant ->(current_user) { mentioned_users(current_user) }
+ participant -> (user, ext) { all_references(user, extractor: ext) }
end
end
@@ -43,23 +43,22 @@ module Mentionable
self
end
- def all_references(current_user = nil, text = nil)
- ext = Gitlab::ReferenceExtractor.new(self.project, current_user || self.author, self.author)
+ def all_references(current_user = nil, text = nil, extractor: nil)
+ extractor ||= Gitlab::ReferenceExtractor.
+ new(project, current_user || author)
if text
- ext.analyze(text)
+ extractor.analyze(text, author: author)
else
self.class.mentionable_attrs.each do |attr, options|
- text = send(attr)
+ text = __send__(attr)
+ options = options.merge(cache_key: [self, attr], author: author)
- context = options.dup
- context[:cache_key] = [self, attr] if context.delete(:cache) && self.persisted?
-
- ext.analyze(text, context)
+ extractor.analyze(text, options)
end
end
- ext
+ extractor
end
def mentioned_users(current_user = nil)
diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb
index fc6f83b918b..9056722f45e 100644
--- a/app/models/concerns/participable.rb
+++ b/app/models/concerns/participable.rb
@@ -3,8 +3,6 @@
# Contains functionality related to objects that can have participants, such as
# an author, an assignee and people mentioned in its description or comments.
#
-# Used by Issue, Note, MergeRequest, Snippet and Commit.
-#
# Usage:
#
# class Issue < ActiveRecord::Base
@@ -12,22 +10,36 @@
#
# # ...
#
-# participant :author, :assignee, :notes, ->(current_user) { mentioned_users(current_user) }
+# participant :author
+# participant :assignee
+# participant :notes
+#
+# participant -> (current_user, ext) do
+# ext.analyze('...')
+# end
# end
#
# issue = Issue.last
# users = issue.participants
-# # `users` will contain the issue's author, its assignee,
-# # all users returned by its #mentioned_users method,
-# # as well as all participants to all of the issue's notes,
-# # since Note implements Participable as well.
-#
module Participable
extend ActiveSupport::Concern
module ClassMethods
- def participant(*attrs)
- participant_attrs.concat(attrs)
+ # Adds a list of participant attributes. Attributes can either be symbols or
+ # Procs.
+ #
+ # When using a Proc instead of a Symbol the Proc will be given two
+ # arguments:
+ #
+ # 1. The current user (as an instance of User)
+ # 2. An instance of `Gitlab::ReferenceExtractor`
+ #
+ # It is expected that a Proc populates the given reference extractor
+ # instance with data. The return value of the Proc is ignored.
+ #
+ # attr - The name of the attribute or a Proc
+ def participant(attr)
+ participant_attrs << attr
end
def participant_attrs
@@ -35,42 +47,42 @@ module Participable
end
end
- # Be aware that this method makes a lot of sql queries.
- # Save result into variable if you are going to reuse it inside same request
- def participants(current_user = self.author)
- participants =
- Gitlab::ReferenceExtractor.lazily do
- self.class.participant_attrs.flat_map do |attr|
- value =
- if attr.respond_to?(:call)
- instance_exec(current_user, &attr)
- else
- send(attr)
- end
+ # Returns the users participating in a discussion.
+ #
+ # This method processes attributes of objects in breadth-first order.
+ #
+ # Returns an Array of User instances.
+ def participants(current_user = nil)
+ current_user ||= author
+ ext = Gitlab::ReferenceExtractor.new(project, current_user)
+ participants = Set.new
+ process = [self]
- participants_for(value, current_user)
- end.compact.uniq
- end
+ until process.empty?
+ source = process.pop
- unless Gitlab::ReferenceExtractor.lazy?
- participants.select! do |user|
- user.can?(:read_project, project)
+ case source
+ when User
+ participants << source
+ when Participable
+ source.class.participant_attrs.each do |attr|
+ if attr.respond_to?(:call)
+ source.instance_exec(current_user, ext, &attr)
+ else
+ process << source.__send__(attr)
+ end
+ end
+ when Enumerable, ActiveRecord::Relation
+ # This uses reverse_each so we can use "pop" to get the next value to
+ # process (in order). Using unshift instead of pop would require
+ # moving all Array values one index to the left (which can be
+ # expensive).
+ source.reverse_each { |obj| process << obj }
end
end
- participants
- end
-
- private
+ participants.merge(ext.users)
- def participants_for(value, current_user = nil)
- case value
- when User, Banzai::LazyReference
- [value]
- when Enumerable, ActiveRecord::Relation
- value.flat_map { |v| participants_for(v, current_user) }
- when Participable
- value.participants(current_user)
- end
+ Ability.users_that_can_read_project(participants.to_a, project)
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 2d4a9b9f19a..bd0fbc96d18 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -95,14 +95,13 @@ class Issue < ActiveRecord::Base
end
def referenced_merge_requests(current_user = nil)
- @referenced_merge_requests ||= {}
- @referenced_merge_requests[current_user] ||= begin
- Gitlab::ReferenceExtractor.lazily do
- [self, *notes].flat_map do |note|
- note.all_references(current_user).merge_requests
- end
- end.sort_by(&:iid).uniq
+ ext = all_references(current_user)
+
+ notes_with_associations.each do |object|
+ object.all_references(current_user, extractor: ext)
end
+
+ ext.merge_requests.sort_by(&:iid)
end
# All branches containing the current issue's ID, except for
@@ -139,9 +138,13 @@ class Issue < ActiveRecord::Base
def closed_by_merge_requests(current_user = nil)
return [] unless open?
- notes.system.flat_map do |note|
- note.all_references(current_user).merge_requests
- end.uniq.select { |mr| mr.open? && mr.closes_issue?(self) }
+ ext = all_references(current_user)
+
+ notes.system.each do |note|
+ note.all_references(current_user, extractor: ext)
+ end
+
+ ext.merge_requests.select { |mr| mr.open? && mr.closes_issue?(self) }
end
def moved?
diff --git a/app/models/key.rb b/app/models/key.rb
index d52afda67d1..0532e84f47d 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -26,7 +26,7 @@ class Key < ActiveRecord::Base
end
def publishable_key
- #Removes anything beyond the keytype and key itself
+ # Removes anything beyond the keytype and key itself
self.key.split[0..1].join(' ')
end
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index 8dae3bb2ef2..46955b430f3 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -5,7 +5,6 @@ class ProjectMember < Member
belongs_to :project, class_name: 'Project', foreign_key: 'source_id'
-
# Make sure project member points only to project as it source
default_value_for :source_type, SOURCE_TYPE
validates_format_of :source_type, with: /\AProject\z/
@@ -15,6 +14,8 @@ class ProjectMember < Member
scope :in_projects, ->(projects) { where(source_id: projects.pluck(:id)) }
scope :with_user, ->(user) { where(user_id: user.id) }
+ before_destroy :delete_member_todos
+
class << self
# Add users to project teams with passed access option
@@ -102,6 +103,10 @@ class ProjectMember < Member
private
+ def delete_member_todos
+ user.todos.where(project_id: source_id).destroy_all if user
+ end
+
def send_invite
notification_service.invite_project_member(self, @raw_invite_token)
diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb
index 1ac37e0307f..a2aee2f925b 100644
--- a/app/models/network/graph.rb
+++ b/app/models/network/graph.rb
@@ -164,7 +164,7 @@ module Network
i != range.last &&
@commits[i].spaces.include?(overlap_space)
- return true;
+ return true
end
end
@@ -205,7 +205,7 @@ module Network
# Visit branching chains
leaves.each do |l|
parents = l.parents(@map).select{|p| p.space.zero?}
- for p in parents
+ parents.each do |p|
place_chain(p, l.time)
end
end
@@ -223,7 +223,7 @@ module Network
end
def mark_reserved(time_range, space)
- for day in time_range
+ time_range.each do |day|
@reserved[day].push(space)
end
end
@@ -232,7 +232,7 @@ module Network
space_default ||= space_base
reserved = []
- for day in time_range
+ time_range.each do |day|
reserved.push(*@reserved[day])
end
reserved.uniq!
diff --git a/app/models/note.rb b/app/models/note.rb
index 5f669c02e8b..c21981ead84 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -6,7 +6,7 @@ class Note < ActiveRecord::Base
default_value_for :system, false
- attr_mentionable :note, cache: true, pipeline: :note
+ attr_mentionable :note, pipeline: :note
participant :author
belongs_to :project
@@ -84,14 +84,30 @@ class Note < ActiveRecord::Base
#
# This method uses ILIKE on PostgreSQL and LIKE on MySQL.
#
- # query - The search query as a String.
+ # query - The search query as a String.
+ # as_user - Limit results to those viewable by a specific user
#
# Returns an ActiveRecord::Relation.
- def search(query)
+ def search(query, as_user: nil)
table = arel_table
pattern = "%#{query}%"
- where(table[:note].matches(pattern))
+ found_notes = joins('LEFT JOIN issues ON issues.id = noteable_id').
+ where(table[:note].matches(pattern))
+
+ if as_user
+ found_notes.where('
+ issues.confidential IS NULL
+ OR issues.confidential IS FALSE
+ OR (issues.confidential IS TRUE
+ AND (issues.author_id = :user_id
+ OR issues.assignee_id = :user_id
+ OR issues.project_id IN(:project_ids)))',
+ user_id: as_user.id,
+ project_ids: as_user.authorized_projects.select(:id))
+ else
+ found_notes.where('issues.confidential IS NULL OR issues.confidential IS FALSE')
+ end
end
def grouped_awards
diff --git a/app/models/project.rb b/app/models/project.rb
index c1d9bae44c9..525a82c7534 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -309,21 +309,25 @@ class Project < ActiveRecord::Base
@repository ||= Repository.new(path_with_namespace, self)
end
+ def container_registry_path_with_namespace
+ path_with_namespace.downcase
+ end
+
def container_registry_repository
return unless Gitlab.config.registry.enabled
@container_registry_repository ||= begin
- token = Auth::ContainerRegistryAuthenticationService.full_access_token(path_with_namespace)
+ token = Auth::ContainerRegistryAuthenticationService.full_access_token(container_registry_path_with_namespace)
url = Gitlab.config.registry.api_url
host_port = Gitlab.config.registry.host_port
registry = ContainerRegistry::Registry.new(url, token: token, path: host_port)
- registry.repository(path_with_namespace)
+ registry.repository(container_registry_path_with_namespace)
end
end
def container_registry_repository_url
if Gitlab.config.registry.enabled
- "#{Gitlab.config.registry.host_port}/#{path_with_namespace}"
+ "#{Gitlab.config.registry.host_port}/#{container_registry_path_with_namespace}"
end
end
diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb
index 5fba6baa204..25b5d777641 100644
--- a/app/models/project_snippet.rb
+++ b/app/models/project_snippet.rb
@@ -7,5 +7,6 @@ class ProjectSnippet < Snippet
# Scopes
scope :fresh, -> { order("created_at DESC") }
- participant :author, :notes
+ participant :author
+ participant :notes_with_associations
end
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index 339fb0b9f9d..25d82929c0b 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -27,6 +27,10 @@ class ProjectWiki
@project.path_with_namespace + ".wiki"
end
+ def web_url
+ Gitlab::Routing.url_helpers.namespace_project_wiki_url(@project.namespace, @project, :home)
+ end
+
def url_to_repo
gitlab_shell.url_to_repo(path_with_namespace)
end
@@ -142,6 +146,16 @@ class ProjectWiki
wiki
end
+ def hook_attrs
+ {
+ web_url: web_url,
+ git_ssh_url: ssh_url_to_repo,
+ git_http_url: http_url_to_repo,
+ path_with_namespace: path_with_namespace,
+ default_branch: default_branch
+ }
+ end
+
private
def init_repo(path_with_namespace)
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 0a3c3b57669..407697b745c 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -30,7 +30,8 @@ class Snippet < ActiveRecord::Base
scope :public_and_internal, -> { where(visibility_level: [Snippet::PUBLIC, Snippet::INTERNAL]) }
scope :fresh, -> { order("created_at DESC") }
- participant :author, :notes
+ participant :author
+ participant :notes_with_associations
def self.reference_prefix
'$'
@@ -100,6 +101,10 @@ class Snippet < ActiveRecord::Base
content.lines.count > 1000
end
+ def notes_with_associations
+ notes.includes(:author, :project)
+ end
+
class << self
# Searches for snippets with a matching title or file name.
#
diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb
index 2bbab643e69..e57b95f21ec 100644
--- a/app/services/auth/container_registry_authentication_service.rb
+++ b/app/services/auth/container_registry_authentication_service.rb
@@ -1,13 +1,13 @@
module Auth
class ContainerRegistryAuthenticationService < BaseService
+ include Gitlab::CurrentSettings
+
AUDIENCE = 'container_registry'
def execute
return error('not found', 404) unless registry.enabled
- if params[:offline_token]
- return error('unauthorized', 401) unless current_user || project
- else
+ unless current_user || project
return error('forbidden', 403) unless scope
end
@@ -19,6 +19,7 @@ module Auth
token = JSONWebToken::RSAToken.new(registry.key)
token.issuer = registry.issuer
token.audience = AUDIENCE
+ token.expire_time = token_expire_at
token[:access] = names.map do |name|
{ type: 'repository', name: name, actions: %w(*) }
end
@@ -32,6 +33,7 @@ module Auth
token.issuer = registry.issuer
token.audience = params[:service]
token.subject = current_user.try(:username)
+ token.expire_time = ContainerRegistryAuthenticationService.token_expire_at
token[:access] = accesses.compact
token
end
@@ -77,5 +79,9 @@ module Auth
def registry
Gitlab.config.registry
end
+
+ def self.token_expire_at
+ Time.now + current_application_settings.container_registry_token_expire_delay.minutes
+ end
end
end
diff --git a/app/services/wiki_pages/base_service.rb b/app/services/wiki_pages/base_service.rb
index 9162f128602..4c0a2c6b4d8 100644
--- a/app/services/wiki_pages/base_service.rb
+++ b/app/services/wiki_pages/base_service.rb
@@ -6,9 +6,8 @@ module WikiPages
object_kind: page.class.name.underscore,
user: current_user.hook_attrs,
project: @project.hook_attrs,
- object_attributes: page.hook_attrs,
- # DEPRECATED
- repository: @project.hook_attrs.slice(:name, :url, :description, :homepage)
+ wiki: @project.wiki.hook_attrs,
+ object_attributes: page.hook_attrs
}
page_url = Gitlab::UrlBuilder.build(page)
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
index 2ab01704b77..862b86d9d4a 100644
--- a/app/views/admin/abuse_reports/_abuse_report.html.haml
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -16,7 +16,7 @@
.light.small
= time_ago_with_tooltip(abuse_report.created_at)
%td
- = markdown(abuse_report.message.squish!, pipeline: :single_line)
+ = markdown(abuse_report.message.squish!, pipeline: :single_line, author: reporter)
%td
- if user
= link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index df286852b97..f149f9eb431 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -178,6 +178,14 @@
.col-sm-10
= f.number_field :max_artifacts_size, class: 'form-control'
+ - if Gitlab.config.registry.enabled
+ %fieldset
+ %legend Container Registry
+ .form-group
+ = f.label :container_registry_token_expire_delay, 'Authorization token duration (minutes)', class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.number_field :container_registry_token_expire_delay, class: 'form-control'
+
%fieldset
%legend Metrics
%p
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index c9d1e454a5e..8c6a1552a53 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -4,6 +4,7 @@
%h3 Two-factor Authentication
.login-body
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
+ = f.hidden_field :remember_me, value: params[resource_name][:remember_me]
= f.text_field :otp_attempt, class: 'form-control', placeholder: 'Two-factor Authentication code', required: true, autofocus: true
%p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
.prepend-top-20
diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml
index dce4081288c..1bc9f604438 100644
--- a/app/views/events/_commit.html.haml
+++ b/app/views/events/_commit.html.haml
@@ -2,4 +2,4 @@
.commit-row-title
= link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: '', title: truncate_sha(commit[:id])
&middot;
- = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line
+ = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line, author: event.author
diff --git a/app/views/events/_event_issue.atom.haml b/app/views/events/_event_issue.atom.haml
index fad65310021..083c3936212 100644
--- a/app/views/events/_event_issue.atom.haml
+++ b/app/views/events/_event_issue.atom.haml
@@ -1,2 +1,2 @@
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- = markdown(issue.description, pipeline: :atom, project: issue.project)
+ = markdown(issue.description, pipeline: :atom, project: issue.project, author: issue.author)
diff --git a/app/views/events/_event_merge_request.atom.haml b/app/views/events/_event_merge_request.atom.haml
index 19bdc7b9ca5..d7e05600627 100644
--- a/app/views/events/_event_merge_request.atom.haml
+++ b/app/views/events/_event_merge_request.atom.haml
@@ -1,2 +1,2 @@
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- = markdown(merge_request.description, pipeline: :atom, project: merge_request.project)
+ = markdown(merge_request.description, pipeline: :atom, project: merge_request.project, author: merge_request.author)
diff --git a/app/views/events/_event_note.atom.haml b/app/views/events/_event_note.atom.haml
index b730ebbd5f9..1154f982821 100644
--- a/app/views/events/_event_note.atom.haml
+++ b/app/views/events/_event_note.atom.haml
@@ -1,2 +1,2 @@
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- = markdown(note.note, pipeline: :atom, project: note.project)
+ = markdown(note.note, pipeline: :atom, project: note.project, author: note.author)
diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml
index b271b9daff1..28bee1d0a33 100644
--- a/app/views/events/_event_push.atom.haml
+++ b/app/views/events/_event_push.atom.haml
@@ -6,7 +6,7 @@
%i
at
= commit[:timestamp].to_time.to_s(:short)
- %blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project)
+ %blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project, author: event.author)
- if event.commits_count > 15
%p
%i
diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml
index f9f623cc031..c7f29f2fc0e 100644
--- a/app/views/events/event/_common.html.haml
+++ b/app/views/events/event/_common.html.haml
@@ -4,7 +4,7 @@
= event_action_name(event)
- if event.target
- %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], title: event.target_title
+ %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], class: 'has-tooltip', title: event.target_title
= event_preposition(event)
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index 235bd46107e..dc4ff17e31a 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -15,7 +15,7 @@
%ul.well-list.event_commits
- few_commits = event.commits[0...2]
- few_commits.each do |commit|
- = render "events/commit", commit: commit, project: project
+ = render "events/commit", commit: commit, project: project, event: event
- create_mr = event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project)
- if event.commits_count > 1
diff --git a/app/views/kaminari/gitlab/_first_page.html.haml b/app/views/kaminari/gitlab/_first_page.html.haml
index ada7306d98d..e7a70e3bb28 100644
--- a/app/views/kaminari/gitlab/_first_page.html.haml
+++ b/app/views/kaminari/gitlab/_first_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the first page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li.first
diff --git a/app/views/kaminari/gitlab/_gap.html.haml b/app/views/kaminari/gitlab/_gap.html.haml
index 3ffd12f8587..80ca30f36e6 100644
--- a/app/views/kaminari/gitlab/_gap.html.haml
+++ b/app/views/kaminari/gitlab/_gap.html.haml
@@ -1,7 +1,7 @@
-# Non-link tag that stands for skipped pages...
-# available local variables
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li{class: "page"}
diff --git a/app/views/kaminari/gitlab/_last_page.html.haml b/app/views/kaminari/gitlab/_last_page.html.haml
index 3431d029bcc..53f780d1d1b 100644
--- a/app/views/kaminari/gitlab/_last_page.html.haml
+++ b/app/views/kaminari/gitlab/_last_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the last page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li.last
diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml
index c805914fc3f..125f09777ba 100644
--- a/app/views/kaminari/gitlab/_next_page.html.haml
+++ b/app/views/kaminari/gitlab/_next_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the next page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
- if current_page.last?
diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml
index a52d883b9a8..522e4d1d05f 100644
--- a/app/views/kaminari/gitlab/_page.html.haml
+++ b/app/views/kaminari/gitlab/_page.html.haml
@@ -3,7 +3,7 @@
-# page: a page object for "this" page
-# url: url to this page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li{class: "page#{' active' if page.current?}"}
diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml
index a12c53bcfe7..f5e0d2ed3f3 100644
--- a/app/views/kaminari/gitlab/_paginator.html.haml
+++ b/app/views/kaminari/gitlab/_paginator.html.haml
@@ -1,7 +1,7 @@
-# The container tag
-# available local variables
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
-# paginator: the paginator that renders the pagination tags inside
@@ -9,7 +9,7 @@
%div.gl-pagination
%ul.pagination.clearfix
- unless current_page.first?
- = first_page_tag unless num_pages < 5 # As kaminari will always show the first 5 pages
+ = first_page_tag unless total_pages < 5 # As kaminari will always show the first 5 pages
= prev_page_tag
- each_page do |page|
- if page.left_outer? || page.right_outer? || page.inside_window?
@@ -18,5 +18,5 @@
= gap_tag
= next_page_tag
- unless current_page.last?
- = last_page_tag unless num_pages < 5
+ = last_page_tag unless total_pages < 5
diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml
index afb20455e0a..7edf10498a8 100644
--- a/app/views/kaminari/gitlab/_prev_page.html.haml
+++ b/app/views/kaminari/gitlab/_prev_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the previous page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
- if current_page.first?
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 087b7472701..2c9b9006668 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -52,15 +52,6 @@
= icon('ship fw')
%span
Pipelines
- %span.badge.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count)
-
- - if project_nav_tab? :builds
- = nav_link(controller: %w(builds)) do
- = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
- = icon('cubes fw')
- %span
- Builds
- %span.badge.count.builds_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all))
- if project_nav_tab? :container_registry
= nav_link(controller: %w(container_registry)) do
@@ -132,4 +123,10 @@
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do
Create a new issue
+ -# Shortcut to builds page
+ - if project_nav_tab? :builds
+ %li.hidden
+ = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
+ Builds
+
.fade-right
diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml
index 12ded41fbf2..e9c66170877 100644
--- a/app/views/notify/_note_message.html.haml
+++ b/app/views/notify/_note_message.html.haml
@@ -2,4 +2,4 @@
%div
#{link_to @note.author_name, user_url(@note.author)} wrote:
%div
- = markdown(@note.note, pipeline: :email)
+ = markdown(@note.note, pipeline: :email, author: @note.author)
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index ad3ab2525bb..f42b150c0d6 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -2,7 +2,7 @@
%div
#{link_to @issue.author_name, user_url(@issue.author)} wrote:
-if @issue.description
- = markdown(@issue.description, pipeline: :email)
+ = markdown(@issue.description, pipeline: :email, author: @issue.author)
- if @issue.assignee_id.present?
%p
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 23423e7d981..158404de396 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -9,4 +9,4 @@
Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
-if @merge_request.description
- = markdown(@merge_request.description, pipeline: :email)
+ = markdown(@merge_request.description, pipeline: :email, author: @merge_request.author)
diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml
index 8fb9ebc1b8b..818d5d28f04 100644
--- a/app/views/projects/builds/index.html.haml
+++ b/app/views/projects/builds/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Builds"
+= render "projects/pipelines/head"
.top-area
%ul.nav-links
diff --git a/app/views/projects/ci/commits/_commit.html.haml b/app/views/projects/ci/commits/_commit.html.haml
index 5b6b940a0c4..5e3a4123a8e 100644
--- a/app/views/projects/ci/commits/_commit.html.haml
+++ b/app/views/projects/ci/commits/_commit.html.haml
@@ -63,9 +63,9 @@
%span #{build.name}
- if can?(current_user, :update_pipeline, @project)
- - if commit.retryable? && commit.builds.failed.any?
+ - if commit.retryable?
= link_to retry_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn has-tooltip', title: "Retry", method: :post do
= icon("repeat")
- - if commit.active?
+ - if commit.cancelable?
= link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
= icon("remove")
diff --git a/app/views/projects/commit/_ci_commit.html.haml b/app/views/projects/commit/_ci_commit.html.haml
index ce5c550b441..32ff4d30977 100644
--- a/app/views/projects/commit/_ci_commit.html.haml
+++ b/app/views/projects/commit/_ci_commit.html.haml
@@ -1,24 +1,24 @@
.row-content-block.build-content.middle-block
.pull-right
- - if can?(current_user, :update_pipeline, @project)
+ - if can?(current_user, :update_pipeline, ci_commit.project)
- if ci_commit.builds.latest.failed.any?(&:retryable?)
- = link_to "Retry failed", retry_namespace_project_pipeline_path(@project.namespace, @project, ci_commit.id), class: 'btn btn-grouped btn-primary', method: :post
+ = link_to "Retry failed", retry_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: 'btn btn-grouped btn-primary', method: :post
- if ci_commit.builds.running_or_pending.any?
- = link_to "Cancel running", cancel_namespace_project_pipeline_path(@project.namespace, @project, ci_commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
+ = link_to "Cancel running", cancel_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
.oneline.clearfix
- if defined?(pipeline_details) && pipeline_details
Pipeline
- = link_to "##{ci_commit.id}", namespace_project_pipeline_path(@project.namespace, @project, ci_commit.id), class: "monospace"
+ = link_to "##{ci_commit.id}", namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: "monospace"
with
= pluralize ci_commit.statuses.count(:id), "build"
- if ci_commit.ref
for
- = link_to ci_commit.ref, namespace_project_commits_path(@project.namespace, @project, ci_commit.ref), class: "monospace"
+ = link_to ci_commit.ref, namespace_project_commits_path(ci_commit.project.namespace, ci_commit.project, ci_commit.ref), class: "monospace"
- if defined?(link_to_commit) && link_to_commit
for commit
- = link_to ci_commit.short_sha, namespace_project_commit_path(@project.namespace, @project, ci_commit.sha), class: "monospace"
+ = link_to ci_commit.short_sha, namespace_project_commit_path(ci_commit.project.namespace, ci_commit.project, ci_commit.sha), class: "monospace"
- if ci_commit.duration
in
= time_interval_in_words ci_commit.duration
@@ -31,7 +31,7 @@
%li= error
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}
-- if @project.builds_enabled? && !ci_commit.ci_yaml_file
+- if ci_commit.project.builds_enabled? && !ci_commit.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
@@ -45,7 +45,7 @@
%th Tags
%th Duration
%th Finished at
- - if @project.build_coverage_enabled?
+ - if ci_commit.project.build_coverage_enabled?
%th Coverage
%th
- ci_commit.statuses.stages.each do |stage|
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 429bf041248..6674d58417b 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -63,10 +63,10 @@
.commit-box.content-block
%h3.commit-title
- = markdown escape_once(@commit.title), pipeline: :single_line
+ = markdown escape_once(@commit.title), pipeline: :single_line, author: @commit.author
- if @commit.description.present?
%pre.commit-description
- = preserve(markdown(escape_once(@commit.description), pipeline: :single_line))
+ = preserve(markdown(escape_once(@commit.description), pipeline: :single_line, author: @commit.author))
:javascript
$(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}");
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 655cb0ac3cb..367027182b6 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -24,7 +24,7 @@
- if commit.description?
.commit-row-description.js-toggle-content
%pre
- = preserve(markdown(escape_once(commit.description), pipeline: :single_line))
+ = preserve(markdown(escape_once(commit.description), pipeline: :single_line, author: commit.author))
.commit-row-info
by
diff --git a/app/views/projects/hooks/_project_hook.html.haml b/app/views/projects/hooks/_project_hook.html.haml
index 62eba5888a4..8151187d499 100644
--- a/app/views/projects/hooks/_project_hook.html.haml
+++ b/app/views/projects/hooks/_project_hook.html.haml
@@ -3,7 +3,7 @@
.col-md-8.col-lg-7
%strong.light-header= hook.url
%div
- - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
+ - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events wiki_page_events).each do |trigger|
- if hook.send(trigger)
%span.label.label-gray.deploy-project-label= trigger.titleize
.col-md-4.col-lg-5.text-right-lg.prepend-top-5
diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml
index cffe9a01a96..917a0b805b1 100644
--- a/app/views/projects/hooks/index.html.haml
+++ b/app/views/projects/hooks/index.html.haml
@@ -64,6 +64,13 @@
Build events
%p.light
This url will be triggered when the build status changes
+ %div
+ = f.check_box :wiki_page_events, class: 'pull-left'
+ .prepend-left-20
+ = f.label :wiki_page_events, class: 'label-light append-bottom-0' do
+ Wiki Page events
+ %p.light
+ This url will be triggered when a wiki page is created/updated
.form-group
= f.label :enable_ssl_verification, "SSL verification", class: "label-light"
%div
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index e95f42064ac..f3b0469b7d4 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -52,12 +52,12 @@
.issue-details.issuable-details
.detail-page-description.content-block
%h2.title
- = markdown escape_once(@issue.title), pipeline: :single_line
+ = markdown escape_once(@issue.title), pipeline: :single_line, author: @issue.author
- if @issue.description.present?
.description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' }
.wiki
= preserve do
- = markdown(@issue.description, cache_key: [@issue, "description"])
+ = markdown(@issue.description, cache_key: [@issue, "description"], author: @issue.author)
%textarea.hidden.js-task-list-field
= @issue.description
= edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue_edited_ago')
diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml
index a23bd8d18d0..ebf18f6ac85 100644
--- a/app/views/projects/merge_requests/show/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_box.html.haml
@@ -1,13 +1,13 @@
.detail-page-description.content-block
%h2.title
- = markdown escape_once(@merge_request.title), pipeline: :single_line
+ = markdown escape_once(@merge_request.title), pipeline: :single_line, author: @merge_request.author
%div
- if @merge_request.description.present?
.description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''}
.wiki
= preserve do
- = markdown(@merge_request.description, cache_key: [@merge_request, "description"])
+ = markdown(@merge_request.description, cache_key: [@merge_request, "description"], author: @merge_request.author)
%textarea.hidden.js-task-list-field
= @merge_request.description
diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml
index 55dbae598d3..13359abede7 100644
--- a/app/views/projects/merge_requests/widget/_open.html.haml
+++ b/app/views/projects/merge_requests/widget/_open.html.haml
@@ -26,4 +26,4 @@
%i.fa.fa-check
Accepting this merge request will close #{"issue".pluralize(@closes_issues.size)}
= succeed '.' do
- != markdown issues_sentence(@closes_issues), pipeline: :gfm
+ != markdown issues_sentence(@closes_issues), pipeline: :gfm, author: @merge_request.author
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 9fbc9a45549..f1045bbd8c3 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -29,7 +29,7 @@
.note-body{class: note_editable ? 'js-task-list-container' : ''}
.note-text
= preserve do
- = markdown(note.note, pipeline: :note, cache_key: [note, "note"])
+ = markdown(note.note, pipeline: :note, cache_key: [note, "note"], author: note.author)
- if note_editable
= render 'projects/notes/edit_form', note: note
= edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true)
diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml
new file mode 100644
index 00000000000..2c8ae625e67
--- /dev/null
+++ b/app/views/projects/pipelines/_head.html.haml
@@ -0,0 +1,14 @@
+%ul.nav-links
+ - if project_nav_tab? :pipelines
+ = nav_link(controller: :pipelines) do
+ = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
+ %span
+ Pipelines
+ %span.badge.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count)
+
+ - if project_nav_tab? :builds
+ = nav_link(controller: %w(builds)) do
+ = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
+ %span
+ Builds
+ %span.badge.count.builds_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all))
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index 8788db09dbe..453767920b5 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Pipelines"
+= render "projects/pipelines/head"
.top-area
%ul.nav-links
diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml
index 6ca919f7f80..43a6fdfd103 100644
--- a/app/views/projects/repositories/_feed.html.haml
+++ b/app/views/projects/repositories/_feed.html.haml
@@ -12,7 +12,7 @@
= link_to namespace_project_commits_path(@project.namespace, @project, commit.id) do
%code= commit.short_id
= image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: ''
- = markdown escape_once(truncate(commit.title, length: 40)), pipeline: :single_line
+ = markdown escape_once(truncate(commit.title, length: 40)), pipeline: :single_line, author: commit.author
%td
%span.pull-right.cgray
= time_ago_with_tooltip(commit.committed_date)
diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml
index 640890fbe92..8f68d6d1b87 100644
--- a/app/views/search/results/_issue.html.haml
+++ b/app/views/search/results/_issue.html.haml
@@ -7,7 +7,7 @@
- if issue.description.present?
.description.term
= preserve do
- = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project }))
+ = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project, author: issue.author }))
%span.light
#{issue.project.name_with_namespace}
- if issue.closed?
diff --git a/app/views/search/results/_merge_request.html.haml b/app/views/search/results/_merge_request.html.haml
index 333f6533213..6331c2bd6b0 100644
--- a/app/views/search/results/_merge_request.html.haml
+++ b/app/views/search/results/_merge_request.html.haml
@@ -6,7 +6,7 @@
- if merge_request.description.present?
.description.term
= preserve do
- = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project }))
+ = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project, author: merge_request.author }))
%span.light
#{merge_request.project.name_with_namespace}
.pull-right
diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml
index d9400b1d9fa..8163aff43b6 100644
--- a/app/views/search/results/_note.html.haml
+++ b/app/views/search/results/_note.html.haml
@@ -19,4 +19,4 @@
.note-search-result
.term
= preserve do
- = search_md_sanitize(markdown(note.note, {no_header_anchors: true}))
+ = search_md_sanitize(markdown(note.note, {no_header_anchors: true, author: note.author}))
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index e0d0d967da6..af753496260 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -4,7 +4,7 @@
= visibility_level_label(@snippet.visibility_level)
= visibility_level_icon(@snippet.visibility_level, fw: false)
%strong.item-title
- Snippet $#{@snippet.id}
+ Snippet #{@snippet.to_reference}
%span.creator
created by #{link_to_member(@project, @snippet.author, size: 24, author_class: "author item-title")}
= time_ago_with_tooltip(@snippet.created_at, placement: 'bottom', html_class: 'snippet_updated_ago')
@@ -21,4 +21,4 @@
.content-block.second-block
%h2.snippet-title.prepend-top-0.append-bottom-0
- = markdown escape_once(@snippet.title), pipeline: :single_line
+ = markdown escape_once(@snippet.title), pipeline: :single_line, author: @snippet.author
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index fa959fc56e3..971f969e25e 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -1,6 +1,7 @@
class EmailsOnPushWorker
include Sidekiq::Worker
+ sidekiq_options queue: :mailers
attr_reader :email, :skip_premailer
def perform(project_id, recipients, push_data, options = {})