Commit 32164bf7 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ce-to-ee-2018-10-09' into 'master'

CE upstream - 2018-10-09 07:18 UTC

See merge request gitlab-org/gitlab-ee!7841
parents bc7d0369 fb734b60
...@@ -826,7 +826,7 @@ GEM ...@@ -826,7 +826,7 @@ GEM
rubyzip (1.2.2) rubyzip (1.2.2)
rufus-scheduler (3.4.0) rufus-scheduler (3.4.0)
et-orbi (~> 1.0) et-orbi (~> 1.0)
rugged (0.27.4) rugged (0.27.5)
safe_yaml (1.0.4) safe_yaml (1.0.4)
sanitize (4.6.6) sanitize (4.6.6)
crass (~> 1.0.2) crass (~> 1.0.2)
......
...@@ -834,7 +834,7 @@ GEM ...@@ -834,7 +834,7 @@ GEM
rubyzip (1.2.2) rubyzip (1.2.2)
rufus-scheduler (3.4.0) rufus-scheduler (3.4.0)
et-orbi (~> 1.0) et-orbi (~> 1.0)
rugged (0.27.4) rugged (0.27.5)
safe_yaml (1.0.4) safe_yaml (1.0.4)
sanitize (4.6.6) sanitize (4.6.6)
crass (~> 1.0.2) crass (~> 1.0.2)
......
...@@ -395,7 +395,7 @@ Please check your network connection and try again.`; ...@@ -395,7 +395,7 @@ Please check your network connection and try again.`;
role="group"> role="group">
<button <button
type="button" type="button"
class="btn btn-default mr-2" class="btn btn-default"
@click="resolveHandler()" @click="resolveHandler()"
> >
<i <i
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
vertical-align: middle; vertical-align: middle;
.stage-cell .stage-container { .stage-cell .stage-container {
margin: 3px 3px 3px 0; margin: 0 3px 3px 0;
} }
.stage-container:last-child { .stage-container:last-child {
......
...@@ -67,7 +67,6 @@ class ApplicationController < ActionController::Base ...@@ -67,7 +67,6 @@ class ApplicationController < ActionController::Base
end end
rescue_from Gitlab::Git::Storage::Inaccessible, GRPC::Unavailable, Gitlab::Git::CommandError do |exception| rescue_from Gitlab::Git::Storage::Inaccessible, GRPC::Unavailable, Gitlab::Git::CommandError do |exception|
Raven.capture_exception(exception) if sentry_enabled?
log_exception(exception) log_exception(exception)
headers['Retry-After'] = exception.retry_after if exception.respond_to?(:retry_after) headers['Retry-After'] = exception.retry_after if exception.respond_to?(:retry_after)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
class Projects::JobsController < Projects::ApplicationController class Projects::JobsController < Projects::ApplicationController
include SendFileUpload include SendFileUpload
include ContinueParams
before_action :build, except: [:index, :cancel_all] before_action :build, except: [:index, :cancel_all]
before_action :authorize_read_build! before_action :authorize_read_build!
...@@ -107,7 +108,12 @@ class Projects::JobsController < Projects::ApplicationController ...@@ -107,7 +108,12 @@ class Projects::JobsController < Projects::ApplicationController
return respond_422 unless @build.cancelable? return respond_422 unless @build.cancelable?
@build.cancel @build.cancel
redirect_to build_path(@build)
if continue_params
redirect_to continue_params[:to]
else
redirect_to builds_project_pipeline_path(@project, @build.pipeline.id)
end
end end
def unschedule def unschedule
......
...@@ -47,12 +47,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -47,12 +47,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@noteable = @merge_request @noteable = @merge_request
@commits_count = @merge_request.commits_count @commits_count = @merge_request.commits_count
# TODO cleanup- Fatih Simon Create an issue to remove these after the refactoring
# we no longer render notes here. I see it will require a small frontend refactoring,
# since we gather some data from this collection.
@discussions = @merge_request.discussions
@notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
labels labels
set_pipeline_variables set_pipeline_variables
......
# frozen_string_literal: true
# Finder for retrieving the pending todos of a user, optionally filtered using
# various fields.
#
# While this finder is a bit more verbose compared to use
# `where(params.slice(...))`, it allows us to decouple the input parameters from
# the actual column names. For example, if we ever decide to use separate
# columns for target types (e.g. `issue_id`, `merge_request_id`, etc), we no
# longer need to change _everything_ that uses this finder. Instead, we just
# change the various `by_*` methods in this finder, without having to touch
# everything that uses it.
class PendingTodosFinder
attr_reader :current_user, :params
# current_user - The user to retrieve the todos for.
# params - A Hash containing columns and values to use for filtering todos.
def initialize(current_user, params = {})
@current_user = current_user
@params = params
end
def execute
todos = current_user.todos.pending
todos = by_project(todos)
todos = by_target_id(todos)
todos = by_target_type(todos)
todos = by_commit_id(todos)
todos
end
def by_project(todos)
if (id = params[:project_id])
todos.for_project(id)
else
todos
end
end
def by_target_id(todos)
if (id = params[:target_id])
todos.for_target(id)
else
todos
end
end
def by_target_type(todos)
if (type = params[:target_type])
todos.for_type(type)
else
todos
end
end
def by_commit_id(todos)
if (id = params[:commit_id])
todos.for_commit(id)
else
todos
end
end
end
...@@ -23,6 +23,8 @@ class TodosFinder ...@@ -23,6 +23,8 @@ class TodosFinder
NONE = '0'.freeze NONE = '0'.freeze
TODO_TYPES = Set.new(%w(Issue MergeRequest Epic)).freeze
attr_accessor :current_user, :params attr_accessor :current_user, :params
def initialize(current_user, params = {}) def initialize(current_user, params = {})
...@@ -45,6 +47,13 @@ class TodosFinder ...@@ -45,6 +47,13 @@ class TodosFinder
sort(items) sort(items)
end end
# Returns `true` if the current user has any todos for the given target.
#
# target - The value of the `target_type` column, such as `Issue`.
def any_for_target?(target)
current_user.todos.any_for_target?(target)
end
private private
def action_id? def action_id?
...@@ -72,14 +81,11 @@ class TodosFinder ...@@ -72,14 +81,11 @@ class TodosFinder
end end
def author def author
return @author if defined?(@author) strong_memoize(:author) do
@author =
if author? && params[:author_id] != NONE if author? && params[:author_id] != NONE
User.find(params[:author_id]) User.find(params[:author_id])
else
nil
end end
end
end end
def project? def project?
...@@ -91,17 +97,9 @@ class TodosFinder ...@@ -91,17 +97,9 @@ class TodosFinder
end end
def project def project
return @project if defined?(@project) strong_memoize(:project) do
Project.find_without_deleted(params[:project_id]) if project?
if project?
@project = Project.find(params[:project_id])
@project = nil if @project.pending_delete?
else
@project = nil
end end
@project
end end
def group def group
...@@ -111,7 +109,7 @@ class TodosFinder ...@@ -111,7 +109,7 @@ class TodosFinder
end end
def type? def type?
type.present? && %w(Issue MergeRequest Epic).include?(type) type.present? && TODO_TYPES.include?(type)
end end
def type def type
...@@ -119,77 +117,66 @@ class TodosFinder ...@@ -119,77 +117,66 @@ class TodosFinder
end end
def sort(items) def sort(items)
params[:sort] ? items.sort_by_attribute(params[:sort]) : items.order_id_desc if params[:sort]
items.sort_by_attribute(params[:sort])
else
items.order_id_desc
end
end end
# rubocop: disable CodeReuse/ActiveRecord
def by_action(items) def by_action(items)
if action? if action?
items = items.where(action: to_action_id) items.for_action(to_action_id)
else
items
end end
items
end end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def by_action_id(items) def by_action_id(items)
if action_id? if action_id?
items = items.where(action: action_id) items.for_action(action_id)
else
items
end end
items
end end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def by_author(items) def by_author(items)
if author? if author?
items = items.where(author_id: author.try(:id)) items.for_author(author)
else
items
end end
items
end end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def by_project(items) def by_project(items)
if project? if project?
items = items.where(project: project) items.for_project(project)
else
items
end end
items
end end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def by_group(items) def by_group(items)
return items unless group? if group?
items.for_group_and_descendants(group)
groups = group.self_and_descendants else
project_todos = items.where(project_id: Project.where(group: groups).select(:id)) items
group_todos = items.where(group_id: groups.select(:id)) end
Todo.from_union([project_todos, group_todos])
end end
# rubocop: enable CodeReuse/ActiveRecord
def by_state(items) def by_state(items)
case params[:state].to_s if params[:state].to_s == 'done'
when 'done'
items.done items.done
else else
items.pending items.pending
end end
end end
# rubocop: disable CodeReuse/ActiveRecord
def by_type(items) def by_type(items)
if type? if type?
items = items.where(target_type: type) items.for_type(type)
else
items
end end
items
end end
# rubocop: enable CodeReuse/ActiveRecord
end end
# frozen_string_literal: true
# Finder that given a target (e.g. an issue) finds all the users that have
# pending todos for said target.
class UsersWithPendingTodosFinder
attr_reader :target
# target - The target, such as an Issue or MergeRequest.
def initialize(target)
@target = target
end
def execute
User.for_todos(target.todos.pending)
end
end
...@@ -144,7 +144,7 @@ module NotesHelper ...@@ -144,7 +144,7 @@ module NotesHelper
def initial_notes_data(autocomplete) def initial_notes_data(autocomplete)
{ {
notesUrl: notes_url, notesUrl: notes_url,
notesIds: @notes.map(&:id), notesIds: @noteable.notes.pluck(:id), # rubocop: disable CodeReuse/ActiveRecord
now: Time.now.to_i, now: Time.now.to_i,
diffView: diff_view, diffView: diff_view,
enableGFM: { enableGFM: {
......
...@@ -391,6 +391,13 @@ class Project < ActiveRecord::Base ...@@ -391,6 +391,13 @@ class Project < ActiveRecord::Base
only_integer: true, only_integer: true,
message: 'needs to be beetween 10 minutes and 1 month' } message: 'needs to be beetween 10 minutes and 1 month' }
# Returns a project, if it is not about to be removed.
#
# id - The ID of the project to retrieve.
def self.find_without_deleted(id)
without_deleted.find_by_id(id)
end
# Paginates a collection using a `WHERE id < ?` condition. # Paginates a collection using a `WHERE id < ?` condition.
# #
# before - A project ID to use for filtering out projects with an equal or # before - A project ID to use for filtering out projects with an equal or
...@@ -455,6 +462,7 @@ class Project < ActiveRecord::Base ...@@ -455,6 +462,7 @@ class Project < ActiveRecord::Base
scope :joins_import_state, -> { joins("LEFT JOIN project_mirror_data import_state ON import_state.project_id = projects.id") } scope :joins_import_state, -> { joins("LEFT JOIN project_mirror_data import_state ON import_state.project_id = projects.id") }
scope :import_started, -> { joins_import_state.where("import_state.status = 'started' OR projects.import_status = 'started'") } scope :import_started, -> { joins_import_state.where("import_state.status = 'started' OR projects.import_status = 'started'") }
scope :for_group, -> (group) { where(group: group) }
class << self class << self
# Searches for a list of projects based on the query given in `query`. # Searches for a list of projects based on the query given in `query`.
......
...@@ -41,6 +41,13 @@ class Todo < ActiveRecord::Base ...@@ -41,6 +41,13 @@ class Todo < ActiveRecord::Base
scope :pending, -> { with_state(:pending) } scope :pending, -> { with_state(:pending) }
scope :done, -> { with_state(:done) } scope :done, -> { with_state(:done) }
scope :for_action, -> (action) { where(action: action) }
scope :for_author, -> (author) { where(author: author) }
scope :for_project, -> (project) { where(project: project) }
scope :for_group, -> (group) { where(group: group) }
scope :for_type, -> (type) { where(target_type: type) }
scope :for_target, -> (id) { where(target_id: id) }
scope :for_commit, -> (id) { where(commit_id: id) }
state_machine :state, initial: :pending do state_machine :state, initial: :pending do
event :done do event :done do
...@@ -54,6 +61,42 @@ class Todo < ActiveRecord::Base ...@@ -54,6 +61,42 @@ class Todo < ActiveRecord::Base
after_save :keep_around_commit, if: :commit_id after_save :keep_around_commit, if: :commit_id
class << self class << self
# Returns all todos for the given group and its descendants.
#
# group - A `Group` to retrieve todos for.
#
# Returns an `ActiveRecord::Relation`.
def for_group_and_descendants(group)
groups = group.self_and_descendants
from_union([
for_project(Project.for_group(groups)),
for_group(groups)
])
end
# Returns `true` if the current user has any todos for the given target.
#
# target - The value of the `target_type` column, such as `Issue`.
def any_for_target?(target)
exists?(target: target)
end
# Updates the state of a relation of todos to the new state.
#
# new_state - The new state of the todos.
#
# Returns an `Array` containing the IDs of the updated todos.
def update_state(new_state)
# Only update those that are not really on that state
base = where.not(state: new_state).except(:order)
ids = base.pluck(:id)
base.update_all(state: new_state)
ids
end
# Priority sorting isn't displayed in the dropdown, because we don't show # Priority sorting isn't displayed in the dropdown, because we don't show
# milestones, but still show something if the user has a URL with that # milestones, but still show something if the user has a URL with that
# selected. # selected.
......
...@@ -274,6 +274,7 @@ class User < ActiveRecord::Base ...@@ -274,6 +274,7 @@ class User < ActiveRecord::Base
scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'ASC')) } scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'ASC')) }
scope :confirmed, -> { where.not(confirmed_at: nil) } scope :confirmed, -> { where.not(confirmed_at: nil) }
scope :by_username, -> (usernames) { iwhere(username: usernames) } scope :by_username, -> (usernames) { iwhere(username: usernames) }
scope :for_todos, -> (todos) { where(id: todos.select(:user_id)) }
# Limits the users to those that have TODOs, optionally in the given state. # Limits the users to those that have TODOs, optionally in the given state.
# #
...@@ -1388,6 +1389,10 @@ class User < ActiveRecord::Base ...@@ -1388,6 +1389,10 @@ class User < ActiveRecord::Base
!consented_usage_stats? && 7.days.ago > self.created_at && !has_current_license? && User.single_user? !consented_usage_stats? && 7.days.ago > self.created_at && !has_current_license? && User.single_user?
end end
def todos_limited_to(ids)
todos.where(id: ids)
end
# @deprecated # @deprecated
alias_method :owned_or_masters_groups, :owned_or_maintainers_groups alias_method :owned_or_masters_groups, :owned_or_maintainers_groups
......
...@@ -43,15 +43,13 @@ class TodoService ...@@ -43,15 +43,13 @@ class TodoService
# collects the todo users before the todos themselves are deleted, then # collects the todo users before the todos themselves are deleted, then
# updates the todo counts for those users. # updates the todo counts for those users.
# #
# rubocop: disable CodeReuse/ActiveRecord
def destroy_target(target) def destroy_target(target)
todo_users = User.where(id: target.todos.pending.select(:user_id)).to_a todo_users = UsersWithPendingTodosFinder.new(target).execute.to_a
yield target yield target
todo_users.each(&:update_todos_count_cache) todo_users.each(&:update_todos_count_cache)
end end
# rubocop: enable CodeReuse/ActiveRecord
# When we reassign an issue we should: # When we reassign an issue we should:
# #
...@@ -202,30 +200,23 @@ class TodoService ...@@ -202,30 +200,23 @@ class TodoService
create_todos(current_user, attributes) create_todos(current_user, attributes)
end end
# rubocop: disable CodeReuse/ActiveRecord
def todo_exist?(issuable, current_user) def todo_exist?(issuable, current_user)
TodosFinder.new(current_user).execute.exists?(target: issuable) TodosFinder.new(current_user).any_for_target?(issuable)
end end
# rubocop: enable CodeReuse/ActiveRecord
private private
# rubocop: disable CodeReuse/ActiveRecord
def todos_by_ids(ids, current_user) def todos_by_ids(ids, current_user)
current_user.todos.where(id: Array(ids)) current_user.todos_limited_to(Array(ids))
end end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def update_todos_state(todos, current_user, state) def update_todos_state(todos, current_user, state)
# Only update those that are not really on that state todos_ids = todos.update_state(state)
todos = todos.where.not(state: state)
todos_ids = todos.pluck(:id)
todos.unscope(:order).update_all(state: state)
current_user.update_todos_count_cache current_user.update_todos_count_cache
todos_ids todos_ids
end end
# rubocop: enable CodeReuse/ActiveRecord
def create_todos(users, attributes) def create_todos(users, attributes)
Array(users).map do |user| Array(users).map do |user|
...@@ -350,10 +341,7 @@ class TodoService ...@@ -350,10 +341,7 @@ class TodoService
end end
end end
# rubocop: disable CodeReuse/ActiveRecord
def pending_todos(user, criteria = {}) def pending_todos(user, criteria = {})
valid_keys = [:project_id, :target_id, :target_type, :commit_id] PendingTodosFinder.new(user, criteria).execute
user.todos.pending.where(criteria.slice(*valid_keys))
end end
# rubocop: enable CodeReuse/ActiveRecord
end end
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
= markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a bullet list") }) = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a bullet list") })
= markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a numbered list") }) = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a numbered list") })
= markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a task list") }) = markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a task list") })
= markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header 1 | header 2 |\n| -------- | -------- |\n| cell 1 | cell 2 |\n| cell 3 | cell 4 |", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a table") }) = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a table") })
= markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _('Add a table') })
%button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: s_("MarkdownToolbar|Go full screen"), data: { container: "body" } } %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: s_("MarkdownToolbar|Go full screen"), data: { container: "body" } }
= sprite_icon("screen-full") = sprite_icon("screen-full")
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
.form-group.project-path.col-sm-6 .form-group.project-path.col-sm-6
= f.label :path, class: 'label-bold' do = f.label :path, class: 'label-bold' do
%span= _("Project slug") %span= _("Project slug")
= f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 2, required: true = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", required: true
- if current_user.can_create_group? - if current_user.can_create_group?
.form-text.text-muted .form-text.text-muted
Want to house several dependent projects under the same namespace? Want to house several dependent projects under the same namespace?
...@@ -61,5 +61,5 @@ ...@@ -61,5 +61,5 @@
.option-description .option-description
Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository. Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.
= f.submit 'Create project', class: "btn btn-success project-submit", tabindex: 4, data: { track_label: "#{track_label}", track_event: "click_button", track_property: "create_project", track_value: "" } = f.submit 'Create project', class: "btn btn-success project-submit", data: { track_label: "#{track_label}", track_event: "click_button", track_property: "create_project", track_value: "" }
= link_to 'Cancel', dashboard_projects_path, class: 'btn btn-cancel', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "cancel" } = link_to 'Cancel', dashboard_projects_path, class: 'btn btn-cancel', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "cancel" }
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
= sprite_icon('download') = sprite_icon('download')
- if can?(current_user, :update_build, job) - if can?(current_user, :update_build, job)
- if job.active? - if job.active?
= link_to cancel_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do = link_to cancel_project_job_path(job.project, job, continue: { to: request.fullpath }), method: :post, title: 'Cancel', class: 'btn btn-build' do
= icon('remove', class: 'cred') = icon('remove', class: 'cred')
- elsif job.scheduled? - elsif job.scheduled?
.btn-group .btn-group
......
...@@ -6,14 +6,13 @@ class PruneOldEventsWorker ...@@ -6,14 +6,13 @@ class PruneOldEventsWorker
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform def perform
# Contribution calendar shows maximum 12 months of events. # Contribution calendar shows maximum 12 months of events, we retain 2 years for data integrity.
# Double nested query is used because MySQL doesn't allow DELETE subqueries # Double nested query is used because MySQL doesn't allow DELETE subqueries on the same table.
# on the same table.
Event.unscoped.where( Event.unscoped.where(
'(id IN (SELECT id FROM (?) ids_to_remove))', '(id IN (SELECT id FROM (?) ids_to_remove))',
Event.unscoped.where( Event.unscoped.where(
'created_at < ?', 'created_at < ?',
(12.months + 1.day).ago) (2.years + 1.day).ago)
.select(:id) .select(:id)
.limit(10_000)) .limit(10_000))
.delete_all .delete_all
......
---
title: Fix incorrect spacing between buttons when commenting on a MR.
merge_request: 22135
author:
type: fixed
---
title: Vertical align Pipeline Graph in Commit Page
merge_request: 22173
author: Johann Hubert Sonntagbauer
type: fixed
---
title: Focus project slug on tab navigation
merge_request: 22198
author:
type: other
---
title: Redirect to the pipeline builds page when a build is canceled
merge_request:
author: Eva Kadlecova
type: fixed
---
title: Increased retained event data by extending events pruner timeframe to 2 years
merge_request: 22145
author:
type: changed
---
title: Remove duplicate button from the markdown header toolbar
merge_request: 22192
author: George Tsiolis
type: changed
---
title: Enable more frozen string in lib/**/*.rb
merge_request:
author: gfyoung
type: performance
---
title: Removes expensive dead code on main MR page request
merge_request: 22153
author:
type: performance
---
title: 'Rails 5: fix mysql milliseconds problems in scheduled build specs'
merge_request: 22170
author: Jasper Maes
type: other
...@@ -52,6 +52,9 @@ Hooks can be also placed in `hooks/<hook_name>.d` (global) or ...@@ -52,6 +52,9 @@ Hooks can be also placed in `hooks/<hook_name>.d` (global) or
`custom_hooks/<hook_name>.d` (per project) directories supporting chained `custom_hooks/<hook_name>.d` (per project) directories supporting chained
execution of the hooks. execution of the hooks.
NOTE: **Note:** `<hook_name>.d` would need to be either `pre-receive.d`,
`post-receive.d`, or `update.d` to work properly. Any other names will be ignored.
To look in a different directory for the global custom hooks (those in To look in a different directory for the global custom hooks (those in
`hooks/<hook_name.d>`), set `custom_hooks_dir` in gitlab-shell config. For `hooks/<hook_name.d>`), set `custom_hooks_dir` in gitlab-shell config. For
Omnibus installations, this can be set in `gitlab.rb`; and in source Omnibus installations, this can be set in `gitlab.rb`; and in source
......
...@@ -44,7 +44,7 @@ YYYY-MM-DD ...@@ -44,7 +44,7 @@ YYYY-MM-DD
### Event Time Period Limit ### Event Time Period Limit
GitLab removes events older than 1 year from the events table for performance reasons. The range of 1 year was chosen because user contribution calendars only show contributions of the past year. GitLab removes events older than 2 years from the events table for performance reasons.
## List currently authenticated user's events ## List currently authenticated user's events
......
...@@ -461,25 +461,25 @@ that runner. ...@@ -461,25 +461,25 @@ that runner.
> - If the repository is private you need to authenticate your GitLab Runner in the > - If the repository is private you need to authenticate your GitLab Runner in the
> registry. Learn more about how [GitLab Runner works in this case][runner-priv-reg]. > registry. Learn more about how [GitLab Runner works in this case][runner-priv-reg].
As an example, let's assume that you want to use the `registry.example.com/private/image:latest` As an example, let's assume that you want to use the `registry.example.com:5000/private/image:latest`
image which is private and requires you to login into a private container registry. image which is private and requires you to login into a private container registry.
Let's also assume that these are the login credentials: Let's also assume that these are the login credentials:
| Key | Value | | Key | Value |
|----------|----------------------| |----------|---------------------------|
| registry | registry.example.com | | registry | registry.example.com:5000 |
| username | my_username | | username | my_username |
| password | my_password | | password | my_password |
To configure access for `registry.example.com`, follow these steps: To configure access for `registry.example.com:5000`, follow these steps:
1. Find what the value of `DOCKER_AUTH_CONFIG` should be. There are two ways to 1. Find what the value of `DOCKER_AUTH_CONFIG` should be. There are two ways to
accomplish this: accomplish this:
- **First way -** Do a `docker login` on your local machine: - **First way -** Do a `docker login` on your local machine:
```bash ```bash
docker login registry.example.com --username my_username --password my_password docker login registry.example.com:5000 --username my_username --password my_password
``` ```
Then copy the content of `~/.docker/config.json`. Then copy the content of `~/.docker/config.json`.
...@@ -503,7 +503,7 @@ To configure access for `registry.example.com`, follow these steps: ...@@ -503,7 +503,7 @@ To configure access for `registry.example.com`, follow these steps:
```json ```json
{ {
"auths": { "auths": {
"registry.example.com": { "registry.example.com:5000": {
"auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=" "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
} }
} }
...@@ -515,22 +515,28 @@ To configure access for `registry.example.com`, follow these steps: ...@@ -515,22 +515,28 @@ To configure access for `registry.example.com`, follow these steps:
registry from it: registry from it:
```bash ```bash
docker logout registry.example.com docker logout registry.example.com:5000
``` ```
1. You can now use any private image from `registry.example.com` defined in 1. You can now use any private image from `registry.example.com:5000` defined in
`image` and/or `services` in your `.gitlab-ci.yml` file: `image` and/or `services` in your `.gitlab-ci.yml` file:
```yaml ```yaml
image: my.registry.tld:5000/namespace/image:tag image: registry.example.com:5000/namespace/image:tag
``` ```
In the example above, GitLab Runner will look at `my.registry.tld:5000` for the In the example above, GitLab Runner will look at `registry.example.com:5000` for the
image `namespace/image:tag`. image `namespace/image:tag`.
You can add configuration for as many registries as you want, adding more You can add configuration for as many registries as you want, adding more
registries to the `"auths"` hash as described above. registries to the `"auths"` hash as described above.
NOTE: **Note:** The full `hostname:port` combination is required everywhere
for the Runner to match the `DOCKER_AUTH_CONFIG`. For example, if
`registry.example.com:5000/namespace/image:tag` is specified in `.gitlab-ci.yml`,
then the `DOCKER_AUTH_CONFIG` must also specify `registry.example.com:5000`.
Specifying only `registry.example.com` will not work.
## Configuring services ## Configuring services
Many services accept environment variables which allow you to easily change Many services accept environment variables which allow you to easily change
......
...@@ -25,6 +25,12 @@ Two things need to be configured for the interactive web terminal to work: ...@@ -25,6 +25,12 @@ Two things need to be configured for the interactive web terminal to work:
NOTE: **Note:** Not all executors are NOTE: **Note:** Not all executors are
[supported](https://docs.gitlab.com/runner/executors/#compatibility-chart). [supported](https://docs.gitlab.com/runner/executors/#compatibility-chart).
NOTE: **Note:** The `docker` executor does not keep running
after the build script is finished. At that point, the terminal will automatically
disconnect and will not wait for the user to finish. Please follow [this
issue](https://gitlab.com/gitlab-org/gitlab-runner/issues/3605) for updates on
improving this behavior.
Sometimes, when a job is running, things don't go as you would expect, and it Sometimes, when a job is running, things don't go as you would expect, and it
would be helpful if one can have a shell to aid debugging. When a job is would be helpful if one can have a shell to aid debugging. When a job is
running, on the right panel you can see a button `debug` that will open the terminal running, on the right panel you can see a button `debug` that will open the terminal
......
...@@ -200,7 +200,7 @@ Likewise, group-level variables can be added by going to your group's ...@@ -200,7 +200,7 @@ Likewise, group-level variables can be added by going to your group's
**Settings > CI/CD**, then finding the section called **Variables**. **Settings > CI/CD**, then finding the section called **Variables**.
Any variables of [subgroups] will be inherited recursively. Any variables of [subgroups] will be inherited recursively.
![Variables](img/secret_variables.png) ![Variables](img/variables.png)
Once you set them, they will be available for all subsequent pipelines. You can also Once you set them, they will be available for all subsequent pipelines. You can also
[protect your variables](#protected-variables). [protect your variables](#protected-variables).
......
...@@ -102,10 +102,13 @@ rspec: ...@@ -102,10 +102,13 @@ rspec:
- $RSPEC - $RSPEC
``` ```
In the example above, the `rspec` job is going to inherit from the `.tests` In the example above, the `rspec` job inherits from the `.tests` template job.
template job. GitLab will perform a reverse deep merge, which means that it will GitLab will perform a reverse deep merge based on the keys. GitLab will:
merge the `rspec` contents into `.tests` recursively, and this is going to result in
the following `rspec` job: - Merge the `rspec` contents into `.tests` recursively.
- Not merge the values of the keys.
This results in the following `rspec` job:
```yaml ```yaml
rspec: rspec:
...@@ -118,6 +121,11 @@ rspec: ...@@ -118,6 +121,11 @@ rspec:
- $RSPEC - $RSPEC
``` ```
NOTE: **Note:**
Note that `script: rake test` has been overwritten by `script: rake rspec`.
If you do want to include the `rake test`, have a look at [before_script-and-after_script](#before_script-and-after_script).
`.tests` in this example is a [hidden key](#hidden-keys-jobs), but it's `.tests` in this example is a [hidden key](#hidden-keys-jobs), but it's
possible to inherit from regular jobs as well. possible to inherit from regular jobs as well.
......
# Merge Request Checklist # Merge Request Checklist
When creating a merge request that performs database related changes (schema When creating a merge request that performs database related changes (schema
changes, adjusting queries to optimise performance, etc) you should use the changes, adjusting queries to optimize performance, etc) you should use the
merge request template called "Database Changes". This template contains a merge request template called "Database changes". This template contains a
checklist of steps to follow to make sure the changes are up to snuff. checklist of steps to follow to make sure the changes are up to snuff.
To use the checklist, create a new merge request and click on the "Choose a To use the checklist, create a new merge request and click on the "Choose a
template" dropdown, then click "Database Changes". template" dropdown, then click "Database changes".
An example of this checklist can be found at An example of this checklist can be found at
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12463. <https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12463>.
The source code of the checklist can be found in at The source code of the checklist can be found in at
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab/merge_request_templates/Database%20Changes.md <https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab/merge_request_templates/Database%20changes.md>
...@@ -12,7 +12,7 @@ Since installations from source don't have Runit, Sidekiq can't be terminated an ...@@ -12,7 +12,7 @@ Since installations from source don't have Runit, Sidekiq can't be terminated an
## Select Version to Install ## Select Version to Install
Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) from the branch (version) of GitLab you would like to install (e.g., `11-3-stable`). Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) from the branch (version) of GitLab you would like to install (e.g., `11-4-stable`).
You can select the branch in the version dropdown in the top left corner of GitLab (below the menu bar). You can select the branch in the version dropdown in the top left corner of GitLab (below the menu bar).
If the highest number stable branch is unclear please check the [GitLab Blog](https://about.gitlab.com/blog/) for installation guide links by version. If the highest number stable branch is unclear please check the [GitLab Blog](https://about.gitlab.com/blog/) for installation guide links by version.
...@@ -300,9 +300,9 @@ sudo usermod -aG redis git ...@@ -300,9 +300,9 @@ sudo usermod -aG redis git
### Clone the Source ### Clone the Source
# Clone GitLab repository # Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 11-3-stable gitlab sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 11-4-stable gitlab
**Note:** You can change `11-3-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! **Note:** You can change `11-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It ### Configure It
......
...@@ -23,7 +23,7 @@ This page gathers all the resources for the topic **Authentication** within GitL ...@@ -23,7 +23,7 @@ This page gathers all the resources for the topic **Authentication** within GitL
- [How to Configure LDAP with GitLab CE](../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md) - [How to Configure LDAP with GitLab CE](../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md)
- [How to Configure LDAP with GitLab EE](../../administration/auth/how_to_configure_ldap_gitlab_ee/index.md) - [How to Configure LDAP with GitLab EE](../../administration/auth/how_to_configure_ldap_gitlab_ee/index.md)
- [Feature Highlight: LDAP Integration](https://about.gitlab.com/2014/07/10/feature-highlight-ldap-sync/) - [Feature Highlight: LDAP Integration](https://about.gitlab.com/2014/07/10/feature-highlight-ldap-sync/)
- [Debugging LDAP](https://about.gitlab.com/handbook/support/workflows/ldap/debugging_ldap.html) - [Debugging LDAP](https://about.gitlab.com/handbook/support/workflows/support-engineering/ldap/debugging_ldap.html)
- **Integrations:** - **Integrations:**
- [OmniAuth](../../integration/omniauth.md) - [OmniAuth](../../integration/omniauth.md)
- [Authentiq OmniAuth Provider](../../administration/auth/authentiq.md#authentiq-omniauth-provider) - [Authentiq OmniAuth Provider](../../administration/auth/authentiq.md#authentiq-omniauth-provider)
...@@ -42,7 +42,7 @@ This page gathers all the resources for the topic **Authentication** within GitL ...@@ -42,7 +42,7 @@ This page gathers all the resources for the topic **Authentication** within GitL
## Third-party resources ## Third-party resources
- [Kanboard Plugin GitLab Authentication](https://kanboard.net/plugin/gitlab-auth) - [Kanboard Plugin GitLab Authentication](https://github.com/kanboard/plugin-gitlab-auth)
- [Jenkins GitLab OAuth Plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitLab+OAuth+Plugin) - [Jenkins GitLab OAuth Plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitLab+OAuth+Plugin)
- [Set up Gitlab CE with Active Directory authentication](https://www.caseylabs.com/setup-gitlab-ce-with-active-directory-authentication/) - [Set up Gitlab CE with Active Directory authentication](https://www.caseylabs.com/setup-gitlab-ce-with-active-directory-authentication/)
- [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/) - [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/)
......
...@@ -15,7 +15,7 @@ need to ensure your own [Runners are configured](../../ci/runners/README.md) and ...@@ -15,7 +15,7 @@ need to ensure your own [Runners are configured](../../ci/runners/README.md) and
Before creating and connecting your Kubernetes cluster to your GitLab project, Before creating and connecting your Kubernetes cluster to your GitLab project,
you need a Google Cloud Platform account. If you don't already have one, you need a Google Cloud Platform account. If you don't already have one,
sign up at https://console.cloud.google.com. You'll need to either sign in with an existing sign up at <https://console.cloud.google.com>. You'll need to either sign in with an existing
Google account (for example, one that you use to access Gmail, Drive, etc.) or create a new one. Google account (for example, one that you use to access Gmail, Drive, etc.) or create a new one.
1. Follow the steps as outlined in the ["Before you begin" section of the Kubernetes Engine docs](https://cloud.google.com/kubernetes-engine/docs/quickstart#before-you-begin) 1. Follow the steps as outlined in the ["Before you begin" section of the Kubernetes Engine docs](https://cloud.google.com/kubernetes-engine/docs/quickstart#before-you-begin)
...@@ -205,7 +205,7 @@ applications. In the rightmost column for the production environment, you can ma ...@@ -205,7 +205,7 @@ applications. In the rightmost column for the production environment, you can ma
application is running. application is running.
Right below, there is the Right below, there is the
[Deploy Board](https://docs.gitlab.com/ee/user/project/deploy_boards.md). [Deploy Board](https://docs.gitlab.com/ee/user/project/deploy_boards.html).
The squares represent pods in your Kubernetes cluster that are associated with The squares represent pods in your Kubernetes cluster that are associated with
the given environment. Hovering above each square you can see the state of a the given environment. Hovering above each square you can see the state of a
deployment and clicking a square will take you to the pod's logs page. deployment and clicking a square will take you to the pod's logs page.
...@@ -264,8 +264,8 @@ Let's fix that: ...@@ -264,8 +264,8 @@ Let's fix that:
to stage the changes. to stage the changes.
1. Write a commit message and click **Commit**. 1. Write a commit message and click **Commit**.
Now, if you go back to the merge request you should not only see the test passing, Now, if you go back to the merge request you should not only see the test passing, but
but also the application deployed as a [review app](index.md#auto-review-apps). You also the application deployed as a [review app](index.md#auto-review-apps). You
can visit it by following the URL in the merge request. The changes that we can visit it by following the URL in the merge request. The changes that we
previously made should be there. previously made should be there.
......
This diff is collapsed.
...@@ -35,17 +35,17 @@ continue their registration afterwards. ...@@ -35,17 +35,17 @@ continue their registration afterwards.
## Accepting terms ## Accepting terms
When this feature was enabled, the users that have not accepted the When this feature is enabled, the users that have not accepted the
terms of service will be presented with a screen where they can either terms of service will be presented with a screen where they can either
accept or decline the terms. accept or decline the terms.
![Respond to terms](img/respond_to_terms.png) ![Respond to terms](img/respond_to_terms.png)
When the user accepts the terms, they will be directed to where they If the user accepts the terms, they will be directed to where they
were going. After a sign-in or sign-up this will most likely be the were going. After a sign-in or sign-up this will most likely be the
dashboard. dashboard.
When the user was already logged in when the feature was turned on, If the user was already logged in when the feature was turned on,
they will be asked to accept the terms on their next interaction. they will be asked to accept the terms on their next interaction.
When a user declines the terms, they will be signed out. If a user declines the terms, they will be signed out.
...@@ -82,11 +82,11 @@ create issues for the same project. ...@@ -82,11 +82,11 @@ create issues for the same project.
## New issue via URL with prefilled fields ## New issue via URL with prefilled fields
You can link directly to the new issue page for a given project, with prefilled You can link directly to the new issue page for a given project, with prefilled
field values using query string parameters in a URL. This is useful for embedding field values using query string parameters in a URL. This is useful for embedding
a URL in an external HTML page, and also certain scenarios where you want the user to a URL in an external HTML page, and also certain scenarios where you want the user to
create an issue with certain fields prefilled. create an issue with certain fields prefilled.
The title, description, and description template fields can be prefilled using The title, description, and description template fields can be prefilled using
this method. The description and description template fields cannot be pre-entered this method. The description and description template fields cannot be pre-entered
in the same URL (since a description template just populates the description field). in the same URL (since a description template just populates the description field).
......
...@@ -57,7 +57,7 @@ started: ...@@ -57,7 +57,7 @@ started:
gpg --full-gen-key gpg --full-gen-key
``` ```
_NOTE: In some cases like Gpg4win on Windows and other Mac OS versions the command here may be ` gpg --gen-key`_ _NOTE: In some cases like Gpg4win on Windows and other Mac OS versions the command here may be ` gpg --gen-key`_
This will spawn a series of questions. This will spawn a series of questions.
......
# frozen_string_literal: true
module AfterCommitQueue module AfterCommitQueue
extend ActiveSupport::Concern extend ActiveSupport::Concern
......
# frozen_string_literal: true
module Backup module Backup
Error = Class.new(StandardError) Error = Class.new(StandardError)
end end
# frozen_string_literal: true
module Banzai module Banzai
# if you need to render markdown, then you probably need to post_process as well, # if you need to render markdown, then you probably need to post_process as well,
# such as removing references that the current user doesn't have # such as removing references that the current user doesn't have
......
# frozen_string_literal: true
module Banzai module Banzai
module ColorParser module ColorParser
ALPHA = /0(?:\.\d+)?|\.\d+|1(?:\.0+)?/ # 0.0..1.0 ALPHA = /0(?:\.\d+)?|\.\d+|1(?:\.0+)?/ # 0.0..1.0
......
# frozen_string_literal: true
module Banzai module Banzai
module CommitRenderer module CommitRenderer
ATTRIBUTES = [:description, :title].freeze ATTRIBUTES = [:description, :title].freeze
......
# frozen_string_literal: true
module Banzai module Banzai
# Common methods for ReferenceFilters that support an optional cross-project # Common methods for ReferenceFilters that support an optional cross-project
# reference. # reference.
......
# frozen_string_literal: true
module Banzai module Banzai
module Filter module Filter
def self.[](name) def self.[](name)
......
# frozen_string_literal: true
# `CommonMark` markdown engine for GitLab's Banzai markdown filter. # `CommonMark` markdown engine for GitLab's Banzai markdown filter.
# This module is used in Banzai::Filter::MarkdownFilter. # This module is used in Banzai::Filter::MarkdownFilter.
# Used gem is `commonmarker` which is a ruby wrapper for libcmark (CommonMark parser) # Used gem is `commonmarker` which is a ruby wrapper for libcmark (CommonMark parser)
......
# frozen_string_literal: true
# `Redcarpet` markdown engine for GitLab's Banzai markdown filter. # `Redcarpet` markdown engine for GitLab's Banzai markdown filter.
# This module is used in Banzai::Filter::MarkdownFilter. # This module is used in Banzai::Filter::MarkdownFilter.
# Used gem is `redcarpet` which is a ruby library for markdown processing. # Used gem is `redcarpet` which is a ruby library for markdown processing.
......
# frozen_string_literal: true
module Banzai module Banzai
module Filter module Filter
class WikiLinkFilter < HTML::Pipeline::Filter class WikiLinkFilter < HTML::Pipeline::Filter
......
# frozen_string_literal: true
module Banzai module Banzai
class FilterArray < Array class FilterArray < Array
# Insert a value immediately after another value # Insert a value immediately after another value
......
# frozen_string_literal: true
module Banzai module Banzai
# Extract references to issuables from multiple documents # Extract references to issuables from multiple documents
......
# frozen_string_literal: true
module Banzai module Banzai
# Class for rendering multiple objects (e.g. Note instances) in a single pass, # Class for rendering multiple objects (e.g. Note instances) in a single pass,
# using +render_field+ to benefit from caching in the database. Rendering and # using +render_field+ to benefit from caching in the database. Rendering and
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
def self.[](name) def self.[](name)
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class AsciiDocPipeline < BasePipeline class AsciiDocPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class AtomPipeline < FullPipeline class AtomPipeline < FullPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class BasePipeline class BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class BroadcastMessagePipeline < DescriptionPipeline class BroadcastMessagePipeline < DescriptionPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
module CombinedPipeline module CombinedPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class CommitDescriptionPipeline < SingleLinePipeline class CommitDescriptionPipeline < SingleLinePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class DescriptionPipeline < FullPipeline class DescriptionPipeline < FullPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class EmailPipeline < FullPipeline class EmailPipeline < FullPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class FullPipeline < CombinedPipeline.new(PlainMarkdownPipeline, GfmPipeline) class FullPipeline < CombinedPipeline.new(PlainMarkdownPipeline, GfmPipeline)
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class GfmPipeline < BasePipeline class GfmPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class MarkupPipeline < BasePipeline class MarkupPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class NotePipeline < FullPipeline class NotePipeline < FullPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class PlainMarkdownPipeline < BasePipeline class PlainMarkdownPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class PostProcessPipeline < BasePipeline class PostProcessPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class PreProcessPipeline < BasePipeline class PreProcessPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class RelativeLinkPipeline < BasePipeline class RelativeLinkPipeline < BasePipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class SingleLinePipeline < GfmPipeline class SingleLinePipeline < GfmPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Pipeline module Pipeline
class WikiPipeline < FullPipeline class WikiPipeline < FullPipeline
......
# frozen_string_literal: true
module Banzai module Banzai
module Querying module Querying
module_function module_function
......
# frozen_string_literal: true
module Banzai module Banzai
# Class for removing Markdown references a certain user is not allowed to # Class for removing Markdown references a certain user is not allowed to
# view. # view.
......
# frozen_string_literal: true
module Banzai module Banzai
# Extract possible GFM references from an arbitrary String for further processing. # Extract possible GFM references from an arbitrary String for further processing.
class ReferenceExtractor class ReferenceExtractor
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
# Returns the reference parser class for the given type # Returns the reference parser class for the given type
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
# Base class for reference parsing classes. # Base class for reference parsing classes.
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class CommitParser < BaseParser class CommitParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class CommitRangeParser < BaseParser class CommitRangeParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class DirectlyAddressedUserParser < UserParser class DirectlyAddressedUserParser < UserParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
# The actual parser is implemented in the EE mixin # The actual parser is implemented in the EE mixin
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class ExternalIssueParser < BaseParser class ExternalIssueParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class IssuableParser < BaseParser class IssuableParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class IssueParser < IssuableParser class IssueParser < IssuableParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class LabelParser < BaseParser class LabelParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class MergeRequestParser < IssuableParser class MergeRequestParser < IssuableParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class MilestoneParser < BaseParser class MilestoneParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class SnippetParser < BaseParser class SnippetParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module ReferenceParser module ReferenceParser
class UserParser < BaseParser class UserParser < BaseParser
......
# frozen_string_literal: true
module Banzai module Banzai
module Renderer module Renderer
# Convert a Markdown String into an HTML-safe String of HTML # Convert a Markdown String into an HTML-safe String of HTML
......
# frozen_string_literal: true
module Banzai module Banzai
module Renderer module Renderer
module CommonMark module CommonMark
......
# frozen_string_literal: true
module Banzai module Banzai
module Renderer module Renderer
module Redcarpet module Redcarpet
......
# frozen_string_literal: true
module Banzai module Banzai
module RequestStoreReferenceCache module RequestStoreReferenceCache
def cached_call(request_store_key, cache_key, path: []) def cached_call(request_store_key, cache_key, path: [])
......
# frozen_string_literal: true
module Bitbucket module Bitbucket
class Client class Client
attr_reader :connection attr_reader :connection
......
# frozen_string_literal: true
module Bitbucket module Bitbucket
class Collection < Enumerator class Collection < Enumerator
def initialize(paginator) def initialize(paginator)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment