Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-04-28 09:09:34 +00:00
parent 99454db49e
commit 0f59ad0c29
41 changed files with 464 additions and 343 deletions

View File

@ -1,5 +1,3 @@
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
stages:
- sync
- prepare
@ -16,6 +14,7 @@ stages:
# in cases where jobs require Docker-in-Docker, the job
# definition must be extended with `.use-docker-in-docker`
default:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-9.6-graphicsmagick-1.3.34"
tags:
- gitlab-org
# All jobs are interruptible by default

View File

@ -3,9 +3,9 @@
- .default-retry
- .default-cache
- .default-before_script
- .use-pg11
- .use-pg9
stage: test
needs: ["setup-test-env pg11"]
needs: ["setup-test-env pg9"]
variables:
FIXTURE_PATH: "db/fixtures/development"
SEED_CYCLE_ANALYTICS: "true"
@ -26,7 +26,7 @@ run-dev-fixtures-ee:
extends:
- .run-dev-fixtures
- .dev-fixtures:rules:ee-only
- .use-pg11-ee
- .use-pg9-ee
script:
- scripts/gitaly-test-spawn
- cp ee/db/fixtures/development/* $FIXTURE_PATH

View File

@ -66,9 +66,9 @@ graphql-reference-verify:
- .default-cache
- .default-before_script
- .docs:rules:graphql-reference-verify
- .use-pg11
- .use-pg9
stage: test
needs: ["setup-test-env pg11"]
needs: ["setup-test-env pg9"]
script:
- bundle exec rake gitlab:graphql:check_docs
- bundle exec rake gitlab:graphql:check_schema

View File

@ -129,9 +129,9 @@ compile-assets pull-cache as-if-foss:
- .default-retry
- .default-cache
- .default-before_script
- .use-pg11
- .use-pg9
stage: fixtures
needs: ["setup-test-env pg11", "compile-assets pull-cache"]
needs: ["setup-test-env pg9", "compile-assets pull-cache"]
script:
- date
- scripts/gitaly-test-spawn

View File

@ -8,7 +8,7 @@
memory-static:
extends: .only-code-memory-job-base
stage: test
needs: ["setup-test-env pg11"]
needs: ["setup-test-env pg9"]
variables:
SETUP_DB: "false"
script:
@ -36,9 +36,9 @@ memory-static:
memory-on-boot:
extends:
- .only-code-memory-job-base
- .use-pg11
- .use-pg9
stage: test
needs: ["setup-test-env pg11", "compile-assets pull-cache"]
needs: ["setup-test-env pg9", "compile-assets pull-cache"]
variables:
NODE_ENV: "production"
RAILS_ENV: "production"

View File

@ -1,5 +1,5 @@
.rails:needs:setup-and-assets:
needs: ["setup-test-env pg11", "compile-assets pull-cache"]
needs: ["setup-test-env pg9", "compile-assets pull-cache"]
.rails-job-base:
extends:
@ -7,8 +7,8 @@
- .default-cache
- .default-before_script
####################
# EE and FOSS jobs #
#######################################################
# EE/FOSS: default refs (MRs, master, schedules) jobs #
.base-setup-test-env:
extends:
- .rails-job-base
@ -28,19 +28,19 @@
setup-test-env pg11:
extends:
- .base-setup-test-env
- .rails:rules:default-refs-code-backstage-qa
- .rails:rules:master-push--master-schedule-2-hourly--code-backstage
- .use-pg11
setup-test-env pg10:
extends:
- .base-setup-test-env
- .rails:rules:master-refs-code-backstage
- .rails:rules:master-schedule-nightly--code-backstage
- .use-pg10
setup-test-env pg9:
extends:
- .base-setup-test-env
- .rails:rules:nightly-master-refs-code-backstage
- .rails:rules:default-refs-code-backstage-qa
- .use-pg9
static-analysis:
@ -55,7 +55,7 @@ static-analysis:
script:
- scripts/static-analysis
cache:
key: "ruby-2.6.5-pg11-rubocop"
key: "ruby-2.6.5-pg9-rubocop"
paths:
- vendor/ruby
- tmp/rubocop_cache
@ -75,7 +75,7 @@ downtime_check:
.rspec-base:
extends: .rails-job-base
stage: test
needs: ["setup-test-env pg11", "retrieve-tests-metadata", "compile-assets pull-cache"]
needs: ["setup-test-env pg9", "retrieve-tests-metadata", "compile-assets pull-cache"]
script:
- source scripts/rspec_helpers.sh
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag ~level:migration"
@ -93,37 +93,37 @@ downtime_check:
reports:
junit: junit_rspec.xml
.rspec-base-pg11:
.rspec-base-pg9:
extends:
- .rspec-base
- .rails:rules:ee-and-foss
- .use-pg11
- .use-pg9
.rspec-base-migration:
script:
- source scripts/rspec_helpers.sh
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
rspec migration pg11:
rspec migration pg9:
extends:
- .rspec-base-pg11
- .rspec-base-pg9
- .rspec-base-migration
parallel: 5
rspec unit pg11:
extends: .rspec-base-pg11
rspec unit pg9:
extends: .rspec-base-pg9
parallel: 20
rspec integration pg11:
extends: .rspec-base-pg11
rspec integration pg9:
extends: .rspec-base-pg9
parallel: 8
rspec system pg11:
extends: .rspec-base-pg11
rspec system pg9:
extends: .rspec-base-pg9
parallel: 24
rspec fast_spec_helper:
extends: .rspec-base-pg11
extends: .rspec-base-pg9
script:
- bin/rspec spec/fast_spec_helper.rb
@ -131,9 +131,9 @@ rspec fast_spec_helper:
extends:
- .rails-job-base
- .rails:rules:ee-and-foss
- .use-pg11
- .use-pg9
stage: test
needs: ["setup-test-env pg11"]
needs: ["setup-test-env pg9"]
db:migrate:reset:
extends: .db-job-base
@ -202,18 +202,18 @@ rspec:coverage:
# We cannot use needs since it would mean needing 84 jobs (since most are parallelized)
# so we use `dependencies` here.
dependencies:
- setup-test-env pg11
- rspec migration pg11
- rspec unit pg11
- rspec integration pg11
- rspec system pg11
- rspec-ee migration pg11
- rspec-ee unit pg11
- rspec-ee integration pg11
- rspec-ee system pg11
- rspec-ee unit pg11 geo
- rspec-ee integration pg11 geo
- rspec-ee system pg11 geo
- setup-test-env pg9
- rspec migration pg9
- rspec unit pg9
- rspec integration pg9
- rspec system pg9
- rspec-ee migration pg9
- rspec-ee unit pg9
- rspec-ee integration pg9
- rspec-ee system pg9
- rspec-ee unit pg9 geo
- rspec-ee integration pg9 geo
- rspec-ee system pg9 geo
- memory-static
- memory-on-boot
variables:
@ -231,15 +231,166 @@ rspec:coverage:
- coverage/index.html
- coverage/assets/
- tmp/memory_test/
# EE and FOSS jobs #
####################
# EE/FOSS: default refs (MRs, master, schedules) jobs #
#######################################################
####################
# master-only jobs #
##################################################
# EE: default refs (MRs, master, schedules) jobs #
.rspec-base-ee:
extends:
- .rspec-base
- .rails:rules:ee-only
.rspec-base-pg9-as-if-foss:
extends:
- .rspec-base-ee
- .as-if-foss
- .use-pg9
needs: ["setup-test-env pg9", "retrieve-tests-metadata", "compile-assets pull-cache as-if-foss"]
.rspec-ee-base-pg9:
extends:
- .rspec-base-ee
- .use-pg9-ee
rspec migration pg9-as-if-foss:
extends:
- .rspec-base-pg9-as-if-foss
- .rspec-base-migration
parallel: 5
rspec unit pg9-as-if-foss:
extends: .rspec-base-pg9-as-if-foss
parallel: 20
rspec integration pg9-as-if-foss:
extends: .rspec-base-pg9-as-if-foss
parallel: 8
rspec system pg9-as-if-foss:
extends: .rspec-base-pg9-as-if-foss
parallel: 24
rspec-ee migration pg9:
extends:
- .rspec-ee-base-pg9
- .rspec-base-migration
parallel: 2
rspec-ee unit pg9:
extends: .rspec-ee-base-pg9
parallel: 10
rspec-ee integration pg9:
extends: .rspec-ee-base-pg9
parallel: 4
rspec-ee system pg9:
extends: .rspec-ee-base-pg9
parallel: 6
.rspec-ee-base-geo:
extends: .rspec-base-ee
script:
- source scripts/rspec_helpers.sh
- scripts/prepare_postgres_fdw.sh
- rspec_paralellized_job "--tag ~quarantine --tag geo"
.rspec-ee-base-geo-pg9:
extends:
- .rspec-ee-base-geo
- .use-pg9-ee
rspec-ee unit pg9 geo:
extends: .rspec-ee-base-geo-pg9
parallel: 2
rspec-ee integration pg9 geo:
extends: .rspec-ee-base-geo-pg9
rspec-ee system pg9 geo:
extends: .rspec-ee-base-geo-pg9
db:rollback geo:
extends:
- db:rollback
- .rails:rules:ee-only
script:
- bundle exec rake geo:db:migrate VERSION=20170627195211
- bundle exec rake geo:db:migrate
# EE: default refs (MRs, master, schedules) jobs #
##################################################
####################################################################
# EE/FOSS: master non-scheduled and master 2-hourly scheduled jobs #
.rspec-base-pg11:
extends:
- .rspec-base
- .rails:rules:master-push--master-schedule-2-hourly--code-backstage
- .use-pg11
needs: ["setup-test-env pg11", "retrieve-tests-metadata", "compile-assets pull-cache"]
rspec migration pg11:
extends:
- .rspec-base-pg11
- .rspec-base-migration
parallel: 5
rspec unit pg11:
extends: .rspec-base-pg11
parallel: 20
rspec integration pg11:
extends: .rspec-base-pg11
parallel: 8
rspec system pg11:
extends: .rspec-base-pg11
parallel: 24
# EE/FOSS: master non-scheduled and master 2-hourly scheduled jobs #
####################################################################
###############################################################
# EE: master non-scheduled and master 2-hourly scheduled jobs #
.rspec-ee-base-pg11:
extends:
- .rspec-base-ee
- .use-pg11-ee
needs: ["setup-test-env pg11", "retrieve-tests-metadata", "compile-assets pull-cache"]
rspec-ee migration pg11:
extends:
- .rspec-ee-base-pg11
- .rspec-base-migration
- .rails:rules:master-push--master-schedule-2-hourly--code-backstage
parallel: 2
rspec-ee unit pg11:
extends:
- .rspec-ee-base-pg11
- .rails:rules:master-push--master-schedule-2-hourly--code-backstage
parallel: 10
rspec-ee integration pg11:
extends:
- .rspec-ee-base-pg11
- .rails:rules:master-push--master-schedule-2-hourly--code-backstage
parallel: 4
rspec-ee system pg11:
extends:
- .rspec-ee-base-pg11
- .rails:rules:master-push--master-schedule-2-hourly--code-backstage
parallel: 6
# EE: master non-scheduled and master 2-hourly scheduled jobs #
###############################################################
##########################################
# EE/FOSS: master nightly scheduled jobs #
.rspec-base-pg10:
extends:
- .rspec-base
- .rails:rules:master-refs-code-backstage
- .rails:rules:master-schedule-nightly--code-backstage
- .use-pg10
needs: ["setup-test-env pg10", "retrieve-tests-metadata", "compile-assets pull-cache"]
@ -260,177 +411,26 @@ rspec integration pg10:
rspec system pg10:
extends: .rspec-base-pg10
parallel: 24
# master-only jobs #
####################
# EE/FOSS: master nightly scheduled jobs #
##########################################
######################
# nightly-only jobs #
.rspec-base-pg9:
##############################
# EE: nightly scheduled jobs #
.rspec-ee-base-geo-pg10:
extends:
- .rspec-base
- .rails:rules:nightly-master-refs-code-backstage
- .use-pg9
needs: ["setup-test-env pg9", "retrieve-tests-metadata", "compile-assets pull-cache"]
rspec migration pg9:
extends:
- .rspec-base-pg9
- .rspec-base-migration
parallel: 5
rspec unit pg9:
extends: .rspec-base-pg9
parallel: 20
rspec integration pg9:
extends: .rspec-base-pg9
parallel: 8
rspec system pg9:
extends: .rspec-base-pg9
parallel: 24
# nightly-only jobs #
#####################
#######################
# EE master-only jobs #
.rspec-ee-base-pg10:
extends:
- .rspec-base-ee
- .rspec-ee-base-geo
- .use-pg10-ee
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
needs: ["setup-test-env pg10", "retrieve-tests-metadata", "compile-assets pull-cache"]
rspec-ee migration pg10:
extends:
- .rspec-ee-base-pg10
- .rspec-base-migration
- .rails:rules:master-refs-code-backstage
rspec-ee unit pg10 geo:
extends: .rspec-ee-base-geo-pg10
parallel: 2
rspec-ee unit pg10:
extends:
- .rspec-ee-base-pg10
- .rails:rules:master-refs-code-backstage
parallel: 10
rspec-ee integration pg10 geo:
extends: .rspec-ee-base-geo-pg10
rspec-ee integration pg10:
extends:
- .rspec-ee-base-pg10
- .rails:rules:master-refs-code-backstage
parallel: 4
rspec-ee system pg10:
extends:
- .rspec-ee-base-pg10
- .rails:rules:master-refs-code-backstage
parallel: 6
# EE master-only jobs #
#######################
################
# EE-only jobs #
.rspec-base-ee:
extends:
- .rspec-base
- .rails:rules:ee-only
.rspec-base-pg11-as-if-foss:
extends:
- .rspec-base-ee
- .as-if-foss
- .use-pg11
needs: ["setup-test-env pg11", "retrieve-tests-metadata", "compile-assets pull-cache as-if-foss"]
.rspec-ee-base-pg11:
extends:
- .rspec-base-ee
- .use-pg11-ee
rspec migration pg11-as-if-foss:
extends:
- .rspec-base-pg11-as-if-foss
- .rspec-base-migration
parallel: 5
rspec unit pg11-as-if-foss:
extends: .rspec-base-pg11-as-if-foss
parallel: 20
rspec integration pg11-as-if-foss:
extends: .rspec-base-pg11-as-if-foss
parallel: 8
rspec system pg11-as-if-foss:
extends: .rspec-base-pg11-as-if-foss
parallel: 24
rspec-ee migration pg11:
extends:
- .rspec-ee-base-pg11
- .rspec-base-migration
parallel: 2
rspec-ee unit pg11:
extends: .rspec-ee-base-pg11
parallel: 10
rspec-ee integration pg11:
extends: .rspec-ee-base-pg11
parallel: 4
rspec-ee system pg11:
extends: .rspec-ee-base-pg11
parallel: 6
.rspec-ee-base-geo:
extends: .rspec-base-ee
script:
- source scripts/rspec_helpers.sh
- scripts/prepare_postgres_fdw.sh
- rspec_paralellized_job "--tag ~quarantine --tag geo"
.rspec-ee-base-geo-pg11:
extends:
- .rspec-ee-base-geo
- .use-pg11-ee
rspec-ee unit pg11 geo:
extends: .rspec-ee-base-geo-pg11
parallel: 2
rspec-ee integration pg11 geo:
extends: .rspec-ee-base-geo-pg11
rspec-ee system pg11 geo:
extends: .rspec-ee-base-geo-pg11
db:rollback geo:
extends:
- db:rollback
- .rails:rules:ee-only
script:
- bundle exec rake geo:db:migrate VERSION=20170627195211
- bundle exec rake geo:db:migrate
# EE-only jobs #
################
########################
# EE nightly-only jobs #
.rspec-ee-base-geo-pg9:
extends:
- .rspec-ee-base-geo
- .use-pg9-ee
- .rails:rules:nightly-master-refs-code-backstage-ee-only
needs: ["setup-test-env pg9", "retrieve-tests-metadata", "compile-assets pull-cache"]
rspec-ee unit pg9 geo:
extends: .rspec-ee-base-geo-pg9
parallel: 2
rspec-ee integration pg9 geo:
extends: .rspec-ee-base-geo-pg9
rspec-ee system pg9 geo:
extends: .rspec-ee-base-geo-pg9
# EE nightly-only jobs #
########################
rspec-ee system pg10 geo:
extends: .rspec-ee-base-geo-pg10
# EE: nightly scheduled jobs #
##############################

View File

@ -16,6 +16,15 @@
.if-master-refs: &if-master-refs
if: '$CI_COMMIT_REF_NAME == "master"'
.if-master-push: &if-master-push
if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"'
.if-master-schedule-2-hourly: &if-master-schedule-2-hourly
if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "schedule" && $FREQUENCY == "2-hourly"'
.if-master-schedule-nightly: &if-master-schedule-nightly
if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "schedule" && $FREQUENCY == "nightly"'
.if-auto-deploy-branches: &if-auto-deploy-branches
if: '$CI_COMMIT_BRANCH =~ /^\d+-\d+-auto-deploy-\d+$/'
@ -25,9 +34,6 @@
.if-merge-request: &if-merge-request
if: '$CI_MERGE_REQUEST_IID'
.if-nightly-master-schedule: &if-nightly-master-schedule
if: '$NIGHTLY && $CI_COMMIT_REF_NAME == "master" && $CI_PIPELINE_SOURCE == "schedule"'
.if-dot-com-gitlab-org-schedule: &if-dot-com-gitlab-org-schedule
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org" && $CI_PIPELINE_SOURCE == "schedule"'
@ -360,36 +366,33 @@
rules:
- <<: *if-default-refs
changes: *code-backstage-patterns
when: on_success
.rails:rules:default-refs-code-backstage-qa:
rules:
- <<: *if-default-refs
changes: *code-backstage-qa-patterns
when: on_success
.rails:rules:master-refs-code-backstage:
.rails:rules:master-push--master-schedule-2-hourly--code-backstage:
rules:
- <<: *if-master-refs
- <<: *if-master-push
changes: *code-backstage-patterns
when: on_success
- changes: [".gitlab/ci/rails.gitlab-ci.yml"]
- <<: *if-master-schedule-2-hourly
- <<: *if-merge-request
changes: [".gitlab/ci/rails.gitlab-ci.yml"]
.rails:rules:nightly-master-refs-code-backstage:
.rails:rules:master-schedule-nightly--code-backstage:
rules:
- <<: *if-nightly-master-schedule
changes: *code-backstage-patterns
when: on_success
- changes: [".gitlab/ci/rails.gitlab-ci.yml"]
- <<: *if-master-schedule-nightly
- <<: *if-merge-request
changes: [".gitlab/ci/rails.gitlab-ci.yml"]
.rails:rules:nightly-master-refs-code-backstage-ee-only:
.rails:rules:master-schedule-nightly--code-backstage-ee-only:
rules:
- <<: *if-not-ee
when: never
- <<: *if-nightly-master-schedule
changes: *code-backstage-patterns
when: on_success
- changes: [".gitlab/ci/rails.gitlab-ci.yml"]
- <<: *if-master-schedule-nightly
- <<: *if-merge-request
changes: [".gitlab/ci/rails.gitlab-ci.yml"]
.rails:rules:ee-only:
rules:
@ -397,7 +400,6 @@
when: never
- <<: *if-default-refs
changes: *code-backstage-patterns
when: on_success
.rails:rules:ee-mr-and-master-only:
rules:
@ -412,7 +414,6 @@
rules:
- <<: *if-merge-request
changes: *code-backstage-patterns
when: on_success
##################
# Releases rules #

View File

@ -7,7 +7,7 @@ cache gems:
- .default-before_script
- .setup:rules:cache-gems
stage: test
needs: ["setup-test-env pg11"]
needs: ["setup-test-env pg9"]
variables:
SETUP_DB: "false"
script:

View File

@ -32,18 +32,18 @@ update-tests-metadata:
- .test-metadata:rules:update-tests-metadata
stage: post-test
dependencies:
- setup-test-env pg11
- rspec migration pg11
- rspec unit pg11
- rspec integration pg11
- rspec system pg11
- rspec-ee migration pg11
- rspec-ee unit pg11
- rspec-ee integration pg11
- rspec-ee system pg11
- rspec-ee unit pg11 geo
- rspec-ee integration pg11 geo
- rspec-ee system pg11 geo
- setup-test-env pg9
- rspec migration pg9
- rspec unit pg9
- rspec integration pg9
- rspec system pg9
- rspec-ee migration pg9
- rspec-ee unit pg9
- rspec-ee integration pg9
- rspec-ee system pg9
- rspec-ee unit pg9 geo
- rspec-ee integration pg9 geo
- rspec-ee system pg9 geo
cache:
policy: push
script:

View File

@ -47,7 +47,8 @@ export default class PasteMarkdownTable {
const htmlData = this.data.getData('text/html');
this.doc = new DOMParser().parseFromString(htmlData, 'text/html');
const tables = this.doc.querySelectorAll('table');
// Avoid formatting lines that were copied from a diff
const tables = this.doc.querySelectorAll('table:not(.diff-wrap-lines)');
// We're only looking for exactly one table. If there happens to be
// multiple tables, it's possible an application copied data into

View File

@ -27,12 +27,13 @@ class Projects::EnvironmentsController < Projects::ApplicationController
format.html
format.json do
Gitlab::PollingInterval.set_header(response, interval: 3_000)
environments_count_by_state = project.environments.count_by_state
render json: {
environments: serialize_environments(request, response, params[:nested]),
review_app: serialize_review_app,
available_count: project.environments.available.count,
stopped_count: project.environments.stopped.count
available_count: environments_count_by_state[:available],
stopped_count: environments_count_by_state[:stopped]
}
end
end

View File

@ -152,6 +152,14 @@ class Environment < ApplicationRecord
.preload(:user, :metadata, :deployment)
end
def count_by_state
environments_count_by_state = group(:state).count
valid_states.each_with_object({}) do |state, count_hash|
count_hash[state] = environments_count_by_state[state.to_s] || 0
end
end
private
def cte_for_deployments_with_stop_action

View File

@ -10,7 +10,7 @@
= _('Allow repository mirroring to be configured by project maintainers')
%span.form-text.text-muted
= _('If disabled, only admins will be able to configure repository mirroring.')
= link_to icon('question-circle'), help_page_path('workflow/repository_mirroring')
= link_to icon('question-circle'), help_page_path('user/project/repository/repository_mirroring.md')
= render_if_exists 'admin/application_settings/mirror_settings', form: f

View File

@ -1,4 +1,5 @@
- can_create_subgroups = can?(current_user, :create_subgroup, @group)
- can_create_projects = can?(current_user, :create_projects, @group)
- emails_disabled = @group.emails_disabled?
.group-home-panel
@ -23,32 +24,33 @@
- if current_user
.group-buttons
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn', emails_disabled: emails_disabled
- if can? current_user, :create_projects, @group
- new_project_label = _("New project")
- new_subgroup_label = _("New subgroup")
- if can_create_subgroups
.btn-group.new-project-subgroup.droplab-dropdown.home-panel-action-button.prepend-top-default.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
%input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } }
%button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
= sprite_icon("chevron-down", css_class: "icon dropdown-btn-icon")
%ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } }
%li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } }
- new_project_label = _("New project")
- new_subgroup_label = _("New subgroup")
- if can_create_projects and can_create_subgroups
.btn-group.new-project-subgroup.droplab-dropdown.home-panel-action-button.prepend-top-default.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
%input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } }
%button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
= sprite_icon("chevron-down", css_class: "icon dropdown-btn-icon")
%ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } }
%li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
.description
%strong= new_project_label
%span= s_("GroupsTree|Create a project in this group.")
%li.divider.droplap-item-ignore
%li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
.description
%strong= new_project_label
%span= s_("GroupsTree|Create a project in this group.")
%li.divider.droplap-item-ignore
%li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
.description
%strong= new_subgroup_label
%span= s_("GroupsTree|Create a subgroup in this group.")
- else
= link_to new_project_label, new_project_path(namespace_id: @group.id), class: "btn btn-success prepend-top-default"
%strong= new_subgroup_label
%span= s_("GroupsTree|Create a subgroup in this group.")
- elsif can_create_projects
= link_to new_project_label, new_project_path(namespace_id: @group.id), class: "btn btn-success prepend-top-default"
- elsif can_create_subgroups
= link_to new_subgroup_label, new_group_path(parent_id: @group.id), class: "btn btn-success prepend-top-default"
- if @group.description.present?
.group-home-desc.mt-1

View File

@ -10,7 +10,7 @@
= expanded ? _('Collapse') : _('Expand')
%p
= _('Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically.')
= link_to _('Read more'), help_page_path('workflow/repository_mirroring'), target: '_blank'
= link_to _('Read more'), help_page_path('user/project/repository/repository_mirroring.md'), target: '_blank'
.settings-content
- if mirror_settings_enabled

View File

@ -0,0 +1,5 @@
---
title: Always display new subgroup button when permission is granted
merge_request: 28309
author: Mattias Michaux
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Fix mirror repos docs link
merge_request: 30443
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Move prepend to last line in lib/gitlab files
merge_request: 30070
author: Rajendra Kadam
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Move prepend to last line in lib/gitlab files
merge_request: 29938
author: Rajendra
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Avoid copying diffs as Markdown tables
merge_request: 30572
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Refactor count queries to single query on Projects::EnvironmentsController
merge_request: 30073
author: Sashi Kumar
type: other

View File

@ -25,14 +25,21 @@ Server-side Git hooks are typically placed in the repository's `hooks`
subdirectory. In GitLab, hook directories are symlinked to the GitLab Shell
`hooks` directory for ease of maintenance between GitLab Shell upgrades.
Server hooks are implemented differently, but the behavior is exactly the same
once the hook is created. Follow the steps below to set up a server hook for a
once the hook is created.
NOTE: **Note:**
If you are not using [hashed storage](repository_storage_types.md#hashed-storage), the project's
repository directory might not exactly match the instructions below. In that case,
for an installation from source the path is usually `/home/git/repositories/<group>/<project>.git`.
For Omnibus installs the path is usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`.
Follow the steps below to set up a server hook for a
repository:
1. Pick a project that needs a server hook.
1. On the GitLab server, navigate to the project's repository directory.
For an installation from source the path is usually
`/home/git/repositories/<group>/<project>.git`. For Omnibus installs the path is
usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`.
1. Find that project's path on the GitLab server, by navigating to the
**Admin area > Projects**. From there, select the project for which you
would like to add a hook. You can find the path to the project's repository
under **Gitaly relative path** on that page.
1. Create a new directory in this location called `custom_hooks`.
1. Inside the new `custom_hooks` directory, create a file with a name matching
the hook type. For a pre-receive hook the file name should be `pre-receive`
@ -43,8 +50,7 @@ repository:
type. For example, if the script is in Ruby the shebang will probably be
`#!/usr/bin/env ruby`.
That's it! Assuming the hook code is properly implemented the hook will fire
as appropriate.
Assuming the hook code is properly implemented the hook will run as appropriate.
## Set a global server hook for all repositories

View File

@ -151,15 +151,26 @@ request, be sure to start the `dont-interrupt-me` job before pushing.
## PostgreSQL versions testing
### Current versions testing
| Where? | PG version |
| ------ | ------ |
| MRs | 9.6 |
| `master` (non-scheduled pipelines) | 9.6 / 11 |
| 2-hourly scheduled pipelines | 9.6 / 11 |
| Nightly scheduled pipeline | 9.6 / 10 |
### Long-term plan
We follow the [PostgreSQL versions shipped with Omnibus GitLab](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html):
| | 12.10 (April 2020) | 13.0 (May 2020) | 13.1 (June 2020) | 13.2 (July 2020) | 13.3 (August 2020) | 13.4, 13.5 | 13.6 (November 2020) | 14.0 (May 2021?) |
| PG version | 12.10 (April 2020) | 13.0 (May 2020) | 13.1 (June 2020) | 13.2 (July 2020) | 13.3 (August 2020) | 13.4, 13.5 | 13.6 (November 2020) | 14.0 (May 2021?) |
| ------ | ------------------ | --------------- | ---------------- | ---------------- | ------------------ | ------------ | -------------------- | ---------------- |
| PG9.6 | nightly | - | - | - | - | - | - | - |
| PG10 | `master` | - | - | - | - | - | - | - |
| PG11 | MRs/`master` | MRs/`master` | MRs/`master` | MRs/`master` | MRs/`master` | MRs/`master` | nightly | - |
| PG12 | - | - | - | - | `master` | `master` | MRs/`master` | `master` |
| PG13 | - | - | - | - | - | - | - | MRs/`master` |
| PG9.6 | MRs/`master`/`2-hour`/`nightly` | - | - | - | - | - | - | - |
| PG10 | `nightly` | - | - | - | - | - | - | - |
| PG11 | `master`/`2-hour` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | `nightly` | - |
| PG12 | - | - | - | - | `master`/`2-hour` | `master`/`2-hour` | MRs/`master`/`2-hour`/`nightly` | `master`/`2-hour` |
| PG13 | - | - | - | - | - | - | - | MRs/`master`/`2-hour`/`nightly` |
## Pipeline types

View File

@ -224,8 +224,8 @@ pip install --index-url https://__token__:<personal_access_token>@gitlab.com/api
Where:
- `<package_name>` is the package name.
- `<personal_access_token>` is your personal access token.
- `<project_id>` is your project id number.
- `<personal_access_token>` is a personal access token with the `read_api` scope.
- `<project_id>` is the project id number.
If you were following the guide above and want to test installing the
`MyPyPiPackage` package, you can run the following:

View File

@ -29,8 +29,6 @@ module Gitlab
private_constant :REASONS
prepend_if_ee('::EE::Gitlab::Ci::Status::Build::Failed') # rubocop: disable Cop/InjectEnterpriseEditionModule
def status_tooltip
base_message
end
@ -65,3 +63,5 @@ module Gitlab
end
end
end
Gitlab::Ci::Status::Build::Failed.prepend_if_ee('::EE::Gitlab::Ci::Status::Build::Failed')

View File

@ -3,8 +3,6 @@
module Gitlab
module Email
module Handler
prepend_if_ee('::EE::Gitlab::Email::Handler') # rubocop: disable Cop/InjectEnterpriseEditionModule
def self.handlers
@handlers ||= load_handlers
end
@ -27,3 +25,5 @@ module Gitlab
end
end
end
Gitlab::Email::Handler.prepend_if_ee('::EE::Gitlab::Email::Handler')

View File

@ -5,8 +5,6 @@ module Gitlab
# The ParallelImporter schedules the importing of a GitHub project using
# Sidekiq.
class ParallelImporter
prepend_if_ee('::EE::Gitlab::GithubImport::ParallelImporter') # rubocop: disable Cop/InjectEnterpriseEditionModule
attr_reader :project
def self.async?
@ -41,3 +39,5 @@ module Gitlab
end
end
end
Gitlab::GithubImport::ParallelImporter.prepend_if_ee('::EE::Gitlab::GithubImport::ParallelImporter')

View File

@ -4,8 +4,6 @@ module Gitlab
module ImportExport
module Project
class RelationFactory < Base::RelationFactory
prepend_if_ee('::EE::Gitlab::ImportExport::Project::RelationFactory') # rubocop: disable Cop/InjectEnterpriseEditionModule
OVERRIDES = { snippets: :project_snippets,
ci_pipelines: 'Ci::Pipeline',
pipelines: 'Ci::Pipeline',
@ -161,3 +159,5 @@ module Gitlab
end
end
end
Gitlab::ImportExport::Project::RelationFactory.prepend_if_ee('::EE::Gitlab::ImportExport::Project::RelationFactory')

View File

@ -4,8 +4,6 @@ module Gitlab
module Middleware
class ReadOnly
class Controller
prepend_if_ee('EE::Gitlab::Middleware::ReadOnly::Controller') # rubocop: disable Cop/InjectEnterpriseEditionModule
DISALLOWED_METHODS = %w(POST PATCH PUT DELETE).freeze
APPLICATION_JSON = 'application/json'
APPLICATION_JSON_TYPES = %W{#{APPLICATION_JSON} application/vnd.git-lfs+json}.freeze
@ -144,3 +142,5 @@ module Gitlab
end
end
end
Gitlab::Middleware::ReadOnly::Controller.prepend_if_ee('EE::Gitlab::Middleware::ReadOnly::Controller')

View File

@ -2,8 +2,6 @@
module Gitlab
class OmniauthInitializer
prepend_if_ee('::EE::Gitlab::OmniauthInitializer') # rubocop: disable Cop/InjectEnterpriseEditionModule
def initialize(devise_config)
@devise_config = devise_config
end
@ -121,3 +119,5 @@ module Gitlab
end
end
end
Gitlab::OmniauthInitializer.prepend_if_ee('::EE::Gitlab::OmniauthInitializer')

View File

@ -5,8 +5,6 @@
module Gitlab
module Patch
module DrawRoute
prepend_if_ee('EE::Gitlab::Patch::DrawRoute') # rubocop: disable Cop/InjectEnterpriseEditionModule
RoutesNotFound = Class.new(StandardError)
def draw(routes_name)
@ -38,3 +36,5 @@ module Gitlab
end
end
end
Gitlab::Patch::DrawRoute.prepend_if_ee('EE::Gitlab::Patch::DrawRoute')

View File

@ -3,7 +3,6 @@
module Gitlab
module Prometheus
class MetricGroup
prepend_if_ee('EE::Gitlab::Prometheus::MetricGroup') # rubocop: disable Cop/InjectEnterpriseEditionModule
include ActiveModel::Model
attr_accessor :name, :priority, :metrics
@ -31,3 +30,5 @@ module Gitlab
end
end
end
Gitlab::Prometheus::MetricGroup.prepend_if_ee('EE::Gitlab::Prometheus::MetricGroup')

View File

@ -4,8 +4,6 @@ module Gitlab
module Prometheus
module Queries
module QueryAdditionalMetrics
prepend_if_ee('EE::Gitlab::Prometheus::Queries::QueryAdditionalMetrics') # rubocop: disable Cop/InjectEnterpriseEditionModule
def query_metrics(project, environment, query_context)
matched_metrics(project).map(&query_group(query_context))
.select(&method(:group_with_any_metrics))
@ -99,3 +97,5 @@ module Gitlab
end
end
end
Gitlab::Prometheus::Queries::QueryAdditionalMetrics.prepend_if_ee('EE::Gitlab::Prometheus::Queries::QueryAdditionalMetrics')

View File

@ -3,8 +3,6 @@
module Gitlab
module Search
class ParsedQuery
prepend_if_ee('EE::Gitlab::Search::ParsedQuery') # rubocop: disable Cop/InjectEnterpriseEditionModule
attr_reader :term, :filters
def initialize(term, filters)
@ -25,3 +23,5 @@ module Gitlab
end
end
end
Gitlab::Search::ParsedQuery.prepend_if_ee('EE::Gitlab::Search::ParsedQuery')

View File

@ -4,8 +4,6 @@ module Gitlab
module SlashCommands
module Presenters
module IssueBase
prepend_if_ee('EE::Gitlab::SlashCommands::Presenters::IssueBase') # rubocop: disable Cop/InjectEnterpriseEditionModule
def color(issuable)
issuable.open? ? '#38ae67' : '#d22852'
end
@ -51,3 +49,5 @@ module Gitlab
end
end
end
Gitlab::SlashCommands::Presenters::IssueBase.prepend_if_ee('EE::Gitlab::SlashCommands::Presenters::IssueBase')

View File

@ -2,8 +2,6 @@
module Gitlab
class TreeSummary
prepend_if_ee('::EE::Gitlab::TreeSummary') # rubocop: disable Cop/InjectEnterpriseEditionModule
include ::Gitlab::Utils::StrongMemoize
CACHE_EXPIRE_IN = 1.hour
@ -135,3 +133,5 @@ module Gitlab
end
end
end
Gitlab::TreeSummary.prepend_if_ee('::EE::Gitlab::TreeSummary')

View File

@ -262,6 +262,42 @@ describe 'Group' do
end
end
describe 'new subgroup / project button' do
let(:group) { create(:group, project_creation_level: Gitlab::Access::NO_ONE_PROJECT_ACCESS, subgroup_creation_level: Gitlab::Access::OWNER_SUBGROUP_ACCESS) }
it 'new subgroup button is displayed without project creation permission' do
visit group_path(group)
page.within '.group-buttons' do
expect(page).to have_link('New subgroup')
end
end
it 'new subgroup button is displayed together with new project button when having project creation permission' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
visit group_path(group)
page.within '.group-buttons' do
expect(page).to have_css("li[data-text='New subgroup']", visible: false)
expect(page).to have_css("li[data-text='New project']", visible: false)
end
end
it 'new project button is displayed without subgroup creation permission' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
user = create(:user)
group.add_maintainer(user)
sign_out(:user)
sign_in(user)
visit group_path(group)
page.within '.group-buttons' do
expect(page).to have_link('New project')
end
end
end
def remove_with_confirm(button_text, confirm_with)
click_button button_text
fill_in 'confirm_name_input', with: confirm_with

View File

@ -57,6 +57,18 @@ describe('PasteMarkdownTable', () => {
expect(new PasteMarkdownTable(data).isTable()).toBe(false);
});
it('returns false when the table copy comes from a diff', () => {
data.types = ['text/html', 'text/plain'];
data.getData = jest.fn().mockImplementation(mimeType => {
if (mimeType === 'text/html') {
return '<table class="diff-wrap-lines"><tr><td>First</td><td>Second</td></tr></table>';
}
return 'First\tSecond';
});
expect(new PasteMarkdownTable(data).isTable()).toBe(false);
});
});
describe('convertToTableMarkdown', () => {

View File

@ -11,6 +11,7 @@ import Dashboard from '~/monitoring/components/dashboard.vue';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue';
import EmptyState from '~/monitoring/components/empty_state.vue';
import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
import { createStore } from '~/monitoring/stores';
@ -33,9 +34,6 @@ describe('Dashboard', () => {
const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(Dashboard, {
propsData: { ...propsData, ...props },
methods: {
fetchData: jest.fn(),
},
store,
...options,
});
@ -44,9 +42,6 @@ describe('Dashboard', () => {
const createMountedWrapper = (props = {}, options = {}) => {
wrapper = mount(Dashboard, {
propsData: { ...propsData, ...props },
methods: {
fetchData: jest.fn(),
},
store,
stubs: ['graph-group', 'dashboard-panel'],
...options,
@ -56,14 +51,14 @@ describe('Dashboard', () => {
beforeEach(() => {
store = createStore();
mock = new MockAdapter(axios);
jest.spyOn(store, 'dispatch').mockResolvedValue();
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
wrapper = null;
}
mock.restore();
if (store.dispatch.mockReset) {
store.dispatch.mockReset();
}
});
describe('no metrics are available yet', () => {
@ -104,9 +99,7 @@ describe('Dashboard', () => {
describe('request information to the server', () => {
it('calls to set time range and fetch data', () => {
jest.spyOn(store, 'dispatch');
createShallowWrapper({ hasMetrics: true }, { methods: {} });
createShallowWrapper({ hasMetrics: true });
return wrapper.vm.$nextTick().then(() => {
expect(store.dispatch).toHaveBeenCalledWith(
@ -119,10 +112,13 @@ describe('Dashboard', () => {
});
it('shows up a loading state', () => {
createShallowWrapper({ hasMetrics: true }, { methods: {} });
store.state.monitoringDashboard.emptyState = 'loading';
createShallowWrapper({ hasMetrics: true });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.emptyState).toEqual('loading');
expect(wrapper.find(EmptyState).exists()).toBe(true);
expect(wrapper.find(EmptyState).props('selectedState')).toBe('loading');
});
});
@ -254,6 +250,10 @@ describe('Dashboard', () => {
return wrapper.vm.$nextTick();
});
afterEach(() => {
wrapper.destroy();
});
it('renders a search input', () => {
expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownSearch' }).exists()).toBe(true);
});
@ -322,8 +322,10 @@ describe('Dashboard', () => {
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
beforeEach(() => {
createShallowWrapper({ hasMetrics: true });
// call original dispatch
store.dispatch.mockRestore();
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick();

View File

@ -18,21 +18,11 @@ describe('Dashboard template', () => {
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
wrapper = null;
}
mock.restore();
});
it('matches the default snapshot', () => {
wrapper = shallowMount(Dashboard, {
propsData: { ...propsData },
methods: {
fetchData: jest.fn(),
},
store,
});
wrapper = shallowMount(Dashboard, { propsData: { ...propsData }, store });
expect(wrapper.element).toMatchSnapshot();
});

View File

@ -1311,4 +1311,25 @@ describe Environment, :use_clean_rails_memory_store_caching do
expect { environment.destroy }.to change { project.commit(deployment.ref_path) }.to(nil)
end
end
describe '.count_by_state' do
context 'when environments are not empty' do
let!(:environment1) { create(:environment, project: project, state: 'stopped') }
let!(:environment2) { create(:environment, project: project, state: 'available') }
let!(:environment3) { create(:environment, project: project, state: 'stopped') }
it 'returns the environments count grouped by state' do
expect(project.environments.count_by_state).to eq({ stopped: 2, available: 1 })
end
it 'returns the environments count grouped by state with zero value' do
environment2.update(state: 'stopped')
expect(project.environments.count_by_state).to eq({ stopped: 3, available: 0 })
end
end
it 'returns zero state counts when environments are empty' do
expect(project.environments.count_by_state).to eq({ stopped: 0, available: 0 })
end
end
end