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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-09 18:07:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-09 18:07:42 +0300
commit263f926c770163788f78af03ab69689c94f57360 (patch)
tree4e1027e596629106d25fa461a1cf3d613749d279
parentcddaddb86bf6d4d277d206c42a9138a2d660ea56 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Gemfile6
-rw-r--r--Gemfile.lock34
-rw-r--r--app/controllers/projects/performance_monitoring/dashboards_controller.rb96
-rw-r--r--app/models/project.rb1
-rw-r--r--changelogs/unreleased/22327-add-ci-server-url.yml5
-rw-r--r--changelogs/unreleased/update-project-hook-limits-100.yml5
-rw-r--r--config/routes/project.rb4
-rw-r--r--db/migrate/20200108100603_update_project_hooks_limit.rb23
-rw-r--r--db/schema.rb2
-rw-r--r--doc/ci/variables/README.md5
-rw-r--r--doc/ci/variables/predefined_variables.md1
-rw-r--r--doc/policy/maintenance.md8
-rw-r--r--doc/update/README.md39
-rw-r--r--doc/update/upgrading_from_source.md11
-rw-r--r--doc/user/project/img/deploy_boards_landing_page.pngbin16107 -> 43047 bytes
-rw-r--r--doc/user/project/integrations/webhooks.md6
-rw-r--r--spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb204
-rw-r--r--spec/frontend/vue_shared/components/gl_modal_vuex_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js23
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_row_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js7
-rw-r--r--spec/models/ci/build_spec.rb1
-rw-r--r--spec/requests/api/deployments_spec.rb32
23 files changed, 446 insertions, 82 deletions
diff --git a/Gemfile b/Gemfile
index 0c4f8d83782..a7bc797e6e3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -129,9 +129,9 @@ gem 'unf', '~> 0.1.4'
gem 'seed-fu', '~> 2.3.7'
# Search
-gem 'elasticsearch-model', '~> 0.1.9'
-gem 'elasticsearch-rails', '~> 0.1.9', require: 'elasticsearch/rails/instrumentation'
-gem 'elasticsearch-api', '5.0.3'
+gem 'elasticsearch-model', '~> 6.1'
+gem 'elasticsearch-rails', '~> 6.1', require: 'elasticsearch/rails/instrumentation'
+gem 'elasticsearch-api', '~> 6.8'
gem 'aws-sdk'
gem 'faraday_middleware-aws-signers-v4'
diff --git a/Gemfile.lock b/Gemfile.lock
index 6a19d35774d..c1b88ae54fc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -235,17 +235,17 @@ GEM
doorkeeper (~> 4.3)
json-jwt (~> 1.6)
ed25519 (1.2.4)
- elasticsearch (5.0.3)
- elasticsearch-api (= 5.0.3)
- elasticsearch-transport (= 5.0.3)
- elasticsearch-api (5.0.3)
+ elasticsearch (6.8.0)
+ elasticsearch-api (= 6.8.0)
+ elasticsearch-transport (= 6.8.0)
+ elasticsearch-api (6.8.0)
multi_json
- elasticsearch-model (0.1.9)
+ elasticsearch-model (6.1.0)
activesupport (> 3)
- elasticsearch (> 0.4)
+ elasticsearch (> 1)
hashie
- elasticsearch-rails (0.1.9)
- elasticsearch-transport (5.0.3)
+ elasticsearch-rails (6.1.0)
+ elasticsearch-transport (6.8.0)
faraday
multi_json
email_reply_trimmer (0.1.6)
@@ -270,7 +270,7 @@ GEM
factory_bot_rails (5.1.0)
factory_bot (~> 5.1.0)
railties (>= 4.2.0)
- faraday (0.12.2)
+ faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-http-cache (2.0.0)
faraday (~> 0.8)
@@ -478,7 +478,7 @@ GEM
tilt
hangouts-chat (0.0.5)
hashdiff (0.3.8)
- hashie (3.5.7)
+ hashie (3.6.0)
hashie-forbidden_attributes (0.1.1)
hashie (>= 3.0)
health_check (2.6.0)
@@ -506,7 +506,7 @@ GEM
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
- i18n (1.7.0)
+ i18n (1.7.1)
concurrent-ruby (~> 1.0)
i18n_data (0.8.0)
icalendar (2.4.1)
@@ -615,9 +615,9 @@ GEM
mini_portile2 (2.4.0)
minitest (5.11.3)
msgpack (1.3.1)
- multi_json (1.13.1)
+ multi_json (1.14.1)
multi_xml (0.6.0)
- multipart-post (2.0.0)
+ multipart-post (2.1.1)
murmurhash3 (0.1.6)
mustermann (1.0.3)
mustermann-grape (1.0.0)
@@ -1048,7 +1048,7 @@ GEM
truncato (0.7.11)
htmlentities (~> 4.3.1)
nokogiri (>= 1.7.0, <= 2.0)
- tzinfo (1.2.5)
+ tzinfo (1.2.6)
thread_safe (~> 0.1)
u2f (0.2.1)
uber (0.1.0)
@@ -1173,9 +1173,9 @@ DEPENDENCIES
doorkeeper (~> 4.3)
doorkeeper-openid_connect (~> 1.5)
ed25519 (~> 1.2)
- elasticsearch-api (= 5.0.3)
- elasticsearch-model (~> 0.1.9)
- elasticsearch-rails (~> 0.1.9)
+ elasticsearch-api (~> 6.8)
+ elasticsearch-model (~> 6.1)
+ elasticsearch-rails (~> 6.1)
email_reply_trimmer (~> 0.1)
email_spec (~> 2.2.0)
escape_utils (~> 1.1)
diff --git a/app/controllers/projects/performance_monitoring/dashboards_controller.rb b/app/controllers/projects/performance_monitoring/dashboards_controller.rb
new file mode 100644
index 00000000000..c873fcd6c8a
--- /dev/null
+++ b/app/controllers/projects/performance_monitoring/dashboards_controller.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+module Projects
+ module PerformanceMonitoring
+ class DashboardsController < ::Projects::ApplicationController
+ include BlobHelper
+
+ before_action :check_repository_available!
+ before_action :validate_required_params!
+ before_action :validate_dashboard_template!
+ before_action :authorize_push!
+
+ USER_DASHBOARDS_DIR = ::Metrics::Dashboard::ProjectDashboardService::DASHBOARD_ROOT
+ DASHBOARD_TEMPLATES = {
+ ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH => ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH
+ }.freeze
+
+ def create
+ result = ::Files::CreateService.new(project, current_user, dashboard_attrs).execute
+
+ if result[:status] == :success
+ respond_success
+ else
+ respond_error(result[:message])
+ end
+ end
+
+ private
+
+ def respond_success
+ respond_to do |format|
+ format.html { redirect_to ide_edit_path(project, redirect_safe_branch_name, new_dashboard_path) }
+ format.json { render json: { redirect_to: ide_edit_path(project, redirect_safe_branch_name, new_dashboard_path) }, status: :created }
+ end
+ end
+
+ def respond_error(message)
+ flash[:alert] = message
+
+ respond_to do |format|
+ format.html { redirect_back_or_default(default: namespace_project_environments_path) }
+ format.json { render json: { error: message }, status: :bad_request }
+ end
+ end
+
+ def authorize_push!
+ access_denied!(%q(You can't commit to this project)) unless user_access(project).can_push_to_branch?(params[:branch])
+ end
+
+ def validate_required_params!
+ params.require(%i(branch file_name dashboard))
+ end
+
+ def validate_dashboard_template!
+ access_denied! unless dashboard_template
+ end
+
+ def dashboard_attrs
+ {
+ commit_message: commit_message,
+ file_path: new_dashboard_path,
+ file_content: new_dashboard_content,
+ encoding: 'text',
+ branch_name: params[:branch],
+ start_branch: repository.branch_exists?(params[:branch]) ? params[:branch] : project.default_branch
+ }
+ end
+
+ def commit_message
+ params[:commit_message] || "Create custom dashboard #{params[:file_name]}"
+ end
+
+ def new_dashboard_path
+ File.join(USER_DASHBOARDS_DIR, params[:file_name])
+ end
+
+ def new_dashboard_content
+ File.read(Rails.root.join(dashboard_template))
+ end
+
+ def dashboard_template
+ dashboard_templates[params[:dashboard]]
+ end
+
+ def dashboard_templates
+ DASHBOARD_TEMPLATES
+ end
+
+ def redirect_safe_branch_name
+ repository.find_branch(params[:branch]).name
+ end
+ end
+ end
+end
+
+Projects::PerformanceMonitoring::DashboardsController.prepend_if_ee('EE::Projects::PerformanceMonitoring::DashboardsController')
diff --git a/app/models/project.rb b/app/models/project.rb
index 25819bc2b85..6858d03098c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1932,6 +1932,7 @@ class Project < ApplicationRecord
Gitlab::Ci::Variables::Collection.new
.append(key: 'CI', value: 'true')
.append(key: 'GITLAB_CI', value: 'true')
+ .append(key: 'CI_SERVER_URL', value: Gitlab.config.gitlab.url)
.append(key: 'CI_SERVER_HOST', value: Gitlab.config.gitlab.host)
.append(key: 'CI_SERVER_NAME', value: 'GitLab')
.append(key: 'CI_SERVER_VERSION', value: Gitlab::VERSION)
diff --git a/changelogs/unreleased/22327-add-ci-server-url.yml b/changelogs/unreleased/22327-add-ci-server-url.yml
new file mode 100644
index 00000000000..1103d2538db
--- /dev/null
+++ b/changelogs/unreleased/22327-add-ci-server-url.yml
@@ -0,0 +1,5 @@
+---
+title: Add CI variable to provide GitLab base URL
+merge_request: 22327
+author: Aidin Abedi
+type: added
diff --git a/changelogs/unreleased/update-project-hook-limits-100.yml b/changelogs/unreleased/update-project-hook-limits-100.yml
new file mode 100644
index 00000000000..ae95c78a28a
--- /dev/null
+++ b/changelogs/unreleased/update-project-hook-limits-100.yml
@@ -0,0 +1,5 @@
+---
+title: Update project hooks limits to 100 for all plans
+merge_request: 22604
+author:
+type: other
diff --git a/config/routes/project.rb b/config/routes/project.rb
index f339be7d0f5..be207f155f9 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -259,6 +259,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
+ namespace :performance_monitoring do
+ resources :dashboards, only: [:create]
+ end
+
namespace :error_tracking do
resources :projects, only: :index
end
diff --git a/db/migrate/20200108100603_update_project_hooks_limit.rb b/db/migrate/20200108100603_update_project_hooks_limit.rb
new file mode 100644
index 00000000000..91533b69afa
--- /dev/null
+++ b/db/migrate/20200108100603_update_project_hooks_limit.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class UpdateProjectHooksLimit < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ return unless Gitlab.com?
+
+ create_or_update_plan_limit('project_hooks', 'free', 100)
+ create_or_update_plan_limit('project_hooks', 'bronze', 100)
+ create_or_update_plan_limit('project_hooks', 'silver', 100)
+ end
+
+ def down
+ return unless Gitlab.com?
+
+ create_or_update_plan_limit('project_hooks', 'free', 10)
+ create_or_update_plan_limit('project_hooks', 'bronze', 20)
+ create_or_update_plan_limit('project_hooks', 'silver', 30)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ca27c33d6f1..1d2b4020915 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2020_01_06_085831) do
+ActiveRecord::Schema.define(version: 2020_01_08_100603) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 384216fed2c..6dc093b6d0f 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -290,6 +290,7 @@ export CI_RUNNER_ID="10"
export CI_RUNNER_DESCRIPTION="my runner"
export CI_RUNNER_TAGS="docker, linux"
export CI_SERVER="yes"
+export CI_SERVER_URL="https://example.com"
export CI_SERVER_HOST="example.com"
export CI_SERVER_NAME="GitLab"
export CI_SERVER_REVISION="70606bf"
@@ -673,6 +674,8 @@ Running on runner-8a2f473d-project-1796893-concurrent-0 via runner-8a2f473d-mach
++ CI_PROJECT_DIR=/builds/gitlab-examples/ci-debug-trace
++ export CI_SERVER=yes
++ CI_SERVER=yes
+++ export CI_SERVER_URL=https://example.com:3000
+++ CI_SERVER_URL=https://example.com:3000
++ export 'CI_SERVER_HOST=example.com'
++ CI_SERVER_HOST='example.com'
++ export 'CI_SERVER_NAME=GitLab CI'
@@ -709,6 +712,8 @@ Running on runner-8a2f473d-project-1796893-concurrent-0 via runner-8a2f473d-mach
++ CI_JOB_NAME=debug_trace
++ export CI_JOB_STAGE=test
++ CI_JOB_STAGE=test
+++ export CI_SERVER_URL=https://example.com:3000
+++ CI_SERVER_URL=https://example.com:3000
++ export CI_SERVER_HOST=example.com
++ CI_SERVER_HOST=example.com
++ export CI_SERVER_NAME=GitLab
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index 678ac285176..9200ef69a31 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -112,6 +112,7 @@ future GitLab releases.**
| `CI_RUNNER_TAGS` | 8.10 | 0.5 | The defined runner tags |
| `CI_RUNNER_VERSION` | all | 10.6 | GitLab Runner version that is executing the current job |
| `CI_SERVER` | all | all | Mark that job is executed in CI environment |
+| `CI_SERVER_URL` | 12.7 | all | The base URL of the GitLab instance, including protocol and port (like `https://gitlab.example.com:8080`) |
| `CI_SERVER_HOST` | 12.1 | all | Host component of the GitLab instance URL, without protocol and port (like `gitlab.example.com`) |
| `CI_SERVER_NAME` | all | all | The name of CI server that is used to coordinate jobs |
| `CI_SERVER_REVISION` | all | all | GitLab revision that is used to schedule jobs |
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index ba561810fab..1739c07ccd5 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -139,6 +139,11 @@ We cannot guarantee that upgrading between major versions will be seamless. As p
We recommend that you first upgrade to the latest available minor version within
your major version. By doing this, you can address any deprecation messages
that could change behavior in the next major release.
+
+It's also important to ensure that any background migrations have been fully completed
+before upgrading to a new major version. To see the current size of the `background_migration` queue,
+[Check for background migrations before upgrading](../update/README.md#checking-for-background-migrations-before-upgrading).
+
To ensure background migrations are successful, increment by one minor version during the version jump before installing newer releases.
For example: `11.11.x` -> `12.0.x`
@@ -151,9 +156,6 @@ Please see the table below for some examples:
| 11.3.4 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9`, `10.8.7` is the last version in version `10` |
| 12.5.8 | 11.3.4 | `11.3.4` -> `11.11.8` -> `12.0.9` -> `12.5.8` | `11.11.8` is the last version in version `11` |
-To check the size of `background_migration` queue and to learn more about background migrations
-see [Upgrading without downtime](../update/README.md#upgrading-without-downtime).
-
More information about the release procedures can be found in our
[release documentation](https://gitlab.com/gitlab-org/release/docs). You may also want to read our
[Responsible Disclosure Policy](https://about.gitlab.com/security/disclosure/).
diff --git a/doc/update/README.md b/doc/update/README.md
index 6834deb1a85..e9db0a73ac5 100644
--- a/doc/update/README.md
+++ b/doc/update/README.md
@@ -69,13 +69,8 @@ before continuing the upgrading procedure. While this won't require downtime
between upgrading major/minor releases, allowing the background migrations to
finish. The time necessary to complete these migrations can be reduced by
increasing the number of Sidekiq workers that can process jobs in the
-`background_migration` queue. To check the size of this queue,
-[start a Rails console session](https://docs.gitlab.com/omnibus/maintenance/#starting-a-rails-console-session)
-and run the command below:
-
-```ruby
-Sidekiq::Queue.new('background_migration').size
-```
+`background_migration` queue. To see the size of this queue,
+[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading).
As a rule of thumb, any database smaller than 10 GB won't take too much time to
upgrade; perhaps an hour at most per minor release. Larger databases however may
@@ -112,6 +107,36 @@ meet the other online upgrade requirements mentioned above.
Steps to [upgrade without downtime][omni-zero-downtime].
+## Checking for background migrations before upgrading
+
+Certain major/minor releases may require a set of background migrations to be
+finished. The number of remaining migrations jobs can be found by running the
+following command:
+
+**For Omnibus installations**
+
+```bash
+sudo gitlab-rails runner -e production 'puts Sidekiq::Queue.new("background_migration").size'
+```
+
+**For installations from source**
+
+```
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Sidekiq::Queue.new("background_migration").size'
+```
+
+## Upgrading to a new major version
+
+Major versions are reserved for backwards incompatible changes. We recommend that
+you first upgrade to the latest available minor version within your major version.
+Please follow the [Upgrade Recommendations](../policy/maintenance.md#upgrade-recommendations)
+to identify the ideal upgrade path.
+
+Before upgrading to a new major version, you should ensure that any background
+migration jobs from previous releases have been completed. The number of remaining
+migrations jobs can be found by running the following command:
+
## Upgrading between editions
GitLab comes in two flavors: [Community Edition][ce] which is MIT licensed,
diff --git a/doc/update/upgrading_from_source.md b/doc/update/upgrading_from_source.md
index 4157b4f7bc5..aeb99261c4b 100644
--- a/doc/update/upgrading_from_source.md
+++ b/doc/update/upgrading_from_source.md
@@ -23,6 +23,17 @@ guide links by version.
If you are changing from GitLab Community Edition to GitLab Enterprise Edition, see
the [Upgrading from CE to EE](upgrading_from_ce_to_ee.md) documentation.
+## Upgrading to a new major version
+
+Major versions are reserved for backwards incompatible changes. We recommend that
+you first upgrade to the latest available minor version within your major version.
+Please follow the [Upgrade Recommendations](../policy/maintenance.md#upgrade-recommendations)
+to identify the ideal upgrade path.
+
+Before upgrading to a new major version, you should ensure that any background
+migration jobs from previous releases have been completed. To see the current size of the `background_migration` queue,
+[Check for background migrations before upgrading](README.md#checking-for-background-migrations-before-upgrading).
+
## Guidelines for all versions
This section contains all the steps necessary to upgrade Community Edition or
diff --git a/doc/user/project/img/deploy_boards_landing_page.png b/doc/user/project/img/deploy_boards_landing_page.png
index c9621a06860..73b3724d657 100644
--- a/doc/user/project/img/deploy_boards_landing_page.png
+++ b/doc/user/project/img/deploy_boards_landing_page.png
Binary files differ
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index bb946574371..79cda9a045e 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -56,9 +56,9 @@ tier](https://about.gitlab.com/pricing/), as shown in the following table:
| Tier | Number of webhooks per project |
|----------|--------------------------------|
-| Free | 10 |
-| Bronze | 20 |
-| Silver | 30 |
+| Free | 100 |
+| Bronze | 100 |
+| Silver | 100 |
| Gold | 100 |
## Use-cases
diff --git a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
new file mode 100644
index 00000000000..6ae37fe6d2f
--- /dev/null
+++ b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
@@ -0,0 +1,204 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::PerformanceMonitoring::DashboardsController do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:namespace) { create(:namespace) }
+ let!(:project) { create(:project, :repository, name: 'dashboard-project', namespace: namespace) }
+ let(:repository) { project.repository }
+ let(:branch) { double(name: branch_name) }
+ let(:commit_message) { 'test' }
+ let(:branch_name) { "#{Time.current.to_i}_dashboard_new_branch" }
+ let(:dashboard) { 'config/prometheus/common_metrics.yml' }
+ let(:file_name) { 'custom_dashboard.yml' }
+ let(:params) do
+ {
+ namespace_id: namespace,
+ project_id: project,
+ dashboard: dashboard,
+ file_name: file_name,
+ commit_message: commit_message,
+ branch: branch_name,
+ format: :json
+ }
+ end
+
+ describe 'POST #create' do
+ context 'authenticated user' do
+ before do
+ sign_in(user)
+ end
+
+ context 'project with repository feature' do
+ context 'with rights to push to the repository' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'valid parameters' do
+ it 'delegates commit creation to service' do
+ allow(controller).to receive(:repository).and_return(repository)
+ allow(repository).to receive(:find_branch).and_return(branch)
+ dashboard_attrs = {
+ commit_message: commit_message,
+ branch_name: branch_name,
+ start_branch: 'master',
+ encoding: 'text',
+ file_path: '.gitlab/dashboards/custom_dashboard.yml',
+ file_content: File.read('config/prometheus/common_metrics.yml')
+ }
+
+ service_instance = instance_double(::Files::CreateService)
+ expect(::Files::CreateService).to receive(:new).with(project, user, dashboard_attrs).and_return(service_instance)
+ expect(service_instance).to receive(:execute).and_return(status: :success)
+
+ post :create, params: params
+ end
+
+ it 'extends dashboard template path to absolute url' do
+ allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: :success }))
+ allow(controller).to receive(:repository).and_return(repository)
+ allow(repository).to receive(:find_branch).and_return(branch)
+
+ expect(File).to receive(:read).with(Rails.root.join('config/prometheus/common_metrics.yml')).and_return('')
+
+ post :create, params: params
+ end
+
+ context 'selected branch already exists' do
+ it 'responds with :created status code', :aggregate_failures do
+ repository.add_branch(user, branch_name, 'master')
+
+ post :create, params: params
+
+ expect(response).to have_gitlab_http_status :created
+ end
+ end
+
+ context 'request format json' do
+ it 'returns path to new file' do
+ allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: :success }))
+ allow(controller).to receive(:repository).and_return(repository)
+
+ expect(repository).to receive(:find_branch).with(branch_name).and_return(branch)
+
+ post :create, params: params
+
+ expect(response).to have_gitlab_http_status :created
+ expect(json_response).to eq('redirect_to' => "/-/ide/project/#{namespace.path}/#{project.name}/edit/#{branch_name}/-/.gitlab/dashboards/#{file_name}")
+ end
+
+ context 'files create service failure' do
+ it 'returns json with failure message' do
+ allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: false, message: 'something went wrong' }))
+
+ post :create, params: params
+
+ expect(response).to have_gitlab_http_status :bad_request
+ expect(response).to set_flash[:alert].to eq('something went wrong')
+ expect(json_response).to eq('error' => 'something went wrong')
+ end
+ end
+ end
+
+ context 'request format html' do
+ before do
+ params.delete(:format)
+ end
+
+ it 'redirects to ide with new file' do
+ allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: :success }))
+ allow(controller).to receive(:repository).and_return(repository)
+
+ expect(repository).to receive(:find_branch).with(branch_name).and_return(branch)
+
+ post :create, params: params
+
+ expect(response).to redirect_to "/-/ide/project/#{namespace.path}/#{project.name}/edit/#{branch_name}/-/.gitlab/dashboards/#{file_name}"
+ end
+
+ context 'files create service failure' do
+ it 'redirects back and sets alert' do
+ allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: false, message: 'something went wrong' }))
+ allow(controller).to receive(:repository).and_return(repository)
+ allow(repository).to receive(:find_branch).and_return(branch)
+
+ post :create, params: params
+
+ expect(response).to set_flash[:alert].to eq('something went wrong')
+ expect(response).to redirect_to namespace_project_environments_path
+ end
+ end
+ end
+ end
+
+ context 'invalid dashboard template' do
+ let(:dashboard) { 'config/database.yml' }
+
+ it 'responds 404 not found' do
+ post :create, params: params
+
+ expect(response).to have_gitlab_http_status :not_found
+ end
+ end
+
+ context 'missing commit message' do
+ before do
+ params.delete(:commit_message)
+ end
+
+ it 'use default commit message' do
+ allow(controller).to receive(:repository).and_return(repository)
+ allow(repository).to receive(:find_branch).and_return(branch)
+ dashboard_attrs = {
+ commit_message: 'Create custom dashboard custom_dashboard.yml',
+ branch_name: branch_name,
+ start_branch: 'master',
+ encoding: 'text',
+ file_path: ".gitlab/dashboards/custom_dashboard.yml",
+ file_content: File.read('config/prometheus/common_metrics.yml')
+ }
+
+ service_instance = instance_double(::Files::CreateService)
+ expect(::Files::CreateService).to receive(:new).with(project, user, dashboard_attrs).and_return(service_instance)
+ expect(service_instance).to receive(:execute).and_return(status: :success)
+
+ post :create, params: params
+ end
+ end
+
+ context 'missing branch' do
+ let(:branch_name) { nil }
+
+ it 'raises ActionController::ParameterMissing' do
+ expect { post :create, params: params }.to raise_error ActionController::ParameterMissing
+ end
+ end
+ end
+
+ context 'without rights to push to repository' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'responds with :forbidden status code' do
+ post :create, params: params
+
+ expect(response).to have_gitlab_http_status :forbidden
+ end
+ end
+ end
+
+ context 'project without repository feature' do
+ let!(:project) { create(:project, name: 'dashboard-project', namespace: namespace) }
+
+ it 'responds with :not_found status code' do
+ post :create, params: params
+
+ expect(response).to have_gitlab_http_status :not_found
+ end
+ end
+ end
+ end
+end
diff --git a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
index 4b7636041b6..8437e68d73c 100644
--- a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
+++ b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
@@ -33,7 +33,7 @@ describe('GlModalVuex', () => {
...options.propsData,
};
- wrapper = shallowMount(localVue.extend(GlModalVuex), {
+ wrapper = shallowMount(GlModalVuex, {
...options,
localVue,
store,
@@ -123,8 +123,8 @@ describe('GlModalVuex', () => {
state.isVisible = true;
- localVue
- .nextTick()
+ wrapper.vm
+ .$nextTick()
.then(() => {
expect(rootEmit).toHaveBeenCalledWith('bv::show::modal', TEST_MODAL_ID);
})
@@ -140,8 +140,8 @@ describe('GlModalVuex', () => {
state.isVisible = false;
- localVue
- .nextTick()
+ wrapper.vm
+ .$nextTick()
.then(() => {
expect(rootEmit).toHaveBeenCalledWith('bv::hide::modal', TEST_MODAL_ID);
})
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 2569f2f02a7..7a05bf092f5 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -1,4 +1,4 @@
-import { mount, createLocalVue } from '@vue/test-utils';
+import { mount } from '@vue/test-utils';
import fieldComponent from '~/vue_shared/components/markdown/field.vue';
import { TEST_HOST, FIXTURES_PATH } from 'spec/test_constants';
import AxiosMockAdapter from 'axios-mock-adapter';
@@ -50,7 +50,6 @@ const getVideo = wrapper => wrapper.find('video');
describe('Markdown field component', () => {
let axiosMock;
- const localVue = createLocalVue();
beforeEach(() => {
axiosMock = new AxiosMockAdapter(axios);
@@ -84,7 +83,7 @@ describe('Markdown field component', () => {
previewLink = getPreviewLink(wrapper);
previewLink.trigger('click');
- return localVue.nextTick().then(() => {
+ return wrapper.vm.$nextTick().then(() => {
expect(previewLink.element.parentNode.classList.contains('active')).toBeTruthy();
});
});
@@ -94,7 +93,7 @@ describe('Markdown field component', () => {
previewLink = getPreviewLink(wrapper);
previewLink.trigger('click');
- localVue.nextTick(() => {
+ wrapper.vm.$nextTick(() => {
expect(wrapper.find('.md-preview-holder').element.textContent.trim()).toContain(
'Loading…',
);
@@ -155,17 +154,17 @@ describe('Markdown field component', () => {
previewLink = getPreviewLink(wrapper);
writeLink.trigger('click');
- return localVue
- .nextTick()
+ return wrapper.vm
+ .$nextTick()
.then(() => assertMarkdownTabs(true, writeLink, previewLink, wrapper))
.then(() => writeLink.trigger('click'))
- .then(() => localVue.nextTick())
+ .then(() => wrapper.vm.$nextTick())
.then(() => assertMarkdownTabs(true, writeLink, previewLink, wrapper))
.then(() => previewLink.trigger('click'))
- .then(() => localVue.nextTick())
+ .then(() => wrapper.vm.$nextTick())
.then(() => assertMarkdownTabs(false, writeLink, previewLink, wrapper))
.then(() => previewLink.trigger('click'))
- .then(() => localVue.nextTick())
+ .then(() => wrapper.vm.$nextTick())
.then(() => assertMarkdownTabs(false, writeLink, previewLink, wrapper));
});
});
@@ -178,7 +177,7 @@ describe('Markdown field component', () => {
const markdownButton = getMarkdownButton(wrapper);
markdownButton.trigger('click');
- localVue.nextTick(() => {
+ wrapper.vm.$nextTick(() => {
expect(textarea.value).toContain('**testing**');
});
});
@@ -190,7 +189,7 @@ describe('Markdown field component', () => {
const markdownButton = getAllMarkdownButtons(wrapper).wrappers[5];
markdownButton.trigger('click');
- localVue.nextTick(() => {
+ wrapper.vm.$nextTick(() => {
expect(textarea.value).toContain('* testing');
});
});
@@ -202,7 +201,7 @@ describe('Markdown field component', () => {
const markdownButton = getAllMarkdownButtons(wrapper).wrappers[5];
markdownButton.trigger('click');
- localVue.nextTick(() => {
+ wrapper.vm.$nextTick(() => {
expect(textarea.value).toContain('* testing\n* 123');
});
});
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_row_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_row_spec.js
index 8e6ac6a5fab..97fcdc67791 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_row_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_row_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import SuggestionDiffRow from '~/vue_shared/components/markdown/suggestion_diff_row.vue';
const oldLine = {
@@ -27,10 +27,7 @@ describe('SuggestionDiffRow', () => {
let wrapper;
const factory = (options = {}) => {
- const localVue = createLocalVue();
-
wrapper = shallowMount(SuggestionDiffRow, {
- localVue,
...options,
});
};
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
index 491e672b0e4..6f66d1cafb9 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import { TEST_HOST } from 'spec/test_constants';
import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue';
@@ -20,8 +20,6 @@ const createList = n =>
.fill(1)
.map((x, id) => createUser(id));
-const localVue = createLocalVue();
-
describe('UserAvatarList', () => {
let props;
let wrapper;
@@ -32,9 +30,8 @@ describe('UserAvatarList', () => {
...options.propsData,
};
- wrapper = shallowMount(localVue.extend(UserAvatarList), {
+ wrapper = shallowMount(UserAvatarList, {
...options,
- localVue,
propsData,
});
};
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index b6006fa9bb7..21644ea5dec 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -2359,6 +2359,7 @@ describe Ci::Build do
{ key: 'CI_BUILD_STAGE', value: 'test', public: true, masked: false },
{ key: 'CI', value: 'true', public: true, masked: false },
{ key: 'GITLAB_CI', value: 'true', public: true, masked: false },
+ { key: 'CI_SERVER_URL', value: Gitlab.config.gitlab.url, public: true, masked: false },
{ key: 'CI_SERVER_HOST', value: Gitlab.config.gitlab.host, public: true, masked: false },
{ key: 'CI_SERVER_NAME', value: 'GitLab', public: true, masked: false },
{ key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true, masked: false },
diff --git a/spec/requests/api/deployments_spec.rb b/spec/requests/api/deployments_spec.rb
index 96b14339469..7e184cea3c0 100644
--- a/spec/requests/api/deployments_spec.rb
+++ b/spec/requests/api/deployments_spec.rb
@@ -346,37 +346,25 @@ describe API::Deployments do
context 'prevent N + 1 queries' do
context 'when the endpoint returns multiple records' do
let(:project) { create(:project, :repository) }
+ let!(:deployment) { create(:deployment, :success, project: project) }
- def create_record
- create(:deployment, :success, project: project)
- end
-
- def request_with_query_count
- ActiveRecord::QueryRecorder.new { trigger_request }.count
- end
-
- def trigger_request
- get api("/projects/#{project.id}/deployments?order_by=updated_at&sort=asc", user)
- end
+ subject { get api("/projects/#{project.id}/deployments?order_by=updated_at&sort=asc", user) }
- before do
- create_record
- end
-
- it 'succeeds' do
- trigger_request
+ it 'succeeds', :aggregate_failures do
+ subject
expect(response).to have_gitlab_http_status(200)
-
expect(json_response.size).to eq(1)
end
- it 'does not increase the query count' do
- 10.times { create_record }
+ context 'with 10 more records' do
+ it 'does not increase the query count', :aggregate_failures do
+ create_list(:deployment, 10, :success, project: project)
- expect { trigger_request }.not_to be_n_plus_1_query
+ expect { subject }.not_to be_n_plus_1_query
- expect(json_response.size).to eq(11)
+ expect(json_response.size).to eq(11)
+ end
end
end
end