diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 898325a0dbc..12cc037f85a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 diff --git a/.gitlab/ci/dev-fixtures.gitlab-ci.yml b/.gitlab/ci/dev-fixtures.gitlab-ci.yml index 27ceb6f37db..a642a80eb85 100644 --- a/.gitlab/ci/dev-fixtures.gitlab-ci.yml +++ b/.gitlab/ci/dev-fixtures.gitlab-ci.yml @@ -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 diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml index b8a66decbb7..0b4e124331f 100644 --- a/.gitlab/ci/docs.gitlab-ci.yml +++ b/.gitlab/ci/docs.gitlab-ci.yml @@ -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 diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index 737f4405fd7..597e9966625 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -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 diff --git a/.gitlab/ci/memory.gitlab-ci.yml b/.gitlab/ci/memory.gitlab-ci.yml index af75ff257ea..92468925dd7 100644 --- a/.gitlab/ci/memory.gitlab-ci.yml +++ b/.gitlab/ci/memory.gitlab-ci.yml @@ -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" diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 85a9ddd8f2e..17c9d03eb98 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -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 # +############################## diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 1a54a88c3f5..e0ec20cfd9d 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -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 # diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml index e79f3939bc7..2d827046538 100644 --- a/.gitlab/ci/setup.gitlab-ci.yml +++ b/.gitlab/ci/setup.gitlab-ci.yml @@ -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: diff --git a/.gitlab/ci/test-metadata.gitlab-ci.yml b/.gitlab/ci/test-metadata.gitlab-ci.yml index db176b00e08..198c0ff1e46 100644 --- a/.gitlab/ci/test-metadata.gitlab-ci.yml +++ b/.gitlab/ci/test-metadata.gitlab-ci.yml @@ -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: diff --git a/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js b/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js index 665a7216424..278dd857ab8 100644 --- a/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js +++ b/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js @@ -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 diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 30ace6100d7..1fa362eff03 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -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 diff --git a/app/models/environment.rb b/app/models/environment.rb index 248e2716b61..21044771bbb 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -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 diff --git a/app/views/admin/application_settings/_repository_mirrors_form.html.haml b/app/views/admin/application_settings/_repository_mirrors_form.html.haml index 6e5fa6eb62c..8ec9b3c528a 100644 --- a/app/views/admin/application_settings/_repository_mirrors_form.html.haml +++ b/app/views/admin/application_settings/_repository_mirrors_form.html.haml @@ -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 diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml index 6772ee94d46..d083288edc8 100644 --- a/app/views/groups/_home_panel.html.haml +++ b/app/views/groups/_home_panel.html.haml @@ -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 diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index 4004c4f4b07..38e4fbf73e0 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -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 diff --git a/changelogs/unreleased/205513-create-subgroup-without-project-permission.yml b/changelogs/unreleased/205513-create-subgroup-without-project-permission.yml new file mode 100644 index 00000000000..6b4cdc1cc4d --- /dev/null +++ b/changelogs/unreleased/205513-create-subgroup-without-project-permission.yml @@ -0,0 +1,5 @@ +--- +title: Always display new subgroup button when permission is granted +merge_request: 28309 +author: Mattias Michaux +type: fixed diff --git a/changelogs/unreleased/aalakkad-fix-mirro-repo-docs-link.yml b/changelogs/unreleased/aalakkad-fix-mirro-repo-docs-link.yml new file mode 100644 index 00000000000..3f5d1c59752 --- /dev/null +++ b/changelogs/unreleased/aalakkad-fix-mirro-repo-docs-link.yml @@ -0,0 +1,5 @@ +--- +title: Fix mirror repos docs link +merge_request: 30443 +author: +type: fixed diff --git a/changelogs/unreleased/lib-gitlab-refactoring-2.yml b/changelogs/unreleased/lib-gitlab-refactoring-2.yml new file mode 100644 index 00000000000..7b6e2fefee8 --- /dev/null +++ b/changelogs/unreleased/lib-gitlab-refactoring-2.yml @@ -0,0 +1,5 @@ +--- +title: Move prepend to last line in lib/gitlab files +merge_request: 30070 +author: Rajendra Kadam +type: fixed diff --git a/changelogs/unreleased/lib-gitlab-refactoring.yml b/changelogs/unreleased/lib-gitlab-refactoring.yml new file mode 100644 index 00000000000..4caa45b6fc9 --- /dev/null +++ b/changelogs/unreleased/lib-gitlab-refactoring.yml @@ -0,0 +1,5 @@ +--- +title: Move prepend to last line in lib/gitlab files +merge_request: 29938 +author: Rajendra +type: fixed diff --git a/changelogs/unreleased/sh-fix-paste-markdown-from-diff.yml b/changelogs/unreleased/sh-fix-paste-markdown-from-diff.yml new file mode 100644 index 00000000000..d9bea5c89e5 --- /dev/null +++ b/changelogs/unreleased/sh-fix-paste-markdown-from-diff.yml @@ -0,0 +1,5 @@ +--- +title: Avoid copying diffs as Markdown tables +merge_request: 30572 +author: +type: fixed diff --git a/changelogs/unreleased/sk-refactor-count-queries-in-environments-controller.yml b/changelogs/unreleased/sk-refactor-count-queries-in-environments-controller.yml new file mode 100644 index 00000000000..7be17cb220a --- /dev/null +++ b/changelogs/unreleased/sk-refactor-count-queries-in-environments-controller.yml @@ -0,0 +1,5 @@ +--- +title: Refactor count queries to single query on Projects::EnvironmentsController +merge_request: 30073 +author: Sashi Kumar +type: other diff --git a/doc/administration/server_hooks.md b/doc/administration/server_hooks.md index 93c7df335ca..0b8c66805ae 100644 --- a/doc/administration/server_hooks.md +++ b/doc/administration/server_hooks.md @@ -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//.git`. +For Omnibus installs the path is usually `/var/opt/gitlab/git-data/repositories//.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//.git`. For Omnibus installs the path is - usually `/var/opt/gitlab/git-data/repositories//.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 diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md index dbf4f8623b8..b98d6200cad 100644 --- a/doc/development/pipelines.md +++ b/doc/development/pipelines.md @@ -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 diff --git a/doc/user/packages/pypi_repository/index.md b/doc/user/packages/pypi_repository/index.md index c763793316b..2904ce06531 100644 --- a/doc/user/packages/pypi_repository/index.md +++ b/doc/user/packages/pypi_repository/index.md @@ -224,8 +224,8 @@ pip install --index-url https://__token__:@gitlab.com/api Where: - `` is the package name. -- `` is your personal access token. -- `` is your project id number. +- `` is a personal access token with the `read_api` scope. +- `` 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: diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb index b0b01538a30..76ad113aad9 100644 --- a/lib/gitlab/ci/status/build/failed.rb +++ b/lib/gitlab/ci/status/build/failed.rb @@ -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') diff --git a/lib/gitlab/email/handler.rb b/lib/gitlab/email/handler.rb index e9a7c9bcf5c..df9d4810ab3 100644 --- a/lib/gitlab/email/handler.rb +++ b/lib/gitlab/email/handler.rb @@ -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') diff --git a/lib/gitlab/github_import/parallel_importer.rb b/lib/gitlab/github_import/parallel_importer.rb index 8fb99c996b3..1b4750da868 100644 --- a/lib/gitlab/github_import/parallel_importer.rb +++ b/lib/gitlab/github_import/parallel_importer.rb @@ -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') diff --git a/lib/gitlab/import_export/project/relation_factory.rb b/lib/gitlab/import_export/project/relation_factory.rb index f7f1195f2f1..c5d99c9fced 100644 --- a/lib/gitlab/import_export/project/relation_factory.rb +++ b/lib/gitlab/import_export/project/relation_factory.rb @@ -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') diff --git a/lib/gitlab/middleware/read_only/controller.rb b/lib/gitlab/middleware/read_only/controller.rb index cdab86540f8..1c49379e8d2 100644 --- a/lib/gitlab/middleware/read_only/controller.rb +++ b/lib/gitlab/middleware/read_only/controller.rb @@ -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') diff --git a/lib/gitlab/omniauth_initializer.rb b/lib/gitlab/omniauth_initializer.rb index c051a581837..4a7a7709c79 100644 --- a/lib/gitlab/omniauth_initializer.rb +++ b/lib/gitlab/omniauth_initializer.rb @@ -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') diff --git a/lib/gitlab/patch/draw_route.rb b/lib/gitlab/patch/draw_route.rb index 4d1b57fbbbb..f5fcd5c6093 100644 --- a/lib/gitlab/patch/draw_route.rb +++ b/lib/gitlab/patch/draw_route.rb @@ -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') diff --git a/lib/gitlab/prometheus/metric_group.rb b/lib/gitlab/prometheus/metric_group.rb index 1b6f7282eb3..4a39260a340 100644 --- a/lib/gitlab/prometheus/metric_group.rb +++ b/lib/gitlab/prometheus/metric_group.rb @@ -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') diff --git a/lib/gitlab/prometheus/queries/query_additional_metrics.rb b/lib/gitlab/prometheus/queries/query_additional_metrics.rb index a5e7d0ac9d5..d24b98e790b 100644 --- a/lib/gitlab/prometheus/queries/query_additional_metrics.rb +++ b/lib/gitlab/prometheus/queries/query_additional_metrics.rb @@ -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') diff --git a/lib/gitlab/search/parsed_query.rb b/lib/gitlab/search/parsed_query.rb index f3136fff294..1f6e0519b4c 100644 --- a/lib/gitlab/search/parsed_query.rb +++ b/lib/gitlab/search/parsed_query.rb @@ -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') diff --git a/lib/gitlab/slash_commands/presenters/issue_base.rb b/lib/gitlab/slash_commands/presenters/issue_base.rb index 4bc05d1f318..017fb8a62c4 100644 --- a/lib/gitlab/slash_commands/presenters/issue_base.rb +++ b/lib/gitlab/slash_commands/presenters/issue_base.rb @@ -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') diff --git a/lib/gitlab/tree_summary.rb b/lib/gitlab/tree_summary.rb index 724341c9cee..9861ea7d322 100644 --- a/lib/gitlab/tree_summary.rb +++ b/lib/gitlab/tree_summary.rb @@ -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') diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index d2e65c02e37..c1cb0b4951e 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -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 diff --git a/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js b/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js index a98919e2113..eab805382bd 100644 --- a/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js +++ b/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js @@ -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 '
FirstSecond
'; + } + return 'First\tSecond'; + }); + + expect(new PasteMarkdownTable(data).isTable()).toBe(false); + }); }); describe('convertToTableMarkdown', () => { diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js index 0ee0a2e6e41..be3c83dfd7d 100644 --- a/spec/frontend/monitoring/components/dashboard_spec.js +++ b/spec/frontend/monitoring/components/dashboard_spec.js @@ -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(); diff --git a/spec/frontend/monitoring/components/dashboard_template_spec.js b/spec/frontend/monitoring/components/dashboard_template_spec.js index d1790df4189..0257515f18e 100644 --- a/spec/frontend/monitoring/components/dashboard_template_spec.js +++ b/spec/frontend/monitoring/components/dashboard_template_spec.js @@ -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(); }); diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index d0305d878e3..c0b2a4ae984 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -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