Commit 6c8d2b99 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge remote-tracking branch 'ce-com/master' into ce-to-ee

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parents de5170d2 f0886918
......@@ -12,6 +12,12 @@
&.readme-holder {
margin: $gl-padding 0;
&.limited-width-container .file-content {
max-width: $limited-layout-width-sm;
margin-left: auto;
margin-right: auto;
}
}
table {
......
......@@ -53,7 +53,7 @@ body {
}
&.limit-container-width-sm {
max-width: 790px;
max-width: $limited-layout-width-sm;
}
}
......
......@@ -161,6 +161,7 @@ $progress-color: #c0392b;
$header-height: 50px;
$fixed-layout-width: 1280px;
$limited-layout-width: 990px;
$limited-layout-width-sm: 790px;
$gl-avatar-size: 40px;
$error-exclamation-point: $red-500;
$border-radius-default: 3px;
......
......@@ -11,7 +11,9 @@
.commit-box,
.info-well,
.commit-ci-menu,
.files-changed {
.files-changed,
.limited-header-width,
.limited-width-notes {
@extend .fixed-width-container;
}
......
......@@ -15,7 +15,7 @@ module GroupsHelper
@has_group_title = true
full_title = ''
group.ancestors.each do |parent|
group.ancestors.reverse.each do |parent|
full_title += link_to(simple_sanitize(parent.name), group_path(parent), class: 'group-path hidable')
full_title += '<span class="hidable"> / </span>'.html_safe
end
......
......@@ -4,7 +4,7 @@
= icon('caret-down')
.dropdown-menu-nav.dropdown-menu-align-right
%ul
- if @group
- if @group&.persisted?
- 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
......@@ -18,7 +18,7 @@
%li.divider
%li.dropdown-bold-header GitLab
- if @project && @project.persisted?
- if @project&.persisted?
- create_project_issue = can?(current_user, :create_issue, @project)
- merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
- create_project_snippet = can?(current_user, :create_project_snippet, @project)
......
......@@ -48,7 +48,7 @@
= f.text_field :id, readonly: true, label: 'User ID', wrapper: { class: 'col-md-3' }
- if @user.external_email?
= f.text_field :email, required: true, readonly: true, help: 'Your email address was automatically set based on your #{email_provider_label} account.'
= f.text_field :email, required: true, readonly: true, help: "Your email address was automatically set based on your #{email_provider_label} account."
- else
= f.text_field :email, required: true, value: (@user.email unless @user.temp_oauth_email?),
help: user_email_help_text(@user)
......
- @no_container = true
- container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : ''
- limited_container_width = fluid_layout || diff_view == :inline ? '' : 'limit-container-width'
- limited_container_width = fluid_layout ? '' : 'limit-container-width'
- page_title "#{@commit.title} (#{@commit.short_id})", "Commits"
- page_description @commit.description
= render "projects/commits/head"
......@@ -13,7 +13,8 @@
.block-connector
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
= render "shared/notes/notes_with_form", :autocomplete => true
- if can_collaborate_with_project?
- %w(revert cherry-pick).each do |type|
= render "projects/commit/change", type: type, commit: @commit, title: @commit.title
.limited-width-notes
= render "shared/notes/notes_with_form", :autocomplete => true
- if can_collaborate_with_project?
- %w(revert cherry-pick).each do |type|
= render "projects/commit/change", type: type, commit: @commit, title: @commit.title
- @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout
- page_title "#{@snippet.title} (#{@snippet.to_reference})", "Snippets"
= render 'shared/snippets/header'
......@@ -9,4 +10,4 @@
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true
#notes= render "shared/notes/notes_with_form", :autocomplete => true
#notes.limited-width-notes= render "shared/notes/notes_with_form", :autocomplete => true
- if readme.rich_viewer
%article.file-holder.readme-holder
%article.file-holder.readme-holder{ class: ("limited-width-container" unless fluid_layout) }
.js-file-title.file-title
= blob_icon readme.mode, readme.name
= link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, readme.path)) do
......
......@@ -3,7 +3,7 @@
.modal-content
.modal-header
%button.close{ type: "button", "aria-label": "close", data: { dismiss: "modal" } }
%span{ "aria-hidden": "true" } } ×
%span{ "aria-hidden": "true" } ×
%h4#custom-notifications-title.modal-title
#{ _('Custom notification events') }
......
......@@ -16,7 +16,7 @@
- else
= render "snippets/actions"
.snippet-header
.snippet-header.limited-header-width
%h2.snippet-title.prepend-top-0.append-bottom-0
= markdown_field(@snippet, :title)
......
- @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout
- page_title "#{@snippet.title} (#{@snippet.to_reference})", "Snippets"
= render 'shared/snippets/header'
......@@ -9,4 +10,4 @@
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true
#notes= render "shared/notes/notes_with_form", :autocomplete => false
#notes.limited-width-notes= render "shared/notes/notes_with_form", :autocomplete => false
---
title: Update QA Dockerfile to lock Chrome browser version
merge_request: 12071
author:
---
title: Limit commit & snippets comments width
merge_request:
author:
---
title: Don't match tilde and exclamation mark as part of requirements.txt package
name
merge_request:
author:
---
title: Fix reversed breadcrumb order for nested groups
merge_request: 12322
author:
---
title: Fix 500 when failing to create private group
merge_request: 12394
author:
---
title: Limit the width of the projects README text
merge_request:
author:
......@@ -2,6 +2,8 @@
class SetMissingStageOnCiBuilds < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def up
update_column_in_batches(:ci_builds, :stage, :test) do |table, query|
query.where(table[:stage].eq(nil))
......
......@@ -5,6 +5,8 @@ class DropAndReaddHasExternalWikiInProjects < ActiveRecord::Migration
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:projects, :has_external_wiki, nil) do |table, query|
query.where(table[:has_external_wiki].not_eq(nil))
......
......@@ -4,6 +4,8 @@ class SetConfidentialIssuesEventsOnWebhooks < ActiveRecord::Migration
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:web_hooks, :confidential_issues_events, true) do |table, query|
query.where(table[:issues_events].eq(true))
......
......@@ -5,6 +5,8 @@ class AddTypeToLabels < ActiveRecord::Migration
DOWNTIME = true
DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.'
disable_ddl_transaction!
def change
add_column :labels, :type, :string
......
......@@ -4,6 +4,8 @@ class MakeProjectOwnersMasters < ActiveRecord::Migration
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:members, :access_level, 40) do |table, query|
query.where(table[:access_level].eq(50).and(table[:source_type].eq('Project')))
......
......@@ -4,6 +4,8 @@ class RenameSlackAndMattermostNotificationServices < ActiveRecord::Migration
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:services, :type, 'SlackService') do |table, query|
query.where(table[:type].eq('SlackNotificationService'))
......
......@@ -4,6 +4,8 @@ class ResetRelativePositionForIssue < ActiveRecord::Migration
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:issues, :relative_position, nil) do |table, query|
query.where(table[:relative_position].not_eq(nil))
......@@ -11,5 +13,6 @@ class ResetRelativePositionForIssue < ActiveRecord::Migration
end
def down
# noop
end
end
......@@ -7,6 +7,8 @@ class UpdateUploadPathsToSystem < ActiveRecord::Migration
DOWNTIME = false
AFFECTED_MODELS = %w(User Project Note Namespace Appearance)
disable_ddl_transaction!
def up
update_column_in_batches(:uploads, :path, replace_sql(arel_table[:path], base_directory, new_upload_dir)) do |_table, query|
query.where(uploads_to_switch_to_new_path)
......
......@@ -7,6 +7,8 @@ class MigrateUserProjectView < ActiveRecord::Migration
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:users, :project_view, 2) do |table, query|
query.where(table[:project_view].eq(0))
......
......@@ -3,6 +3,8 @@ class AddHeadPipelineForEachMergeRequest < ActiveRecord::Migration
DOWNTIME = false
disable_ddl_transaction!
def up
disable_statement_timeout
......
......@@ -155,7 +155,7 @@ Find more information about different Runners in the
[Runners](../runners/README.md) documentation.
You can find whether any Runners are assigned to your project by going to
**Settings ➔ CI/CD Pipelines**. Setting up a Runner is easy and straightforward. The
**Settings ➔ Pipelines**. Setting up a Runner is easy and straightforward. The
official Runner supported by GitLab is written in Go and its documentation
can be found at <https://docs.gitlab.com/runner/>.
......@@ -168,7 +168,7 @@ Follow the links above to set up your own Runner or use a Shared Runner as
described in the next section.
Once the Runner has been set up, you should see it on the Runners page of your
project, following **Settings ➔ CI/CD Pipelines**.
project, following **Settings ➔ Pipelines**.
![Activated runners](img/runners_activated.png)
......@@ -181,7 +181,7 @@ These are special virtual machines that run on GitLab's infrastructure and can
build any project.
To enable the **Shared Runners** you have to go to your project's
**Settings ➔ CI/CD Pipelines** and click **Enable shared runners**.
**Settings ➔ Pipelines** and click **Enable shared runners**.
[Read more on Shared Runners](../runners/README.md).
......
......@@ -95,15 +95,16 @@ installation (e.g. the number of users, projects, etc).
We currently support the following databases:
- PostgreSQL (highly recommended)
- MySQL/MariaDB (doesn't support all features)
- MySQL/MariaDB (strongly discouraged, not all GitLab features are supported, no support for [MySQL/MariaDB GTID](https://mariadb.com/kb/en/mariadb/gtid/))
We **highly recommend** the use of PostgreSQL instead of MySQL/MariaDB as not all
We highly recommend the use of PostgreSQL instead of MySQL/MariaDB as not all
features of GitLab work with MySQL/MariaDB:
1. MySQL support for subgroups was [dropped with GitLab 9.3][post].
See [issue #30472][30472] for more information.
1. GitLab Geo does [not support MySQL](https://docs.gitlab.com/ee/gitlab-geo/database.html#mysql-replication).
1. [Zero downtime migrations][zero] do not work with MySQL
1. We expect this list to grow over time.
Existing users using GitLab with MySQL/MariaDB are advised to
[migrate to PostgreSQL](../update/mysql_to_postgresql.md) instead.
......
# Pipelines settings
To reach the pipelines settings navigate to your project's
**Settings ➔ CI/CD Pipelines**.
**Settings ➔ Pipelines**.
The following settings can be configured per project.
......
......@@ -222,6 +222,12 @@ module Gitlab
#
# rubocop: disable Metrics/AbcSize
def update_column_in_batches(table, column, value)
if transaction_open?
raise 'update_column_in_batches can not be run inside a transaction, ' \
'you can disable transactions by calling disable_ddl_transaction! ' \
'in the body of your migration class'
end
table = Arel::Table.new(table)
count_arel = table.project(Arel.star.count.as('count'))
......
......@@ -6,7 +6,7 @@ module Gitlab
private
def link_dependencies
link_regex(/^(?<name>(?![a-z+]+:)[^#.-][^ ><=;\[]+)/) do |name|
link_regex(/^(?<name>(?![a-z+]+:)[^#.-][^ ><=~!;\[]+)/) do |name|
"https://pypi.python.org/pypi/#{name}"
end
......
FROM ruby:2.3
LABEL maintainer "Grzegorz Bizon <grzegorz@gitlab.com>"
ENV CHROME_VERSION 59.0.3071.109-1
ENV CHROME_DRIVER_VERSION 2.30
##
# Update APT sources and install some dependencies
#
......@@ -8,15 +11,16 @@ RUN sed -i "s/httpredir.debian.org/ftp.us.debian.org/" /etc/apt/sources.list
RUN apt-get update && apt-get install -y wget git unzip xvfb
##
# At this point Google Chrome Beta is 59 - first version with headless support
# Install Google Chrome version with headless support
#
RUN wget -q https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb
RUN dpkg -i google-chrome-beta_current_amd64.deb; apt-get -fy install
RUN curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list
RUN apt-get update -q && DEBIAN_FRONTEND=noninteractive apt-get install -y google-chrome-stable=$CHROME_VERSION
##
# Install chromedriver to make it work with Selenium
#
RUN wget -q https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip
RUN wget -q https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip
RUN unzip chromedriver_linux64.zip -d /usr/local/bin
RUN apt-get clean
......
......@@ -55,7 +55,7 @@ module QA
Capybara.register_driver :chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
'binary' => '/opt/google/chrome-beta/google-chrome-beta',
'binary' => '/usr/bin/google-chrome-stable',
'args' => %w[headless no-sandbox disable-gpu]
}
)
......
require 'spec_helper'
describe GroupsHelper do
include ApplicationHelper
let(:group) { create(:group) }
describe 'group_icon' do
......@@ -100,4 +102,15 @@ describe GroupsHelper do
end
end
end
describe 'group_title' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deep_nested_group) { create(:group, parent: nested_group) }
let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
it 'outputs the groups in the correct order' do
expect(group_title(very_deep_nested_group)).to match(/>#{group.name}<\/a>.*>#{nested_group.name}<\/a>.*>#{deep_nested_group.name}<\/a>/)
end
end
end
......@@ -262,39 +262,53 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
describe '#update_column_in_batches' do
before do
create_list(:empty_project, 5)
end
context 'when running outside of a transaction' do
before do
expect(model).to receive(:transaction_open?).and_return(false)
it 'updates all the rows in a table' do
model.update_column_in_batches(:projects, :import_error, 'foo')
create_list(:empty_project, 5)
end
expect(Project.where(import_error: 'foo').count).to eq(5)
end
it 'updates all the rows in a table' do
model.update_column_in_batches(:projects, :import_error, 'foo')
it 'updates boolean values correctly' do
model.update_column_in_batches(:projects, :archived, true)
expect(Project.where(import_error: 'foo').count).to eq(5)
end
expect(Project.where(archived: true).count).to eq(5)
end
it 'updates boolean values correctly' do
model.update_column_in_batches(:projects, :archived, true)
expect(Project.where(archived: true).count).to eq(5)
end
context 'when a block is supplied' do
it 'yields an Arel table and query object to the supplied block' do
first_id = Project.first.id
context 'when a block is supplied' do
it 'yields an Arel table and query object to the supplied block' do
first_id = Project.first.id
model.update_column_in_batches(:projects, :archived, true) do |t, query|
query.where(t[:id].eq(first_id))
end
model.update_column_in_batches(:projects, :archived, true) do |t, query|
query.where(t[:id].eq(first_id))
expect(Project.where(archived: true).count).to eq(1)
end
end
context 'when the value is Arel.sql (Arel::Nodes::SqlLiteral)' do
it 'updates the value as a SQL expression' do
model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1'))
expect(Project.where(archived: true).count).to eq(1)
expect(Project.sum(:star_count)).to eq(2 * Project.count)
end
end
end
context 'when the value is Arel.sql (Arel::Nodes::SqlLiteral)' do
it 'updates the value as a SQL expression' do
model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1'))
context 'when running inside the transaction' do
it 'raises RuntimeError' do
expect(model).to receive(:transaction_open?).and_return(true)
expect(Project.sum(:star_count)).to eq(2 * Project.count)
expect do
model.update_column_in_batches(:projects, :star_count, Arel.sql('1+1'))
end.to raise_error(RuntimeError)
end
end
end
......@@ -303,7 +317,9 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
context 'outside of a transaction' do
context 'when a column limit is not set' do
before do
expect(model).to receive(:transaction_open?).and_return(false)
expect(model).to receive(:transaction_open?)
.and_return(false)
.at_least(:once)
expect(model).to receive(:transaction).and_yield
......@@ -810,7 +826,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
let!(:user) { create(:user, name: 'Kathy Alice Aliceson') }
it 'replaces the correct part of the string' do
model.update_column_in_batches(:users, :name, model.replace_sql(Arel::Table.new(:users)[:name], 'Alice', 'Eve'))
allow(model).to receive(:transaction_open?).and_return(false)
query = model.replace_sql(Arel::Table.new(:users)[:name], 'Alice', 'Eve')
model.update_column_in_batches(:users, :name, query)
expect(user.reload.name).to eq('Kathy Eve Aliceson')
end
end
......
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase do
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :truncate do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
......
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :truncate do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
......
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects do
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :truncate do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
......
......@@ -13,7 +13,7 @@ shared_examples 'renames child namespaces' do |type|
end
end
describe Gitlab::Database::RenameReservedPathsMigration::V1 do
describe Gitlab::Database::RenameReservedPathsMigration::V1, :truncate do
let(:subject) { FakeRenameReservedPathMigrationV1.new }
before do
......
......@@ -54,6 +54,8 @@ describe Gitlab::DependencyLinker::RequirementsTxtLinker, lib: true do
Sphinx>=1.3
docutils>=0.7
markupsafe
pytest~=3.0
foop!=3.0
CONTENT
end
......@@ -78,6 +80,8 @@ describe Gitlab::DependencyLinker::RequirementsTxtLinker, lib: true do
expect(subject).to include(link('Sphinx', 'https://pypi.python.org/pypi/Sphinx'))
expect(subject).to include(link('docutils', 'https://pypi.python.org/pypi/docutils'))
expect(subject).to include(link('markupsafe', 'https://pypi.python.org/pypi/markupsafe'))
expect(subject).to include(link('pytest', 'https://pypi.python.org/pypi/pytest'))
expect(subject).to include(link('foop', 'https://pypi.python.org/pypi/foop'))
end
it 'links URLs' do
......
......@@ -21,7 +21,7 @@ describe Gitlab::VisibilityLevel, lib: true do
describe '.levels_for_user' do
it 'returns all levels for an admin' do
user = double(:user, has_full_private_access?: true)
user = build(:user, :admin)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::PRIVATE,
......@@ -30,7 +30,7 @@ describe Gitlab::VisibilityLevel, lib: true do
end
it 'returns INTERNAL and PUBLIC for internal users' do
user = double(:user, has_full_private_access?: false, external?: false)
user = build(:user)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::INTERNAL,
......@@ -38,7 +38,7 @@ describe Gitlab::VisibilityLevel, lib: true do
end
it 'returns PUBLIC for external users' do
user = double(:user, has_full_private_access?: false, external?: true)
user = build(:user, :external)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::PUBLIC])
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170508170547_add_head_pipeline_for_each_merge_request.rb')
describe AddHeadPipelineForEachMergeRequest do
describe AddHeadPipelineForEachMergeRequest, :truncate do
let(:migration) { described_class.new }
let!(:project) { create(:empty_project) }
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170324160416_migrate_user_activities_to_users_last_activity_on.rb')
describe MigrateUserActivitiesToUsersLastActivityOn, :redis do
describe MigrateUserActivitiesToUsersLastActivityOn, :redis, :truncate do
let(:migration) { described_class.new }
let!(:user_active_1) { create(:user) }
let!(:user_active_2) { create(:user) }
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170406142253_migrate_user_project_view.rb')
describe MigrateUserProjectView do
describe MigrateUserProjectView, :truncate do
let(:migration) { described_class.new }
let!(:user) { create(:user) }
......
......@@ -1869,43 +1869,6 @@ describe User, models: true do
end
end
describe '.ghost' do
it "creates a ghost user if one isn't already present" do
ghost = User.ghost
expect(ghost).to be_ghost
expect(ghost).to be_persisted
end
it "does not create a second ghost user if one is already present" do
expect do
User.ghost
User.ghost
end.to change { User.count }.by(1)
expect(User.ghost).to eq(User.ghost)
end
context "when a regular user exists with the username 'ghost'" do
it "creates a ghost user with a non-conflicting username" do
create(:user, username: 'ghost')
ghost = User.ghost
expect(ghost).to be_persisted
expect(ghost.username).to eq('ghost1')
end
end
context "when a regular user exists with the email 'ghost@example.com'" do
it "creates a ghost user with a non-conflicting email" do
create(:user, email: 'ghost@example.com')
ghost = User.ghost
expect(ghost).to be_persisted
expect(ghost.email).to eq('ghost1@example.com')
end
end
end
describe '.ghost' do
it "creates a ghost user if one isn't already present" do
ghost = User.ghost
......
......@@ -21,24 +21,26 @@ describe 'projects/commit/show.html.haml', :view do
context 'inline diff view' do
before do
allow(view).to receive(:diff_view).and_return(:inline)
allow(view).to receive(:diff_view).and_return(:inline)
render
end
it 'keeps container-limited' do
expect(rendered).not_to have_selector('.limit-container-width')
it 'has limited width' do
expect(rendered).to have_selector('.limit-container-width')
end
end
context 'parallel diff view' do
before do
allow(view).to receive(:diff_view).and_return(:parallel)
allow(view).to receive(:fluid_layout).and_return(true)
render
end
it 'spans full width' do
expect(rendered).to have_selector('.limit-container-width')
expect(rendered).not_to have_selector('.limit-container-width')
end
end
end
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