Commit df91318a authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ce-to-ee-2018-07-25' into 'master'

CE upstream - 2018-07-25 12:22 UTC

See merge request gitlab-org/gitlab-ee!6659
parents b01739ac 33dfca35
......@@ -437,7 +437,7 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly-proto', '~> 0.106.0', require: 'gitaly'
gem 'gitaly-proto', '~> 0.109.0', require: 'gitaly'
gem 'grpc', '~> 1.11.0'
# Locked until https://github.com/google/protobuf/issues/4210 is closed
......
......@@ -308,7 +308,7 @@ GEM
gettext_i18n_rails (>= 0.7.1)
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gitaly-proto (0.106.0)
gitaly-proto (0.109.0)
google-protobuf (~> 3.1)
grpc (~> 1.10)
github-linguist (5.3.3)
......@@ -424,7 +424,7 @@ GEM
hipchat (1.5.2)
httparty
mimemagic
html-pipeline (2.8.3)
html-pipeline (2.8.4)
activesupport (>= 2)
nokogiri (>= 1.4)
html2text (0.2.0)
......@@ -1076,7 +1076,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly-proto (~> 0.106.0)
gitaly-proto (~> 0.109.0)
github-linguist (~> 5.3.3)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-gollum-lib (~> 4.2)
......
......@@ -311,7 +311,7 @@ GEM
gettext_i18n_rails (>= 0.7.1)
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gitaly-proto (0.106.0)
gitaly-proto (0.109.0)
google-protobuf (~> 3.1)
grpc (~> 1.10)
github-linguist (5.3.3)
......@@ -1086,7 +1086,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly-proto (~> 0.106.0)
gitaly-proto (~> 0.109.0)
github-linguist (~> 5.3.3)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-gollum-lib (~> 4.2)
......
......@@ -112,7 +112,7 @@ class Projects::WikisController < Projects::ApplicationController
private
def load_project_wiki
@project_wiki = ProjectWiki.new(@project, current_user)
@project_wiki = load_wiki
# Call #wiki to make sure the Wiki Repo is initialized
@project_wiki.wiki
......@@ -128,6 +128,10 @@ class Projects::WikisController < Projects::ApplicationController
false
end
def load_wiki
ProjectWiki.new(@project, current_user)
end
def wiki_params
params.require(:wiki).permit(:title, :content, :format, :message, :last_commit_sha)
end
......
......@@ -90,7 +90,7 @@ class ProjectWiki
# Returns an Array of Gitlab WikiPage instances or an
# empty Array if this Wiki has no pages.
def pages(limit: nil)
def pages(limit: 0)
wiki.pages(limit: limit).map { |page| WikiPage.new(self, page, true) }
end
......
# frozen_string_literal: true
class ApplicationSetting
class TermPolicy < BasePolicy
include Gitlab::Utils::StrongMemoize
......
# frozen_string_literal: true
require_dependency 'declarative_policy'
class BasePolicy < DeclarativePolicy::Base
......
# frozen_string_literal: true
module Ci
class BuildPolicy < CommitStatusPolicy
condition(:protected_ref) do
......
# frozen_string_literal: true
module Ci
class PipelinePolicy < BasePolicy
delegate { @subject.project }
......
# frozen_string_literal: true
module Ci
class PipelineSchedulePolicy < PipelinePolicy
alias_method :pipeline_schedule, :subject
......
# frozen_string_literal: true
module Ci
class RunnerPolicy < BasePolicy
with_options scope: :subject, score: 0
......
# frozen_string_literal: true
module Ci
class TriggerPolicy < BasePolicy
delegate { @subject.project }
......
# frozen_string_literal: true
module Clusters
class ClusterPolicy < BasePolicy
alias_method :cluster, :subject
......
# frozen_string_literal: true
class CommitStatusPolicy < BasePolicy
delegate { @subject.project }
......
# frozen_string_literal: true
class DeployKeyPolicy < BasePolicy
with_options scope: :subject, score: 0
condition(:private_deploy_key) { @subject.private? }
......
# frozen_string_literal: true
class DeployTokenPolicy < BasePolicy
with_options scope: :subject, score: 0
condition(:maintainer) { @subject.project.team.maintainer?(@user) }
......
# frozen_string_literal: true
class DeploymentPolicy < BasePolicy
delegate { @subject.project }
end
# frozen_string_literal: true
class EnvironmentPolicy < BasePolicy
delegate { @subject.project }
......
# frozen_string_literal: true
class ExternalIssuePolicy < BasePolicy
delegate { @subject.project }
end
# frozen_string_literal: true
class GlobalPolicy < BasePolicy
desc "User is blocked"
with_options scope: :user, score: 0
......
# frozen_string_literal: true
class GroupLabelPolicy < BasePolicy
delegate { @subject.group }
end
# frozen_string_literal: true
class GroupMemberPolicy < BasePolicy
delegate :group
......
# frozen_string_literal: true
class GroupPolicy < BasePolicy
prepend EE::GroupPolicy
......
# frozen_string_literal: true
class IssuablePolicy < BasePolicy
delegate { @subject.project }
......
# frozen_string_literal: true
class IssuePolicy < IssuablePolicy
# This class duplicates the same check of Issue#readable_by? for performance reasons
# Make sure to sync this class checks with issue.rb to avoid security problems.
......
# frozen_string_literal: true
class MergeRequestPolicy < IssuablePolicy
prepend EE::MergeRequestPolicy
end
# frozen_string_literal: true
class NamespacePolicy < BasePolicy
rule { anonymous }.prevent_all
......
# frozen_string_literal: true
class NilPolicy < BasePolicy
rule { default }.prevent_all
end
# frozen_string_literal: true
class NotePolicy < BasePolicy
delegate { @subject.project }
delegate { @subject.noteable if DeclarativePolicy.has_policy?(@subject.noteable) }
......
# frozen_string_literal: true
class PersonalSnippetPolicy < BasePolicy
condition(:public_snippet, scope: :subject) { @subject.public? }
condition(:is_author) { @user && @subject.author == @user }
......
# frozen_string_literal: true
class ProjectLabelPolicy < BasePolicy
delegate { @subject.project }
end
# frozen_string_literal: true
class ProjectMemberPolicy < BasePolicy
delegate { @subject.project }
......
# frozen_string_literal: true
class ProjectPolicy < BasePolicy
extend ClassMethods
prepend EE::ProjectPolicy
......
# frozen_string_literal: true
class ProjectPolicy
module ClassMethods
def create_read_update_admin_destroy(name)
......
# frozen_string_literal: true
class ProjectSnippetPolicy < BasePolicy
delegate :project
......
# frozen_string_literal: true
class ProtectedBranchPolicy < BasePolicy
prepend EE::ProtectedBranchPolicy
......
# frozen_string_literal: true
class UserPolicy < BasePolicy
desc "The current user is the user in question"
condition(:user_is_self, score: 0) { @subject == @user }
......
# frozen_string_literal: true
module Ci
class BuildMetadataPresenter < Gitlab::View::Presenter::Delegated
TIMEOUT_SOURCES = {
......
# frozen_string_literal: true
module Ci
class BuildPresenter < CommitStatusPresenter
def erased_by_user?
......
# frozen_string_literal: true
module Ci
class GroupVariablePresenter < Gitlab::View::Presenter::Delegated
presents :variable
......
# frozen_string_literal: true
module Ci
class PipelinePresenter < Gitlab::View::Presenter::Delegated
prepend ::EE::Ci::PipelinePresenter
......
# frozen_string_literal: true
module Ci
class VariablePresenter < Gitlab::View::Presenter::Delegated
presents :variable
......
# frozen_string_literal: true
module Clusters
class ClusterPresenter < Gitlab::View::Presenter::Delegated
presents :cluster
......
# frozen_string_literal: true
class CommitStatusPresenter < Gitlab::View::Presenter::Delegated
CALLOUT_FAILURE_MESSAGES = {
unknown_failure: 'There is an unknown failure, please try again',
......
# frozen_string_literal: true
module ConversationalDevelopmentIndex
class MetricPresenter < Gitlab::View::Presenter::Simple
def cards
......
# frozen_string_literal: true
class GenericCommitStatusPresenter < CommitStatusPresenter
end
# frozen_string_literal: true
class GroupMemberPresenter < MemberPresenter
prepend EE::GroupMemberPresenter
......
# frozen_string_literal: true
class MemberPresenter < Gitlab::View::Presenter::Delegated
prepend EE::MemberPresenter
......
# frozen_string_literal: true
class MembersPresenter < Gitlab::View::Presenter::Delegated
include Enumerable
......
# frozen_string_literal: true
class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
prepend EE::MergeRequestPresenter
......
# frozen_string_literal: true
class ProjectMemberPresenter < MemberPresenter
prepend EE::ProjectMemberPresenter
......
# frozen_string_literal: true
class ProjectPresenter < Gitlab::View::Presenter::Delegated
include ActionView::Helpers::NumberHelper
include ActionView::Helpers::UrlHelper
......
# frozen_string_literal: true
module Projects
module Settings
class DeployKeysPresenter < Gitlab::View::Presenter::Simple
......
- humanized_resource_name = spammable.class.model_name.human.downcase
%h3.page-title
Anti-spam verification
= _('Anti-spam verification')
%hr
%p
#{"We detected potential spam in the #{humanized_resource_name}. Please solve the reCAPTCHA to proceed."}
= _("We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed.") % { humanized_resource_name: humanized_resource_name }
= render 'shared/recaptcha_form', spammable: spammable
- if controller.controller_path =~ /^groups/ && @group.persisted?
- label = 'This group'
- label = _('This group')
- if controller.controller_path =~ /^projects/ && @project.persisted?
- label = 'This project'
- label = _('This project')
- if @group && @group.persisted? && @group.path
- group_data_attrs = { group_path: j(@group.path), name: @group.name, issues_path: issues_group_path(j(@group.path)), mr_path: merge_requests_group_path(j(@group.path)) }
- if @project && @project.persisted?
......@@ -13,21 +13,21 @@
.location-badge= label
.search-input-wrap
.dropdown{ data: { url: search_autocomplete_path } }
= search_field_tag 'search', nil, placeholder: 'Search',
= search_field_tag 'search', nil, placeholder: _('Search'),
class: 'search-input dropdown-menu-toggle no-outline js-search-dashboard-options',
spellcheck: false,
tabindex: '1',
autocomplete: 'off',
data: { issues_path: issues_dashboard_path,
mr_path: merge_requests_dashboard_path },
aria: { label: 'Search' }
aria: { label: _('Search') }
%button.hidden.js-dropdown-search-toggle{ type: 'button', data: { toggle: 'dropdown' } }
.dropdown-menu.dropdown-select
= dropdown_content do
%ul
%li.dropdown-menu-empty-item
%a
Loading...
= _('Loading...')
= dropdown_loading
= sprite_icon('search', size: 16, css_class: 'search-icon')
= sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input')
......
- page_title "Admin Area"
- header_title "Admin Area", admin_root_path
- page_title _("Admin Area")
- header_title _("Admin Area"), admin_root_path
- nav "admin"
- @left_sidebar = true
......
- page_title "Dashboard"
- header_title "Dashboard", root_path unless header_title
- page_title _("Dashboard")
- header_title _("Dashboard"), root_path unless header_title
- sidebar "dashboard"
= render template: "layouts/application"
......@@ -18,12 +18,11 @@
- if current_appearance&.description?
= brand_text
- else
%h3 Open source software to collaborate on code
%h3
= _('Open source software to collaborate on code')
%p
Manage Git repositories with fine-grained access controls that keep your code secure.
Perform code reviews and enhance collaboration with merge requests.
Each project can also have an issue tracker and a wiki.
= _('Manage Git repositories with fine-grained access controls that keep your code secure. Perform code reviews and enhance collaboration with merge requests. Each project can also have an issue tracker and a wiki.')
- if Gitlab::CurrentSettings.sign_in_text.present?
= markdown_field(Gitlab::CurrentSettings.current_application_settings, :sign_in_text)
......@@ -39,7 +38,7 @@
%hr.footer-fixed
.container.footer-container
.footer-links
= link_to "Explore", explore_root_path
= link_to "Help", help_path
= link_to "About GitLab", "https://about.gitlab.com/"
= link_to _("Explore"), explore_root_path
= link_to _("Help"), help_path
= link_to _("About GitLab"), "https://about.gitlab.com/"
= footer_message
......@@ -13,7 +13,7 @@
%hr
.container
.footer-links
= link_to "Explore", explore_root_path
= link_to "Help", help_path
= link_to "About GitLab", "https://about.gitlab.com/"
= link_to _("Explore"), explore_root_path
= link_to _("Help"), help_path
= link_to _("About GitLab"), "https://about.gitlab.com/"
= footer_message
- page_title "Explore"
- page_title = _("Explore")
- unless current_user
- header_title "Explore GitLab", explore_root_path
- header_title = _("Explore GitLab"), explore_root_path
= render template: "layouts/application"
- page_title "Settings"
- page_title = _("Settings")
- nav "group"
= render template: "layouts/group"
......@@ -4,7 +4,7 @@
.header-content
.title-container
%h1.title
= link_to root_path, title: 'Dashboard', id: 'logo' do
= link_to root_path, title: _('Dashboard'), id: 'logo' do
= brand_header_logo
- logo_text = brand_header_logo_type
- if logo_text.present?
......@@ -24,26 +24,26 @@
%li.nav-item.d-none.d-sm-none.d-md-block.m-auto
= render 'layouts/search' unless current_controller?(:search)
%li.nav-item.d-inline-block.d-sm-none.d-md-none
= link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= link_to search_path, title: _('Search'), aria: { label: _("Search") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('search', size: 16)
- if header_link?(:issues)
= nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do
= link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues', aria: { label: _("Issues") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('issues', size: 16)
- issues_count = assigned_issuables_count(:issues)
%span.badge.badge-pill.issues-count{ class: ('hidden' if issues_count.zero?) }
= number_with_delimiter(issues_count)
- if header_link?(:merge_requests)
= nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter" }) do
= link_to assigned_mrs_dashboard_path, title: 'Merge requests', class: 'dashboard-shortcuts-merge_requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= link_to assigned_mrs_dashboard_path, title: _('Merge requests'), class: 'dashboard-shortcuts-merge_requests', aria: { label: _("Merge requests") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('git-merge', size: 16)
- merge_requests_count = assigned_issuables_count(:merge_requests)
%span.badge.badge-pill.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) }
= number_with_delimiter(merge_requests_count)
- if header_link?(:todos)
= nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do
= link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= link_to dashboard_todos_path, title: _('Todos'), aria: { label: _("Todos") }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('todo-done', size: 16)
%span.badge.badge-pill.todos-count{ class: ('hidden' if todos_pending_count.zero?) }
= todos_count_format(todos_pending_count)
......@@ -56,16 +56,16 @@
= render 'layouts/header/current_user_dropdown'
- if header_link?(:admin_impersonation)
%li.nav-item.impersonation
= link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: "Stop impersonation", aria: { label: 'Stop impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _("Stop impersonation"), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= icon('user-secret')
- if header_link?(:sign_in)
%li.nav-item
%div
- sign_in_text = allow_signup? ? 'Sign in / Register' : 'Sign in'
- sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in')
= link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in'
%button.navbar-toggler.d-block.d-sm-none{ type: 'button' }
%span.sr-only Toggle navigation
%span.sr-only= _("Toggle navigation")
= sprite_icon('more', size: 12, css_class: 'more-icon js-navbar-toggle-right')
= sprite_icon('close', size: 12, css_class: 'close-icon js-navbar-toggle-left')
%li.header-new.dropdown
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do
= sprite_icon('plus-square', size: 16)
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
......@@ -8,13 +8,14 @@
- create_group_project = can?(current_user, :create_projects, @group)
- create_group_subgroup = can?(current_user, :create_subgroup, @group)
- if create_group_project || create_group_subgroup
%li.dropdown-bold-header This group
%li.dropdown-bold-header
= _('This group')
- if create_group_project
%li.header-new-group-project
= link_to 'New project', new_project_path(namespace_id: @group.id)
= link_to _('New project'), new_project_path(namespace_id: @group.id)
- if create_group_subgroup
%li
= link_to 'New subgroup', new_group_path(parent_id: @group.id)
= link_to _('New subgroup'), new_group_path(parent_id: @group.id)
%li.divider
%li.dropdown-bold-header GitLab
......@@ -23,23 +24,24 @@
- merge_project = merge_request_source_project_for_project(@project)
- create_project_snippet = can?(current_user, :create_project_snippet, @project)
- if create_project_issue || merge_project || create_project_snippet
%li.dropdown-bold-header This project
%li.dropdown-bold-header
= _('This project')
- if create_project_issue
%li
= link_to 'New issue', new_project_issue_path(@project)
= link_to _('New issue'), new_project_issue_path(@project)
- if merge_project
%li
= link_to 'New merge request', project_new_merge_request_path(merge_project)
= link_to _('New merge request'), project_new_merge_request_path(merge_project)
- if create_project_snippet
%li.header-new-project-snippet
= link_to 'New snippet', new_project_snippet_path(@project)
= link_to _('New snippet'), new_project_snippet_path(@project)
%li.divider
%li.dropdown-bold-header GitLab
- if current_user.can_create_project?
%li
= link_to 'New project', new_project_path, class: 'qa-global-new-project-link'
= link_to _('New project'), new_project_path, class: 'qa-global-new-project-link'
- if current_user.can_create_group?
%li
= link_to 'New group', new_group_path
= link_to _('New group'), new_group_path
%li
= link_to 'New snippet', new_snippet_path
= link_to _('New snippet'), new_snippet_path
- @breadcrumb_title = "Help"
- page_title "Help"
- header_title "Help", help_path
- @breadcrumb_title = _("Help")
- page_title _("Help")
- header_title _("Help"), help_path
= render template: "layouts/application"
- page_title "Koding"
- page_description "Koding Dashboard"
- header_title "Koding", koding_path
- page_title _("Koding")
- page_description _("Koding Dashboard")
- header_title _("Koding"), koding_path
= render template: "layouts/application"
<%= yield -%>
-- <%# signature marker %>
You're receiving this email because of your account on <%= Gitlab.config.gitlab.host %>.
<%# EE-specific start %><%= render 'layouts/mailer/additional_text' %><%# EE-specific end %>
\ No newline at end of file
<%= _("You're receiving this email because of your account on %{host}.") % { host: Gitlab.config.gitlab.host } %>
<%# EE-specific start %><%= render 'layouts/mailer/additional_text' %><%# EE-specific end %>
......@@ -3,17 +3,17 @@
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:13px;line-height:1.6;color:#5c5c5c;" }
%div
Everyone can contribute
= _('Everyone can contribute')
%div
= link_to 'Blog', 'https://about.gitlab.com/blog/', style: "color:#3777b0;text-decoration:none;"
= link_to _('Blog'), 'https://about.gitlab.com/blog/', style: "color:#3777b0;text-decoration:none;"
&middot;
= link_to 'Twitter', 'https://twitter.com/gitlab', style: "color:#3777b0;text-decoration:none;"
= link_to _('Twitter'), 'https://twitter.com/gitlab', style: "color:#3777b0;text-decoration:none;"
&middot;
= link_to 'Facebook', 'https://www.facebook.com/gitlab/', style: "color:#3777b0;text-decoration:none;"
= link_to _('Facebook'), 'https://www.facebook.com/gitlab/', style: "color:#3777b0;text-decoration:none;"
&middot;
= link_to 'YouTube', 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg', style: "color:#3777b0;text-decoration:none;"
= link_to _('YouTube'), 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg', style: "color:#3777b0;text-decoration:none;"
&middot;
= link_to 'LinkedIn', 'https://www.linkedin.com/company/gitlab-com', style: "color:#3777b0;text-decoration:none;"
= link_to _('LinkedIn'), 'https://www.linkedin.com/company/gitlab-com', style: "color:#3777b0;text-decoration:none;"
= render layout: 'layouts/mailer' do
%tr
......
......@@ -5,7 +5,7 @@
.breadcrumbs-container
- if defined?(@left_sidebar)
= button_tag class: 'toggle-mobile-nav', type: 'button' do
%span.sr-only Open sidebar
%span.sr-only= _("Open sidebar")
= icon ('bars')
.breadcrumbs-links.js-title-container
%ul.list-unstyled.breadcrumbs-list.js-breadcrumbs-list
......
......@@ -2,7 +2,7 @@
- if dashboard_nav_link?(:projects)
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown" }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
Projects
= _('Projects')
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.frequent-items-dropdown-menu
= render "layouts/nav/projects_dropdown/show"
......@@ -10,69 +10,69 @@
- if dashboard_nav_link?(:groups)
= nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "home dropdown header-groups qa-groups-dropdown" }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
Groups
= _('Groups')
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.frequent-items-dropdown-menu
= render "layouts/nav/groups_dropdown/show"
- if dashboard_nav_link?(:activity)
= nav_link(path: 'dashboard#activity', html_options: { class: "d-none d-lg-block d-xl-block" }) do
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do
Activity
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: _('Activity') do
= _('Activity')
- if dashboard_nav_link?(:milestones)
= nav_link(controller: 'dashboard/milestones', html_options: { class: "d-none d-lg-block d-xl-block" }) do
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: 'Milestones' do
Milestones
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: _('Milestones') do
= _('Milestones')
- if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets', html_options: { class: "d-none d-lg-block d-xl-block" }) do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do
Snippets
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: _('Snippets') do
= _('Snippets')
- if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
%li.header-more.dropdown.d-lg-none.d-xl-none
%a{ href: "#", data: { toggle: "dropdown" } }
More
= _('More')
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu
%ul
- if dashboard_nav_link?(:activity)
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, title: 'Activity' do
Activity
= link_to activity_dashboard_path, title: _('Activity') do
= _('Activity')
- if dashboard_nav_link?(:milestones)
= nav_link(controller: 'dashboard/milestones') do
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: 'Milestones' do
Milestones
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: _('Milestones') do
= _('Milestones')
- if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets') do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do
Snippets
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: _('Snippets') do
= _('Snippets')
-# Shortcut to Dashboard > Projects
- if dashboard_nav_link?(:projects)
%li.hidden
= link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do
Projects
= link_to dashboard_projects_path, title: _('Projects'), class: 'dashboard-shortcuts-projects' do
= _('Projects')
- if current_controller?('ide')
%li.line-separator.d-none.d-sm-block
= nav_link(controller: 'ide') do
= link_to '#', class: 'dashboard-shortcuts-web-ide', title: 'Web IDE' do
Web IDE
= link_to '#', class: 'dashboard-shortcuts-web-ide', title: _('Web IDE') do
= _('Web IDE')
- if current_user.admin? || Gitlab::Sherlock.enabled?
%li.line-separator.d-none.d-sm-block
- if current_user.admin?
= nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin area'), aria: { label: _("Admin area") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions',
= link_to sherlock_transactions_path, class: 'admin-icon', title: _('Sherlock Transactions'),
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('tachometer fw')
- if Gitlab::Geo.secondary? && Gitlab::Geo.primary_node_configured?
......
%ul.list-unstyled.navbar-sub-nav
- if explore_nav_link?(:projects)
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to explore_root_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do
Projects
= link_to explore_root_path, title: _('Projects'), class: 'dashboard-shortcuts-projects' do
= _('Projects')
- if explore_nav_link?(:groups)
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to explore_groups_path, title: 'Groups', class: 'dashboard-shortcuts-groups' do
Groups
= link_to explore_groups_path, title: _('Groups'), class: 'dashboard-shortcuts-groups' do
= _('Groups')
- if explore_nav_link?(:snippets)
= nav_link(controller: :snippets) do
= link_to explore_snippets_path, title: 'Snippets', class: 'dashboard-shortcuts-snippets' do
Snippets
= link_to explore_snippets_path, title: _('Snippets'), class: 'dashboard-shortcuts-snippets' do
= _('Snippets')
%li
= link_to "Help", help_path, title: 'About GitLab CE'
= link_to _("Help"), help_path, title: _('About GitLab CE')
......@@ -17,24 +17,24 @@
.nav-icon-container
= sprite_icon('project')
%span.nav-item-name
Overview
= _('Overview')
%ul.sidebar-sub-level-items
= nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: "fly-out-top-item" } ) do
= link_to group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Overview') }
= _('Overview')
%li.divider.fly-out-top-item
= nav_link(path: ['groups#show', 'groups#subgroups'], html_options: { class: 'home' }) do
= link_to group_path(@group), title: 'Group details' do
= link_to group_path(@group), title: _('Group details') do
%span
Details
= _('Details')
- if group_sidebar_link?(:activity)
= nav_link(path: 'groups#activity') do
= link_to activity_group_path(@group), title: 'Activity' do
= link_to activity_group_path(@group), title: _('Activity') do
%span
Activity
= _('Activity')
- if group_sidebar_link?(:contribution_analytics)
= nav_link(path: 'analytics#show') do
......@@ -50,21 +50,21 @@
.nav-icon-container
= sprite_icon('issues')
%span.nav-item-name
Issues
= _('Issues')
%span.badge.badge-pill.count= number_with_delimiter(issues_count)
%ul.sidebar-sub-level-items
= nav_link(path: ['groups#issues', 'labels#index', 'milestones#index'], html_options: { class: "fly-out-top-item" } ) do
= link_to issues_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Issues') }
= _('Issues')
%span.badge.badge-pill.count.issue_counter.fly-out-badge= number_with_delimiter(issues_count)
%li.divider.fly-out-top-item
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
= link_to issues_group_path(@group), title: 'List' do
= link_to issues_group_path(@group), title: _('List') do
%span
List
= _('List')
- if group_sidebar_link?(:boards)
= nav_link(path: ['boards#index', 'boards#show']) do
......@@ -74,15 +74,15 @@
- if group_sidebar_link?(:labels)
= nav_link(path: 'labels#index') do
= link_to group_labels_path(@group), title: 'Labels' do
= link_to group_labels_path(@group), title: _('Labels') do
%span
Labels
= _('Labels')
- if group_sidebar_link?(:milestones)
= nav_link(path: 'milestones#index') do
= link_to group_milestones_path(@group), title: 'Milestones' do
= link_to group_milestones_path(@group), title: _('Milestones') do
%span
Milestones
= _('Milestones')
- if group_sidebar_link?(:merge_requests)
= nav_link(path: 'groups#merge_requests') do
......@@ -90,13 +90,13 @@
.nav-icon-container
= sprite_icon('git-merge')
%span.nav-item-name
Merge Requests
= _('Merge Requests')
%span.badge.badge-pill.count= number_with_delimiter(merge_requests_count)
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'groups#merge_requests', html_options: { class: "fly-out-top-item" } ) do
= link_to merge_requests_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Merge Requests') }
= _('Merge Requests')
%span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests_count)
- if group_sidebar_link?(:group_members)
......@@ -105,12 +105,12 @@
.nav-icon-container
= sprite_icon('users')
%span.nav-item-name
Members
= _('Members')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'group_members#index', html_options: { class: "fly-out-top-item" } ) do
= link_to group_group_members_path(@group) do
%strong.fly-out-top-item-name
#{ _('Members') }
= _('Members')
- if group_sidebar_link?(:settings)
= nav_link(path: group_nav_link_paths) do
......@@ -118,17 +118,17 @@
.nav-icon-container
= sprite_icon('settings')
%span.nav-item-name
Settings
= _('Settings')
%ul.sidebar-sub-level-items
= nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show], html_options: { class: "fly-out-top-item" } ) do
= link_to edit_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Settings') }
= _('Settings')
%li.divider.fly-out-top-item
= nav_link(path: 'groups#edit') do
= link_to edit_group_path(@group), title: 'General' do
= link_to edit_group_path(@group), title: _('General') do
%span
General
= _('General')
= nav_link(controller: :badges) do
= link_to group_settings_badges_path(@group), title: _('Project Badges') do
......@@ -137,14 +137,14 @@
= nav_link(path: 'groups#projects') do
= link_to projects_group_path(@group), title: 'Projects' do
= link_to projects_group_path(@group), title: _('Projects') do
%span
Projects
= _('Projects')
= nav_link(controller: :ci_cd) do
= link_to group_settings_ci_cd_path(@group), title: 'CI / CD' do
= link_to group_settings_ci_cd_path(@group), title: _('CI / CD') do
%span
CI / CD
= _('CI / CD')
= render "groups/ee/settings_nav"
......
.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
.nav-sidebar-inner-scroll
.context-header
= link_to profile_path, title: 'Profile Settings' do
= link_to profile_path, title: _('Profile Settings') do
.avatar-container.s40.settings-avatar
= sprite_icon('user', size: 24)
.sidebar-context-title User Settings
......@@ -11,23 +11,23 @@
.nav-icon-container
= sprite_icon('profile')
%span.nav-item-name
Profile
= _('Profile')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'profiles#show', html_options: { class: "fly-out-top-item" } ) do
= link_to profile_path do
%strong.fly-out-top-item-name
#{ _('Profile') }
= _('Profile')
= nav_link(controller: [:accounts, :two_factor_auths]) do
= link_to profile_account_path do
.nav-icon-container
= sprite_icon('account')
%span.nav-item-name
Account
= _('Account')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: [:accounts, :two_factor_auths], html_options: { class: "fly-out-top-item" } ) do
= link_to profile_account_path do
%strong.fly-out-top-item-name
#{ _('Account') }
= _('Account')
- if Gitlab::CurrentSettings.should_check_namespace_plan?
= nav_link(controller: :billings) do
= link_to profile_billings_path do
......@@ -46,123 +46,123 @@
.nav-icon-container
= sprite_icon('applications')
%span.nav-item-name
Applications
= _('Applications')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do
= link_to applications_profile_path do
%strong.fly-out-top-item-name
#{ _('Applications') }
= _('Applications')
= nav_link(controller: :chat_names) do
= link_to profile_chat_names_path do
.nav-icon-container
= sprite_icon('comment')
%span.nav-item-name
Chat
= _('Chat')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :chat_names, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_chat_names_path do
%strong.fly-out-top-item-name
#{ _('Chat') }
= _('Chat')
= nav_link(controller: :personal_access_tokens) do
= link_to profile_personal_access_tokens_path do
.nav-icon-container
= sprite_icon('token')
%span.nav-item-name
Access Tokens
= _('Access Tokens')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :personal_access_tokens, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_personal_access_tokens_path do
%strong.fly-out-top-item-name
#{ _('Access Tokens') }
= _('Access Tokens')
= nav_link(controller: :emails) do
= link_to profile_emails_path do
.nav-icon-container
= sprite_icon('mail')
%span.nav-item-name
Emails
= _('Emails')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :emails, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_emails_path do
%strong.fly-out-top-item-name
#{ _('Emails') }
= _('Emails')
- if current_user.allow_password_authentication?
= nav_link(controller: :passwords) do
= link_to edit_profile_password_path do
.nav-icon-container
= sprite_icon('lock')
%span.nav-item-name
Password
= _('Password')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :passwords, html_options: { class: "fly-out-top-item" } ) do
= link_to edit_profile_password_path do
%strong.fly-out-top-item-name
#{ _('Password') }
= _('Password')
= nav_link(controller: :notifications) do
= link_to profile_notifications_path do
.nav-icon-container
= sprite_icon('notifications')
%span.nav-item-name
Notifications
= _('Notifications')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :notifications, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_notifications_path do
%strong.fly-out-top-item-name
#{ _('Notifications') }
= _('Notifications')
= nav_link(controller: :keys) do
= link_to profile_keys_path do
.nav-icon-container
= sprite_icon('key')
%span.nav-item-name
SSH Keys
= _('SSH Keys')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :keys, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_keys_path do
%strong.fly-out-top-item-name
#{ _('SSH Keys') }
= _('SSH Keys')
= nav_link(controller: :gpg_keys) do
= link_to profile_gpg_keys_path do
.nav-icon-container
= sprite_icon('key-2')
%span.nav-item-name
GPG Keys
= _('GPG Keys')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :gpg_keys, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_gpg_keys_path do
%strong.fly-out-top-item-name
#{ _('GPG Keys') }
= _('GPG Keys')
= nav_link(controller: :preferences) do
= link_to profile_preferences_path do
.nav-icon-container
= sprite_icon('preferences')
%span.nav-item-name
Preferences
= _('Preferences')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :preferences, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_preferences_path do
%strong.fly-out-top-item-name
#{ _('Preferences') }
= _('Preferences')
= nav_link(controller: :active_sessions) do
= link_to profile_active_sessions_path do
.nav-icon-container
= sprite_icon('monitor-lines')
%span.nav-item-name
Active Sessions
= _('Active Sessions')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :active_sessions, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_active_sessions_path do
%strong.fly-out-top-item-name
#{ _('Active Sessions') }
= _('Active Sessions')
= nav_link(path: 'profiles#audit_log') do
= link_to audit_log_profile_path do
.nav-icon-container
= sprite_icon('log')
%span.nav-item-name
Authentication log
= _('Authentication log')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'profiles#audit_log', html_options: { class: "fly-out-top-item" } ) do
= link_to audit_log_profile_path do
%strong.fly-out-top-item-name
#{ _('Authentication Log') }
= _('Authentication Log')
= nav_link(path: 'profiles#pipeline_quota') do
= link_to profile_pipeline_quota_path do
.nav-icon-container
......
......@@ -105,7 +105,7 @@
= number_with_delimiter(@project.open_issues_count(current_user))
%li.divider.fly-out-top-item
= nav_link(controller: :issues, action: :index) do
= link_to project_issues_path(@project), title: 'Issues' do
= link_to project_issues_path(@project), title: _('Issues') do
%span
= _('List')
......@@ -115,14 +115,14 @@
= boards_link_text
= nav_link(controller: :labels) do
= link_to project_labels_path(@project), title: 'Labels' do
= link_to project_labels_path(@project), title: _('Labels') do
%span
= _('Labels')
= render_if_exists 'projects/sidebar/issues_service_desk'
= nav_link(controller: :milestones) do
= link_to project_milestones_path(@project), title: 'Milestones', class: 'qa-milestones-link' do
= link_to project_milestones_path(@project), title: _('Milestones'), class: 'qa-milestones-link' do
%span
= _('Milestones')
- if project_nav_tab? :external_issue_tracker
......@@ -172,25 +172,25 @@
%li.divider.fly-out-top-item
- if project_nav_tab? :pipelines
= nav_link(path: ['pipelines#index', 'pipelines#show']) do
= link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
= link_to project_pipelines_path(@project), title: _('Pipelines'), class: 'shortcuts-pipelines' do
%span
= _('Pipelines')
- if project_nav_tab? :builds
= nav_link(controller: [:jobs, :artifacts]) do
= link_to project_jobs_path(@project), title: 'Jobs', class: 'shortcuts-builds' do
= link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do
%span
= _('Jobs')
- if project_nav_tab? :pipelines
= nav_link(controller: :pipeline_schedules) do
= link_to pipeline_schedules_path(@project), title: 'Schedules', class: 'shortcuts-builds' do
= link_to pipeline_schedules_path(@project), title: _('Schedules'), class: 'shortcuts-builds' do
%span
= _('Schedules')
- if @project.feature_available?(:builds, current_user) && !@project.empty_repo?
= nav_link(path: 'pipelines#charts') do
= link_to charts_project_pipelines_path(@project), title: 'Charts', class: 'shortcuts-pipelines-charts' do
= link_to charts_project_pipelines_path(@project), title: _('Charts'), class: 'shortcuts-pipelines-charts' do
%span
= _('Charts')
......@@ -242,7 +242,7 @@
%p= _('Allows you to add and manage Kubernetes clusters.')
%p
= _('Protip:')
= link_to 'Auto DevOps', help_page_path('topics/autodevops/index.md')
= link_to _('Auto DevOps'), help_page_path('topics/autodevops/index.md')
%span= _('uses Kubernetes clusters to deploy your code!')
%hr
%button.btn.btn-create.btn-sm.dismiss-feature-highlight{ type: 'button' }
......@@ -305,11 +305,11 @@
= _('Settings')
%li.divider.fly-out-top-item
= nav_link(path: %w[projects#edit]) do
= link_to edit_project_path(@project), title: 'General' do
= link_to edit_project_path(@project), title: _('General') do
%span
= _('General')
= nav_link(controller: :project_members) do
= link_to project_project_members_path(@project), title: 'Members' do
= link_to project_project_members_path(@project), title: _('Members') do
%span
= _('Members')
- if can_edit
......@@ -319,21 +319,21 @@
= _('Badges')
- if can_edit
= nav_link(controller: [:integrations, :services, :hooks, :hook_logs]) do
= link_to project_settings_integrations_path(@project), title: 'Integrations' do
= link_to project_settings_integrations_path(@project), title: _('Integrations') do
%span
= _('Integrations')
= nav_link(controller: :repository) do
= link_to project_settings_repository_path(@project), title: 'Repository' do
= link_to project_settings_repository_path(@project), title: _('Repository') do
%span
= _('Repository')
- if @project.feature_available?(:builds, current_user)
= nav_link(controller: :ci_cd) do
= link_to project_settings_ci_cd_path(@project), title: 'CI / CD' do
= link_to project_settings_ci_cd_path(@project), title: _('CI / CD') do
%span
= _('CI / CD')
- if @project.pages_available?
= nav_link(controller: :pages) do
= link_to project_pages_path(@project), title: 'Pages' do
= link_to project_pages_path(@project), title: _('Pages') do
%span
= _('Pages')
......@@ -341,7 +341,7 @@
- else
= nav_link(controller: :project_members) do
= link_to project_settings_members_path(@project), title: 'Members', class: 'shortcuts-tree' do
= link_to project_settings_members_path(@project), title: _('Members'), class: 'shortcuts-tree' do
.nav-icon-container
= sprite_icon('users')
%span.nav-item-name
......@@ -356,41 +356,41 @@
-# Shortcut to Project > Activity
%li.hidden
= link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do
= link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do
%span
Activity
= _('Activity')
-# Shortcut to Repository > Graph (formerly, Network)
- if project_nav_tab? :network
%li.hidden
= link_to project_network_path(@project, current_ref), title: 'Network', class: 'shortcuts-network' do
Graph
= link_to project_network_path(@project, current_ref), title: _('Network'), class: 'shortcuts-network' do
= _('Graph')
-# Shortcut to Repository > Charts (formerly, top-nav item "Graphs")
- unless @project.empty_repo?
%li.hidden
= link_to charts_project_graph_path(@project, current_ref), title: 'Charts', class: 'shortcuts-repository-charts' do
Charts
= link_to charts_project_graph_path(@project, current_ref), title: _('Charts'), class: 'shortcuts-repository-charts' do
= _('Charts')
-# Shortcut to Issues > New Issue
- if project_nav_tab?(:issues)
%li.hidden
= link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do
Create a new issue
= _('Create a new issue')
-# Shortcut to Pipelines > Jobs
- if project_nav_tab? :builds
%li.hidden
= link_to project_jobs_path(@project), title: 'Jobs', class: 'shortcuts-builds' do
Jobs
= link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do
= _('Jobs')
-# Shortcut to commits page
- if project_nav_tab? :commits
%li.hidden
= link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do
Commits
= link_to project_commits_path(@project), title: _('Commits'), class: 'shortcuts-commits' do
= _('Commits')
-# Shortcut to issue boards
- if project_nav_tab?(:issues)
%li.hidden
= link_to 'Issue Boards', project_boards_path(@project), title: 'Issue Boards', class: 'shortcuts-issue-boards'
= link_to _('Issue Boards'), project_boards_path(@project), title: _('Issue Boards'), class: 'shortcuts-issue-boards'
......@@ -14,13 +14,12 @@
%br
- if @target_url
- if @reply_by_email
Reply to this email directly or
#{link_to "view it on GitLab", @target_url}.
= _('Reply to this email directly or %{view_it_on_gitlab}.') % { view_it_on_gitlab: link_to(_("view it on GitLab"), @target_url) }
- else
#{link_to "View it on GitLab", @target_url}.
#{link_to _("View it on GitLab"), @target_url}.
%br
-# Don't link the host in the line below, one link in the email is easier to quickly click than two.
You're receiving this email because #{notification_reason_text(@reason)}.
= _("You're receiving this email because %{reason}.") % { reason: notification_reason_text(@reason) }
If you'd like to receive fewer emails, you can
- if @labels_url
adjust your #{link_to 'label subscriptions', @labels_url}.
......
- page_title "User Settings"
- header_title "User Settings", profile_path unless header_title
- page_title _("User Settings")
- header_title _("User Settings"), profile_path unless header_title
- sidebar "dashboard"
- nav "profile"
- @left_sidebar = true
......
- page_title "Settings"
- page_title _("Settings")
- nav "project"
= render template: "layouts/project"
- page_title "Search"
- header_title "Search", search_path
- page_title _("Search")
- header_title _("Search"), search_path
= render template: "layouts/application"
- header_title "Snippets", snippets_path
- header_title _("Snippets"), snippets_path
- content_for :page_specific_javascripts do
- if @snippet && current_user
......
---
title: Rack attack is now disabled by default
merge_request: 16669
author:
type: changed
---
title: Update docs of Helm Tiller
merge_request: 20515
author: Takuya Noguchi
type: other
---
title: Enable frozen string in app/presenters and app/policies
merge_request: 20819
author: gfyoung
type: performance
---
title: Use limit parameter to retrieve Wikis from Gitaly
merge_request: 20764
author:
type: performance
......@@ -501,7 +501,7 @@ Settings['extra'] ||= Settingslogic.new({})
#
Settings['rack_attack'] ||= Settingslogic.new({})
Settings.rack_attack['git_basic_auth'] ||= Settingslogic.new({})
Settings.rack_attack.git_basic_auth['enabled'] = true if Settings.rack_attack.git_basic_auth['enabled'].nil?
Settings.rack_attack.git_basic_auth['enabled'] = false if Settings.rack_attack.git_basic_auth['enabled'].nil?
Settings.rack_attack.git_basic_auth['ip_whitelist'] ||= %w{127.0.0.1}
Settings.rack_attack.git_basic_auth['maxretry'] ||= 10
Settings.rack_attack.git_basic_auth['findtime'] ||= 1.minute
......
......@@ -427,7 +427,7 @@ services:
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
......@@ -440,8 +440,10 @@ build:
```
Here, `$CI_REGISTRY_IMAGE` would be resolved to the address of the registry tied
to this project, and `$CI_COMMIT_REF_NAME` would be resolved to the branch or
tag name for this particular job. We also declare our own variable, `$IMAGE_TAG`,
to this project. Since `$CI_COMMIT_REF_NAME` resolves to the branch or tag name,
and your branch-name can contain forward slashes (e.g., feature/my-feature), it is
safer to use `$CI_COMMIT_REF_SLUG` as the image tag. This is due to that image tags
cannot contain forward slashes. We also declare our own variable, `$IMAGE_TAG`,
combining the two to save us some typing in the `script` section.
Here's a more elaborate example that splits up the tasks into 4 pipeline stages,
......@@ -464,7 +466,7 @@ stages:
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
CONTAINER_TEST_IMAGE: registry.example.com/my-group/my-project/my-image:$CI_COMMIT_REF_NAME
CONTAINER_TEST_IMAGE: registry.example.com/my-group/my-project/my-image:$CI_COMMIT_REF_SLUG
CONTAINER_RELEASE_IMAGE: registry.example.com/my-group/my-project/my-image:latest
before_script:
......
......@@ -219,28 +219,26 @@ below.
- Every piece of documentation that comes with a new feature should declare the
GitLab version that feature got introduced. Right below the heading add a
note:
blockquote:
```md
> Introduced in GitLab 8.3.
```
- Whenever possible, every feature should have a link to the MR, issue, or epic that introduced it.
The above note would be then transformed to:
- Whenever possible, every feature should have a link to the issue, MR or epic
(in that order) that introduced it. The above quote would be then transformed to:
```md
> [Introduced][ce-1242] in GitLab 8.3.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/1242) in GitLab 8.3.
```
, where the [link identifier](#links) is named after the repository (CE) and
the MR number.
- If the feature is only available in GitLab Enterprise Edition, don't forget to mention
the [paid tier](https://about.gitlab.com/handbook/marketing/product-marketing/#tiers)
the feature is available in:
```md
> [Introduced][ee-1234] in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/1242)
in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
```
### Product badges
......
......@@ -4,7 +4,7 @@ To make use of Helm, you must have a [Kubernetes][k8s-io] cluster. Ensure you ca
Helm consists of two parts, the `helm` client and a `tiller` server inside Kubernetes.
> **Note**: If you are not able to run tiller in your cluster, for example on OpenShift, it is possible to use [tiller locally](#local-tiller) and avoid deploying it into the cluster. This should only be used when Tiller cannot be normally deployed.
> **Note**: If you are not able to run Tiller in your cluster, for example on OpenShift, it is possible to use [Tiller locally](https://gitlab.com/charts/gitlab/tree/master/doc/helm#local-tiller) and avoid deploying it into the cluster. This should only be used when Tiller cannot be normally deployed.
## Initialize Helm and Tiller
......@@ -65,28 +65,32 @@ kubectl --username=admin --password=xxxxxxxxxxxxxx create -f rbac-config.yaml
For other clusters like Amazon EKS, you can directly upload the RBAC configuration.
```
kubectl create -f rbac-config.yaml
```
## Initialize Helm
Deploy Helm Tiller with a service account
Deploy Helm Tiller with a service account:
```
helm init --service-account tiller
```
If your cluster
previously had Helm/Tiller installed, run the following to ensure that the deployed version of Tiller matches the local Helm version:
If your cluster previously had Helm/Tiller installed,
run the following to ensure that the deployed version of Tiller matches the local Helm version:
```
helm init --upgrade --service-account tiller
```
### Patching Helm Tiller for EKS
### Patching Helm Tiller for Amazon EKS
Helm Tiller requires a flag to be enabled to work properly on EKS:
Helm Tiller requires a flag to be enabled to work properly on Amazon EKS:
`kubectl -n kube-system patch deployment tiller-deploy -p '{"spec": {"template": {"spec": {"automountServiceAccountToken": true}}}}'`
```
kubectl -n kube-system patch deployment tiller-deploy -p '{"spec": {"template": {"spec": {"automountServiceAccountToken": true}}}}'
```
[helm]: https://helm.sh
[helm-using]: https://docs.helm.sh/using_helm
......
......@@ -18,8 +18,8 @@ limited to 6 requests per minute. After trying for 6 times, the client will
have to wait for the next minute to be able to try again.
If you installed or upgraded GitLab by following the [official guides](../install/README.md)
this should be enabled by default. If your instance is not exposed to any incoming
connections, it is recommended to disable Rack Attack.
this should be disabled by default. If your instance is not exposed to any incoming
connections, it is recommended to leave Rack Attack disabled.
For more information on how to use these options check out
[rack-attack README](https://github.com/kickstarter/rack-attack/blob/master/README.md).
......@@ -49,7 +49,7 @@ For more information on how to use these options check out
The following settings can be configured:
- `enabled`: By default this is set to `true`. Set this to `false` to disable Rack Attack.
- `enabled`: By default this is set to `false`. Set this to `true` to enable Rack Attack.
- `ip_whitelist`: Whitelist any IPs from being blocked. They must be formatted as strings within a ruby array.
For example, `["127.0.0.1", "127.0.0.2", "127.0.0.3"]`.
- `maxretry`: The maximum amount of times a request can be made in the
......
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
......
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
......
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
......
......@@ -44,9 +44,9 @@ module Gitlab
end
end
def pages(limit: nil)
def pages(limit: 0)
@repository.wrapped_gitaly_errors do
gitaly_get_all_pages
gitaly_get_all_pages(limit: limit)
end
end
......@@ -158,8 +158,8 @@ module Gitlab
Gitlab::Git::WikiFile.new(wiki_file)
end
def gitaly_get_all_pages
gitaly_wiki_client.get_all_pages.map do |wiki_page, version|
def gitaly_get_all_pages(limit: 0)
gitaly_wiki_client.get_all_pages(limit: limit).map do |wiki_page, version|
Gitlab::Git::WikiPage.new(wiki_page, version)
end
end
......
......@@ -85,8 +85,8 @@ module Gitlab
wiki_page_from_iterator(response)
end
def get_all_pages
request = Gitaly::WikiGetAllPagesRequest.new(repository: @gitaly_repo)
def get_all_pages(limit: 0)
request = Gitaly::WikiGetAllPagesRequest.new(repository: @gitaly_repo, limit: limit)
response = GitalyClient.call(@repository.storage, :wiki_service, :wiki_get_all_pages, request, timeout: GitalyClient.medium_timeout)
pages = []
......
......@@ -278,6 +278,12 @@ msgstr ""
msgid "A user with write access to the source branch selected this option"
msgstr ""
msgid "About GitLab"
msgstr ""
msgid "About GitLab CE"
msgstr ""
msgid "About auto deploy"
msgstr ""
......@@ -371,6 +377,15 @@ msgstr ""
msgid "Additional text"
msgstr ""
msgid "Admin Area"
msgstr ""
msgid "Admin Overview"
msgstr ""
msgid "Admin area"
msgstr ""
msgid "AdminArea|Stop all jobs"
msgstr ""
......@@ -596,6 +611,9 @@ msgstr ""
msgid "Anonymous"
msgstr ""
msgid "Anti-spam verification"
msgstr ""
msgid "Any"
msgstr ""
......@@ -710,6 +728,9 @@ msgstr ""
msgid "Authentication Log"
msgstr ""
msgid "Authentication log"
msgstr ""
msgid "Author"
msgstr ""
......@@ -734,6 +755,9 @@ msgstr ""
msgid "Authors: %{authors}"
msgstr ""
msgid "Auto DevOps"
msgstr ""
msgid "Auto DevOps enabled"
msgstr ""
......@@ -794,6 +818,9 @@ msgstr ""
msgid "Background Color"
msgstr ""
msgid "Background Jobs"
msgstr ""
msgid "Background color"
msgstr ""
......@@ -947,6 +974,9 @@ msgstr ""
msgid "Bitbucket import"
msgstr ""
msgid "Blog"
msgstr ""
msgid "Boards"
msgstr ""
......@@ -1789,6 +1819,9 @@ msgstr ""
msgid "ClusterIntegration|sign up"
msgstr ""
msgid "Cohorts"
msgstr ""
msgid "Collapse"
msgstr ""
......@@ -2036,6 +2069,9 @@ msgstr ""
msgid "Control the maximum concurrency of verification operations for this Geo node"
msgstr ""
msgid "ConvDev Index"
msgstr ""
msgid "Copy SSH public key to clipboard"
msgstr ""
......@@ -2078,6 +2114,9 @@ msgstr ""
msgid "Create a new branch and merge request"
msgstr ""
msgid "Create a new issue"
msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
......@@ -2219,6 +2258,9 @@ msgstr ""
msgid "CycleAnalyticsStage|Test"
msgstr ""
msgid "Dashboard"
msgstr ""
msgid "DashboardProjects|All"
msgstr ""
......@@ -2764,6 +2806,9 @@ msgstr ""
msgid "Every week (Sundays at 4:00am)"
msgstr ""
msgid "Everyone can contribute"
msgstr ""
msgid "Expand"
msgstr ""
......@@ -2773,6 +2818,9 @@ msgstr ""
msgid "Expand sidebar"
msgstr ""
msgid "Explore"
msgstr ""
msgid "Explore GitLab"
msgstr ""
......@@ -2809,6 +2857,9 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
msgid "Facebook"
msgstr ""
msgid "Failed"
msgstr ""
......@@ -3270,6 +3321,9 @@ msgstr ""
msgid "Group avatar"
msgstr ""
msgid "Group details"
msgstr ""
msgid "Group info:"
msgstr ""
......@@ -3670,6 +3724,9 @@ msgstr ""
msgid "Koding"
msgstr ""
msgid "Koding Dashboard"
msgstr ""
msgid "Kubernetes"
msgstr ""
......@@ -3801,6 +3858,9 @@ msgstr ""
msgid "License"
msgstr ""
msgid "LinkedIn"
msgstr ""
msgid "List"
msgstr ""
......@@ -3846,12 +3906,18 @@ msgstr ""
msgid "Locks give the ability to lock specific file or folder."
msgstr ""
msgid "Logs"
msgstr ""
msgid "Make everyone on your team more productive regardless of their location. GitLab Geo creates read-only mirrors of your GitLab instance so you can reduce the time it takes to clone and fetch large repos."
msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
msgid "Manage Git repositories with fine-grained access controls that keep your code secure. Perform code reviews and enhance collaboration with merge requests. Each project can also have an issue tracker and a wiki."
msgstr ""
msgid "Manage access"
msgstr ""
......@@ -4119,6 +4185,9 @@ msgstr ""
msgid "Months"
msgstr ""
msgid "More"
msgstr ""
msgid "More actions"
msgstr ""
......@@ -4167,6 +4236,9 @@ msgstr ""
msgid "Nav|Sign out and sign in with a different account"
msgstr ""
msgid "Network"
msgstr ""
msgid "New"
msgstr ""
......@@ -4244,6 +4316,9 @@ msgstr ""
msgid "New tag"
msgstr ""
msgid "New..."
msgstr ""
msgid "No"
msgstr ""
......@@ -4451,6 +4526,12 @@ msgstr ""
msgid "Open in Xcode"
msgstr ""
msgid "Open sidebar"
msgstr ""
msgid "Open source software to collaborate on code"
msgstr ""
msgid "Opened"
msgstr ""
......@@ -4778,6 +4859,9 @@ msgstr ""
msgid "Profile"
msgstr ""
msgid "Profile Settings"
msgstr ""
msgid "Profiles|Account scheduled for removal."
msgstr ""
......@@ -5195,6 +5279,9 @@ msgstr ""
msgid "Repair authentication"
msgstr ""
msgid "Reply to this email directly or %{view_it_on_gitlab}."
msgstr ""
msgid "Repo by URL"
msgstr ""
......@@ -5225,6 +5312,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
msgid "Requests Profiles"
msgstr ""
msgid "Require all users to accept Terms of Service and Privacy Policy when they access GitLab."
msgstr ""
......@@ -5539,6 +5629,9 @@ msgstr ""
msgid "SharedRunnersMinutesSettings|Reset used pipeline minutes"
msgstr ""
msgid "Sherlock Transactions"
msgstr ""
msgid "Show command"
msgstr ""
......@@ -5580,6 +5673,12 @@ msgstr ""
msgid "Sidebar|Weight"
msgstr ""
msgid "Sign in"
msgstr ""
msgid "Sign in / Register"
msgstr ""
msgid "Sign in to %{group_name}"
msgstr ""
......@@ -5823,6 +5922,9 @@ msgstr ""
msgid "Status"
msgstr ""
msgid "Stop impersonation"
msgstr ""
msgid "Stop this environment"
msgstr ""
......@@ -5859,6 +5961,9 @@ msgstr ""
msgid "System Hooks"
msgstr ""
msgid "System Info"
msgstr ""
msgid "System header and footer:"
msgstr ""
......@@ -6131,6 +6236,9 @@ msgstr ""
msgid "This directory"
msgstr ""
msgid "This group"
msgstr ""
msgid "This group allows you to sign in with your %{group_name} Single Sign-On account. This will redirect you to an external sign in page."
msgstr ""
......@@ -6453,12 +6561,18 @@ msgstr ""
msgid "Todo"
msgstr ""
msgid "Todos"
msgstr ""
msgid "Toggle Sidebar"
msgstr ""
msgid "Toggle discussion"
msgstr ""
msgid "Toggle navigation"
msgstr ""
msgid "Toggle sidebar"
msgstr ""
......@@ -6507,6 +6621,9 @@ msgstr ""
msgid "Turn on Service Desk"
msgstr ""
msgid "Twitter"
msgstr ""
msgid "Unable to load the diff. %{button_try_again}"
msgstr ""
......@@ -6623,6 +6740,9 @@ msgstr ""
msgid "Used by members to sign in to your group in GitLab"
msgstr ""
msgid "User Settings"
msgstr ""
msgid "User and IP Rate Limits"
msgstr ""
......@@ -6665,6 +6785,9 @@ msgstr ""
msgid "View issue"
msgstr ""
msgid "View it on GitLab"
msgstr ""
msgid "View jobs"
msgstr ""
......@@ -6707,6 +6830,9 @@ msgstr ""
msgid "Want to see the data? Please ask an administrator for access."
msgstr ""
msgid "We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed."
msgstr ""
msgid "We don't have enough data to show this stage."
msgstr ""
......@@ -7013,9 +7139,18 @@ msgstr ""
msgid "You'll need to use different branch names to get a valid comparison."
msgstr ""
msgid "You're receiving this email because %{reason}."
msgstr ""
msgid "You're receiving this email because of your account on %{host}."
msgstr ""
msgid "You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}"
msgstr ""
msgid "YouTube"
msgstr ""
msgid "Your Groups"
msgstr ""
......@@ -7607,6 +7742,9 @@ msgstr ""
msgid "uses Kubernetes clusters to deploy your code!"
msgstr ""
msgid "view it on GitLab"
msgstr ""
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
......
......@@ -5,8 +5,8 @@ module QA
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :settings_item
element :settings_link, 'link_to edit_project_path'
element :repository_link, "title: 'Repository'"
element :pipelines_settings_link, "title: 'CI / CD'"
element :repository_link, "title: _('Repository')"
element :pipelines_settings_link, "title: _('CI / CD')"
element :operations_kubernetes_link, "title: _('Kubernetes')"
element :issues_link, /link_to.*shortcuts-issues/
element :issues_link_text, "Issues"
......@@ -14,7 +14,7 @@ module QA
element :merge_requests_link_text, "Merge Requests"
element :top_level_items, '.sidebar-top-level-items'
element :operations_section, "class: 'shortcuts-operations'"
element :activity_link, "title: 'Activity'"
element :activity_link, "title: _('Activity')"
element :wiki_link_text, "Wiki"
element :milestones_link
end
......
......@@ -16,7 +16,7 @@ module QA
view 'app/views/layouts/header/_new_dropdown.haml' do
element :new_menu_toggle
element :new_issue_link, "link_to 'New issue', new_project_issue_path(@project)"
element :new_issue_link, "link_to _('New issue'), new_project_issue_path(@project)"
end
view 'app/views/shared/_ref_switcher.html.haml' do
......
require 'spec_helper'
describe Projects::WikisController do
let(:project) { create(:project_empty_repo, :public) }
let(:project) { create(:project, :public, :repository) }
let(:user) { create(:user) }
let(:wiki) { ProjectWiki.new(project, user) }
describe 'GET #show' do
let(:wiki_title) { 'page-title-test' }
render_views
before do
create_page(wiki_title, 'hello world')
end
it 'limits the retrieved pages for the sidebar' do
sign_in(user)
expect(controller).to receive(:load_wiki).and_return(wiki)
# empty? call
expect(wiki).to receive(:pages).with(limit: 1).and_call_original
# Sidebar entries
expect(wiki).to receive(:pages).with(limit: 15).and_call_original
get :show, namespace_id: project.namespace, project_id: project, id: wiki_title
expect(response).to have_http_status(:ok)
expect(response.body).to include(wiki_title)
end
end
describe 'POST #preview_markdown' do
it 'renders json in a correct format' do
......@@ -13,4 +40,12 @@ describe Projects::WikisController do
expect(JSON.parse(response.body).keys).to match_array(%w(body references))
end
end
def create_page(name, content)
project.wiki.wiki.write_page(name, :markdown, content, commit_details(name))
end
def commit_details(name)
Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "created page #{name}")
end
end
......@@ -6,6 +6,31 @@ describe Gitlab::Git::Wiki do
let(:project_wiki) { ProjectWiki.new(project, user) }
subject { project_wiki.wiki }
describe '#pages' do
before do
create_page('page1', 'content')
create_page('page2', 'content2')
end
after do
destroy_page('page1')
destroy_page('page2')
end
it 'returns all the pages' do
expect(subject.pages.count).to eq(2)
expect(subject.pages.first.title).to eq 'page1'
expect(subject.pages.last.title).to eq 'page2'
end
it 'returns only one page' do
pages = subject.pages(limit: 1)
expect(pages.count).to eq(1)
expect(pages.first.title).to eq 'page1'
end
end
describe '#page' do
before do
create_page('page1', 'content')
......
......@@ -70,6 +70,15 @@ describe Gitlab::GitalyClient::WikiService do
subject
end
it 'sends a limit of 0 to wiki_get_all_pages' do
expect_any_instance_of(Gitaly::WikiService::Stub)
.to receive(:wiki_get_all_pages)
.with(gitaly_request_with_params(limit: 0), kind_of(Hash))
.and_return([].each)
subject
end
it 'concatenates the raw data and returns a pair of WikiPage and WikiPageVersion for each page' do
expect_any_instance_of(Gitaly::WikiService::Stub)
.to receive(:wiki_get_all_pages)
......@@ -84,5 +93,18 @@ describe Gitlab::GitalyClient::WikiService do
expect(wiki_page_2.raw_data).to eq('cd')
expect(wiki_page_2_version.format).to eq('markdown')
end
context 'with limits' do
subject { client.get_all_pages(limit: 1) }
it 'sends a request with the limit' do
expect_any_instance_of(Gitaly::WikiService::Stub)
.to receive(:wiki_get_all_pages)
.with(gitaly_request_with_params(limit: 1), kind_of(Hash))
.and_return([].each)
subject
end
end
end
end
......@@ -381,6 +381,10 @@ describe 'Git HTTP requests' do
context "when authentication fails" do
context "when the user is IP banned" do
before do
Gitlab.config.rack_attack.git_basic_auth['enabled'] = true
end
it "responds with status 401" do
expect(Rack::Attack::Allow2Ban).to receive(:filter).and_return(true)
allow_any_instance_of(Rack::Request).to receive(:ip).and_return('1.2.3.4')
......@@ -420,6 +424,10 @@ describe 'Git HTTP requests' do
end
context "when the user isn't blocked" do
before do
Gitlab.config.rack_attack.git_basic_auth['enabled'] = true
end
it "resets the IP in Rack Attack on download" do
expect(Rack::Attack::Allow2Ban).to receive(:reset).twice
......
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