New upstream version 13.2.1
This commit is contained in:
parent
f7a89b7334
commit
029fca15f4
8181 changed files with 344178 additions and 71305 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,6 +17,7 @@ eslint-report.html
|
||||||
.rbx/
|
.rbx/
|
||||||
/.ruby-gemset
|
/.ruby-gemset
|
||||||
/.ruby-version
|
/.ruby-version
|
||||||
|
/.tool-versions
|
||||||
/.rvmrc
|
/.rvmrc
|
||||||
.sass-cache/
|
.sass-cache/
|
||||||
/.secret
|
/.secret
|
||||||
|
|
|
@ -20,6 +20,8 @@ default:
|
||||||
- gitlab-org
|
- gitlab-org
|
||||||
# All jobs are interruptible by default
|
# All jobs are interruptible by default
|
||||||
interruptible: true
|
interruptible: true
|
||||||
|
# Default job timeout set to 90m https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/10520
|
||||||
|
timeout: 90m
|
||||||
|
|
||||||
workflow:
|
workflow:
|
||||||
rules:
|
rules:
|
||||||
|
@ -61,6 +63,7 @@ variables:
|
||||||
DOCKER_VERSION: "19.03.0"
|
DOCKER_VERSION: "19.03.0"
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
- local: .gitlab/ci/build-images.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/cache-repo.gitlab-ci.yml
|
- local: .gitlab/ci/cache-repo.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/cng.gitlab-ci.yml
|
- local: .gitlab/ci/cng.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/docs.gitlab-ci.yml
|
- local: .gitlab/ci/docs.gitlab-ci.yml
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
/doc/development/ @marcia @mjang1
|
/doc/development/ @marcia @mjang1
|
||||||
/doc/development/documentation/ @mikelewis
|
/doc/development/documentation/ @mikelewis
|
||||||
/doc/ci @marcel.amirault @sselhorn
|
/doc/ci @marcel.amirault @sselhorn
|
||||||
|
/doc/operations @aqualls @eread
|
||||||
/doc/user/clusters @aqualls
|
/doc/user/clusters @aqualls
|
||||||
/doc/user/infrastructure @aqualls
|
/doc/user/infrastructure @aqualls
|
||||||
/doc/user/project/clusters @aqualls
|
/doc/user/project/clusters @aqualls
|
||||||
|
@ -43,17 +44,12 @@
|
||||||
# Feature specific owners
|
# Feature specific owners
|
||||||
/ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono
|
/ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono
|
||||||
/lib/gitlab/auth/ldap/ @dblessing @mkozono
|
/lib/gitlab/auth/ldap/ @dblessing @mkozono
|
||||||
/lib/gitlab/ci/templates/ @nolith @zj
|
/lib/gitlab/ci/templates/ @nolith @dosuken123
|
||||||
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
|
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
|
||||||
/lib/gitlab/ci/templates/Security/ @plafoucriere @gonzoyumo @twoodham @sethgitlab
|
/lib/gitlab/ci/templates/Security/ @plafoucriere @gonzoyumo @twoodham @sethgitlab
|
||||||
/ee/app/models/project_alias.rb @patrickbajao
|
/ee/app/models/project_alias.rb @patrickbajao
|
||||||
/ee/lib/api/project_aliases.rb @patrickbajao
|
/ee/lib/api/project_aliases.rb @patrickbajao
|
||||||
|
|
||||||
# Code Owners
|
|
||||||
#
|
|
||||||
/ee/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh
|
|
||||||
/doc/user/project/code_owners.md @reprazent @kerrizor @garyh
|
|
||||||
|
|
||||||
# Quality owned files
|
# Quality owned files
|
||||||
/qa/ @gl-quality
|
/qa/ @gl-quality
|
||||||
|
|
||||||
|
@ -77,3 +73,9 @@ Dangerfile @gl-quality/eng-prod
|
||||||
/lib/gitlab/usage_data.rb @gitlab-org/growth/telemetry
|
/lib/gitlab/usage_data.rb @gitlab-org/growth/telemetry
|
||||||
/lib/gitlab/cycle_analytics/usage_data.rb @gitlab-org/growth/telemetry
|
/lib/gitlab/cycle_analytics/usage_data.rb @gitlab-org/growth/telemetry
|
||||||
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/telemetry
|
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/telemetry
|
||||||
|
|
||||||
|
[Code Owners]
|
||||||
|
/ee/lib/gitlab/code_owners.rb @reprazent @kerrizor @garyh
|
||||||
|
/ee/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh
|
||||||
|
/ee/spec/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh
|
||||||
|
/doc/user/project/code_owners.md @reprazent @kerrizor @garyh
|
||||||
|
|
31
.gitlab/ci/build-images.gitlab-ci.yml
Normal file
31
.gitlab/ci/build-images.gitlab-ci.yml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# This image is used by the `review-qa-*` jobs. Not currently used by the `omnibus-gitlab` pipelines which rebuild this
|
||||||
|
# image, e.g. https://gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/-/jobs/587107399, which we could probably avoid.
|
||||||
|
# See https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5429.
|
||||||
|
build-qa-image:
|
||||||
|
extends:
|
||||||
|
- .use-kaniko
|
||||||
|
- .build-images:rules:build-qa-image
|
||||||
|
stage: build-images
|
||||||
|
needs: []
|
||||||
|
script:
|
||||||
|
- export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
|
||||||
|
- /kaniko/executor --context=${CI_PROJECT_DIR} --dockerfile=${CI_PROJECT_DIR}/qa/Dockerfile --destination=${QA_IMAGE} --cache=true
|
||||||
|
retry: 2
|
||||||
|
|
||||||
|
# This image is used by:
|
||||||
|
# - The `CNG` pipelines (via the `review-build-cng` job): https://gitlab.com/gitlab-org/build/CNG/-/blob/cfc67136d711e1c8c409bf8e57427a644393da2f/.gitlab-ci.yml#L335
|
||||||
|
# - The `omnibus-gitlab` pipelines (via the `package-and-qa` job): https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/dfd1ad475868fc84e91ab7b5706aa03e46dc3a86/.gitlab-ci.yml#L130
|
||||||
|
build-assets-image:
|
||||||
|
extends:
|
||||||
|
- .use-kaniko
|
||||||
|
- .build-images:rules:build-assets-image
|
||||||
|
stage: build-images
|
||||||
|
needs: ["compile-production-assets"]
|
||||||
|
variables:
|
||||||
|
GIT_DEPTH: "1"
|
||||||
|
script:
|
||||||
|
# TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists
|
||||||
|
# We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/issues/208389
|
||||||
|
- run_timed_command "scripts/build_assets_image"
|
||||||
|
retry: 2
|
|
@ -59,6 +59,15 @@ docs lint:
|
||||||
# Check the internal anchor links
|
# Check the internal anchor links
|
||||||
- bundle exec nanoc check internal_anchors
|
- bundle exec nanoc check internal_anchors
|
||||||
|
|
||||||
|
ui-docs-links lint:
|
||||||
|
extends:
|
||||||
|
- .docs:rules:docs-lint
|
||||||
|
- .static-analysis-base
|
||||||
|
stage: test
|
||||||
|
needs: []
|
||||||
|
script:
|
||||||
|
- bundle exec haml-lint -i DocumentationLinks
|
||||||
|
|
||||||
graphql-reference-verify:
|
graphql-reference-verify:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
|
|
|
@ -2,16 +2,18 @@
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .assets-compile-cache
|
|
||||||
variables:
|
variables:
|
||||||
SETUP_DB: "false"
|
SETUP_DB: "false"
|
||||||
# we override the max_old_space_size to prevent OOM errors
|
# we override the max_old_space_size to prevent OOM errors
|
||||||
NODE_OPTIONS: --max_old_space_size=3584
|
NODE_OPTIONS: --max_old_space_size=3584
|
||||||
WEBPACK_VENDOR_DLL: "true"
|
|
||||||
|
|
||||||
.compile-assets-base:
|
.compile-assets-base:
|
||||||
extends: .frontend-base
|
extends:
|
||||||
|
- .frontend-base
|
||||||
|
- .assets-compile-cache
|
||||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.27-lfs-2.9-node-12.x-yarn-1.21-graphicsmagick-1.3.34
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.27-lfs-2.9-node-12.x-yarn-1.21-graphicsmagick-1.3.34
|
||||||
|
variables:
|
||||||
|
WEBPACK_VENDOR_DLL: "true"
|
||||||
stage: prepare
|
stage: prepare
|
||||||
script:
|
script:
|
||||||
- node --version
|
- node --version
|
||||||
|
@ -90,21 +92,6 @@ update-yarn-cache:
|
||||||
cache:
|
cache:
|
||||||
policy: push
|
policy: push
|
||||||
|
|
||||||
build-assets-image:
|
|
||||||
extends:
|
|
||||||
- .use-kaniko
|
|
||||||
- .frontend:rules:compile-production-assets
|
|
||||||
stage: build-images
|
|
||||||
needs: ["compile-production-assets"]
|
|
||||||
variables:
|
|
||||||
GIT_DEPTH: "1"
|
|
||||||
script:
|
|
||||||
# TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists
|
|
||||||
# We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/issues/208389
|
|
||||||
- run_timed_command "scripts/build_assets_image"
|
|
||||||
retry: 2
|
|
||||||
|
|
||||||
.frontend-fixtures-base:
|
.frontend-fixtures-base:
|
||||||
extends:
|
extends:
|
||||||
- .frontend-base
|
- .frontend-base
|
||||||
|
@ -114,6 +101,7 @@ build-assets-image:
|
||||||
needs: ["setup-test-env", "compile-test-assets"]
|
needs: ["setup-test-env", "compile-test-assets"]
|
||||||
variables:
|
variables:
|
||||||
SETUP_DB: "true"
|
SETUP_DB: "true"
|
||||||
|
WEBPACK_VENDOR_DLL: "true"
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
|
@ -138,22 +126,25 @@ frontend-fixtures-as-if-foss:
|
||||||
|
|
||||||
.frontend-test-base:
|
.frontend-test-base:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .frontend-base
|
||||||
- .yarn-cache
|
- .yarn-cache
|
||||||
variables:
|
variables:
|
||||||
USE_BUNDLE_INSTALL: "false"
|
USE_BUNDLE_INSTALL: "false"
|
||||||
SETUP_DB: "false"
|
|
||||||
stage: test
|
stage: test
|
||||||
before_script:
|
|
||||||
- source scripts/utils.sh
|
eslint-as-if-foss:
|
||||||
|
extends:
|
||||||
|
- .frontend-test-base
|
||||||
|
- .frontend:rules:eslint-as-if-foss
|
||||||
|
- .as-if-foss
|
||||||
|
needs: []
|
||||||
|
script:
|
||||||
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
|
- yarn run eslint
|
||||||
|
|
||||||
.karma-base:
|
.karma-base:
|
||||||
extends: .frontend-test-base
|
extends: .frontend-test-base
|
||||||
variables:
|
|
||||||
# we override the max_old_space_size to prevent OOM errors
|
|
||||||
NODE_OPTIONS: --max_old_space_size=3584
|
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
|
||||||
- export BABEL_ENV=coverage CHROME_LOG_FILE=chrome_debug.log
|
- export BABEL_ENV=coverage CHROME_LOG_FILE=chrome_debug.log
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
- run_timed_command "yarn karma"
|
- run_timed_command "yarn karma"
|
||||||
|
@ -174,6 +165,7 @@ karma:
|
||||||
- tmp/tests/frontend/
|
- tmp/tests/frontend/
|
||||||
reports:
|
reports:
|
||||||
junit: junit_karma.xml
|
junit: junit_karma.xml
|
||||||
|
cobertura: coverage-javascript/cobertura-coverage.xml
|
||||||
|
|
||||||
karma-as-if-foss:
|
karma-as-if-foss:
|
||||||
extends:
|
extends:
|
||||||
|
@ -185,7 +177,6 @@ karma-as-if-foss:
|
||||||
.jest-base:
|
.jest-base:
|
||||||
extends: .frontend-test-base
|
extends: .frontend-test-base
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
- run_timed_command "yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js"
|
- run_timed_command "yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js"
|
||||||
|
|
||||||
|
@ -211,7 +202,6 @@ jest-integration:
|
||||||
- .frontend-test-base
|
- .frontend-test-base
|
||||||
- .frontend:rules:default-frontend-jobs
|
- .frontend:rules:default-frontend-jobs
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
- run_timed_command "yarn jest:integration --ci"
|
- run_timed_command "yarn jest:integration --ci"
|
||||||
needs: ["frontend-fixtures"]
|
needs: ["frontend-fixtures"]
|
||||||
|
@ -236,11 +226,14 @@ coverage-frontend:
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
script:
|
script:
|
||||||
- run_timed_command "yarn node scripts/frontend/merge_coverage_frontend.js"
|
- run_timed_command "yarn node scripts/frontend/merge_coverage_frontend.js"
|
||||||
|
coverage: '/^Statements\s*:\s*?(\d+(?:\.\d+)?)%/'
|
||||||
artifacts:
|
artifacts:
|
||||||
name: coverage-frontend
|
name: coverage-frontend
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
paths:
|
paths:
|
||||||
- coverage-frontend/
|
- coverage-frontend/
|
||||||
|
reports:
|
||||||
|
cobertura: coverage-frontend/cobertura-coverage.xml
|
||||||
|
|
||||||
.qa-frontend-node:
|
.qa-frontend-node:
|
||||||
extends:
|
extends:
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
.rails-cache:
|
.rails-cache:
|
||||||
cache:
|
cache:
|
||||||
key: "rails-v1"
|
key: "rails-v2"
|
||||||
paths:
|
paths:
|
||||||
- vendor/ruby/
|
- vendor/ruby/
|
||||||
- vendor/gitaly-ruby/
|
- vendor/gitaly-ruby/
|
||||||
|
@ -72,6 +72,15 @@
|
||||||
variables:
|
variables:
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
|
.use-pg12:
|
||||||
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-12-graphicsmagick-1.3.34"
|
||||||
|
services:
|
||||||
|
- name: postgres:12
|
||||||
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
|
- name: redis:alpine
|
||||||
|
variables:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-pg11-ee:
|
.use-pg11-ee:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
|
||||||
services:
|
services:
|
||||||
|
@ -82,6 +91,16 @@
|
||||||
variables:
|
variables:
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
|
.use-pg12-ee:
|
||||||
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-12-graphicsmagick-1.3.34"
|
||||||
|
services:
|
||||||
|
- name: postgres:12
|
||||||
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
|
- name: redis:alpine
|
||||||
|
- name: elasticsearch:6.4.2
|
||||||
|
variables:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-kaniko:
|
.use-kaniko:
|
||||||
image:
|
image:
|
||||||
name: gcr.io/kaniko-project/executor:debug-v0.20.0
|
name: gcr.io/kaniko-project/executor:debug-v0.20.0
|
||||||
|
|
|
@ -49,7 +49,6 @@ update-qa-cache:
|
||||||
.package-and-qa-base:
|
.package-and-qa-base:
|
||||||
image: ruby:2.6-alpine
|
image: ruby:2.6-alpine
|
||||||
stage: qa
|
stage: qa
|
||||||
dependencies: []
|
|
||||||
retry: 0
|
retry: 0
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
- source scripts/utils.sh
|
||||||
|
|
|
@ -1,9 +1,129 @@
|
||||||
|
######################
|
||||||
|
# rspec job base specs
|
||||||
.rails-job-base:
|
.rails-job-base:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .rails-cache
|
- .rails-cache
|
||||||
|
|
||||||
|
.rspec-base:
|
||||||
|
extends: .rails-job-base
|
||||||
|
stage: test
|
||||||
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"]
|
||||||
|
script:
|
||||||
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
|
- source scripts/rspec_helpers.sh
|
||||||
|
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag ~level:migration"
|
||||||
|
artifacts:
|
||||||
|
expire_in: 31d
|
||||||
|
when: always
|
||||||
|
paths:
|
||||||
|
- coverage/
|
||||||
|
- knapsack/
|
||||||
|
- rspec_flaky/
|
||||||
|
- rspec_profiling/
|
||||||
|
- tmp/capybara/
|
||||||
|
- tmp/memory_test/
|
||||||
|
- log/*.log
|
||||||
|
reports:
|
||||||
|
junit: junit_rspec.xml
|
||||||
|
|
||||||
|
.rspec-base-migration:
|
||||||
|
extends: .rails:rules:ee-and-foss-migration
|
||||||
|
script:
|
||||||
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
|
- source scripts/rspec_helpers.sh
|
||||||
|
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
|
||||||
|
|
||||||
|
.rspec-base-pg11:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .use-pg11
|
||||||
|
|
||||||
|
.rspec-base-pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .use-pg12
|
||||||
|
|
||||||
|
.rspec-base-pg11-as-if-foss:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .as-if-foss
|
||||||
|
- .use-pg11
|
||||||
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss"]
|
||||||
|
|
||||||
|
.rspec-ee-base-pg11:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .use-pg11-ee
|
||||||
|
|
||||||
|
.rspec-ee-base-pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-base
|
||||||
|
- .use-pg12-ee
|
||||||
|
|
||||||
|
.rspec-ee-base-geo:
|
||||||
|
extends: .rspec-base
|
||||||
|
script:
|
||||||
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
|
- 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-base-geo-pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-geo
|
||||||
|
- .use-pg12-ee
|
||||||
|
|
||||||
|
.db-job-base:
|
||||||
|
extends:
|
||||||
|
- .rails-job-base
|
||||||
|
- .rails:rules:ee-and-foss-migration
|
||||||
|
- .use-pg11
|
||||||
|
stage: test
|
||||||
|
needs: ["setup-test-env"]
|
||||||
|
# rspec job base specs
|
||||||
|
######################
|
||||||
|
|
||||||
|
############################
|
||||||
|
# rspec job parallel configs
|
||||||
|
.rspec-migration-parallel:
|
||||||
|
parallel: 5
|
||||||
|
|
||||||
|
.rspec-ee-migration-parallel:
|
||||||
|
parallel: 2
|
||||||
|
|
||||||
|
.rspec-unit-parallel:
|
||||||
|
parallel: 20
|
||||||
|
|
||||||
|
.rspec-ee-unit-parallel:
|
||||||
|
parallel: 10
|
||||||
|
|
||||||
|
.rspec-ee-unit-geo-parallel:
|
||||||
|
parallel: 2
|
||||||
|
|
||||||
|
.rspec-integration-parallel:
|
||||||
|
parallel: 8
|
||||||
|
|
||||||
|
.rspec-ee-integration-parallel:
|
||||||
|
parallel: 4
|
||||||
|
|
||||||
|
.rspec-system-parallel:
|
||||||
|
parallel: 24
|
||||||
|
|
||||||
|
.rspec-ee-system-parallel:
|
||||||
|
parallel: 6
|
||||||
|
# rspec job parallel configs
|
||||||
|
############################
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
# EE/FOSS: default refs (MRs, master, schedules) jobs #
|
# EE/FOSS: default refs (MRs, master, schedules) jobs #
|
||||||
setup-test-env:
|
setup-test-env:
|
||||||
|
@ -86,73 +206,37 @@ downtime_check:
|
||||||
script:
|
script:
|
||||||
- bundle exec rake downtime_check
|
- bundle exec rake downtime_check
|
||||||
|
|
||||||
.rspec-base:
|
|
||||||
extends: .rails-job-base
|
|
||||||
stage: test
|
|
||||||
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"]
|
|
||||||
script:
|
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag ~level:migration"
|
|
||||||
artifacts:
|
|
||||||
expire_in: 31d
|
|
||||||
when: always
|
|
||||||
paths:
|
|
||||||
- coverage/
|
|
||||||
- knapsack/
|
|
||||||
- rspec_flaky/
|
|
||||||
- rspec_profiling/
|
|
||||||
- tmp/capybara/
|
|
||||||
- tmp/memory_test/
|
|
||||||
- log/*.log
|
|
||||||
reports:
|
|
||||||
junit: junit_rspec.xml
|
|
||||||
|
|
||||||
.rspec-base-pg11:
|
|
||||||
extends:
|
|
||||||
- .rspec-base
|
|
||||||
- .rails:rules:ee-and-foss
|
|
||||||
- .use-pg11
|
|
||||||
|
|
||||||
.rspec-base-migration:
|
|
||||||
script:
|
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
|
|
||||||
|
|
||||||
rspec migration pg11:
|
rspec migration pg11:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-base-pg11
|
- .rspec-base-pg11
|
||||||
- .rspec-base-migration
|
- .rspec-base-migration
|
||||||
parallel: 5
|
- .rspec-migration-parallel
|
||||||
|
|
||||||
rspec unit pg11:
|
rspec unit pg11:
|
||||||
extends: .rspec-base-pg11
|
extends:
|
||||||
parallel: 20
|
- .rspec-base-pg11
|
||||||
|
- .rails:rules:ee-and-foss-unit
|
||||||
|
- .rspec-unit-parallel
|
||||||
|
|
||||||
rspec integration pg11:
|
rspec integration pg11:
|
||||||
extends: .rspec-base-pg11
|
extends:
|
||||||
parallel: 8
|
- .rspec-base-pg11
|
||||||
|
- .rails:rules:ee-and-foss-integration
|
||||||
|
- .rspec-integration-parallel
|
||||||
|
|
||||||
rspec system pg11:
|
rspec system pg11:
|
||||||
extends: .rspec-base-pg11
|
extends:
|
||||||
parallel: 24
|
- .rspec-base-pg11
|
||||||
|
- .rails:rules:ee-and-foss-system
|
||||||
|
- .rspec-system-parallel
|
||||||
|
|
||||||
rspec fast_spec_helper:
|
rspec fast_spec_helper:
|
||||||
extends: .rspec-base-pg11
|
extends:
|
||||||
|
- .rspec-base-pg11
|
||||||
|
- .rails:rules:ee-and-foss-fast_spec_helper
|
||||||
script:
|
script:
|
||||||
- bin/rspec spec/fast_spec_helper.rb
|
- bin/rspec spec/fast_spec_helper.rb
|
||||||
|
|
||||||
.db-job-base:
|
|
||||||
extends:
|
|
||||||
- .rails-job-base
|
|
||||||
- .rails:rules:ee-and-foss
|
|
||||||
- .use-pg11
|
|
||||||
stage: test
|
|
||||||
needs: ["setup-test-env"]
|
|
||||||
|
|
||||||
db:migrate:reset:
|
db:migrate:reset:
|
||||||
extends: .db-job-base
|
extends: .db-job-base
|
||||||
script:
|
script:
|
||||||
|
@ -216,7 +300,7 @@ gitlab:setup:
|
||||||
rspec:coverage:
|
rspec:coverage:
|
||||||
extends:
|
extends:
|
||||||
- .rails-job-base
|
- .rails-job-base
|
||||||
- .rails:rules:ee-mr-and-master-only
|
- .rails:rules:rspec-coverage
|
||||||
stage: post-test
|
stage: post-test
|
||||||
# We cannot use needs since it would mean needing 84 jobs (since most are parallelized)
|
# We cannot use needs since it would mean needing 84 jobs (since most are parallelized)
|
||||||
# so we use `dependencies` here.
|
# so we use `dependencies` here.
|
||||||
|
@ -248,118 +332,180 @@ rspec:coverage:
|
||||||
- coverage/index.html
|
- coverage/index.html
|
||||||
- coverage/assets/
|
- coverage/assets/
|
||||||
- tmp/memory_test/
|
- tmp/memory_test/
|
||||||
|
reports:
|
||||||
|
cobertura: coverage/coverage.xml
|
||||||
# EE/FOSS: default refs (MRs, master, schedules) jobs #
|
# EE/FOSS: default refs (MRs, master, schedules) jobs #
|
||||||
#######################################################
|
#######################################################
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# EE: default refs (MRs, master, schedules) jobs #
|
# EE: default refs (MRs, master, schedules) jobs #
|
||||||
.rspec-base-ee:
|
|
||||||
extends:
|
|
||||||
- .rspec-base
|
|
||||||
- .rails:rules:ee-only
|
|
||||||
|
|
||||||
.rspec-base-pg11-as-if-foss:
|
|
||||||
extends:
|
|
||||||
- .rspec-base
|
|
||||||
- .rails:rules:as-if-foss
|
|
||||||
- .as-if-foss
|
|
||||||
- .use-pg11
|
|
||||||
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss"]
|
|
||||||
|
|
||||||
.rspec-ee-base-pg11:
|
|
||||||
extends:
|
|
||||||
- .rspec-base-ee
|
|
||||||
- .use-pg11-ee
|
|
||||||
|
|
||||||
rspec migration pg11-as-if-foss:
|
rspec migration pg11-as-if-foss:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-base-pg11-as-if-foss
|
- .rspec-base-pg11-as-if-foss
|
||||||
- .rspec-base-migration
|
- .rspec-base-migration
|
||||||
parallel: 5
|
- .rails:rules:as-if-foss-migration
|
||||||
|
- .rspec-migration-parallel
|
||||||
|
|
||||||
rspec unit pg11-as-if-foss:
|
rspec unit pg11-as-if-foss:
|
||||||
extends: .rspec-base-pg11-as-if-foss
|
extends:
|
||||||
parallel: 20
|
- .rspec-base-pg11-as-if-foss
|
||||||
|
- .rails:rules:as-if-foss-unit
|
||||||
|
- .rspec-unit-parallel
|
||||||
|
|
||||||
rspec integration pg11-as-if-foss:
|
rspec integration pg11-as-if-foss:
|
||||||
extends: .rspec-base-pg11-as-if-foss
|
extends:
|
||||||
parallel: 8
|
- .rspec-base-pg11-as-if-foss
|
||||||
|
- .rails:rules:as-if-foss-integration
|
||||||
|
- .rspec-integration-parallel
|
||||||
|
|
||||||
rspec system pg11-as-if-foss:
|
rspec system pg11-as-if-foss:
|
||||||
extends: .rspec-base-pg11-as-if-foss
|
extends:
|
||||||
parallel: 24
|
- .rspec-base-pg11-as-if-foss
|
||||||
|
- .rails:rules:as-if-foss-system
|
||||||
|
- .rspec-system-parallel
|
||||||
|
|
||||||
rspec-ee migration pg11:
|
rspec-ee migration pg11:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-ee-base-pg11
|
- .rspec-ee-base-pg11
|
||||||
- .rspec-base-migration
|
- .rspec-base-migration
|
||||||
parallel: 2
|
- .rails:rules:ee-only-migration
|
||||||
|
- .rspec-ee-migration-parallel
|
||||||
|
|
||||||
rspec-ee unit pg11:
|
rspec-ee unit pg11:
|
||||||
extends: .rspec-ee-base-pg11
|
extends:
|
||||||
parallel: 10
|
- .rspec-ee-base-pg11
|
||||||
|
- .rails:rules:ee-only-unit
|
||||||
|
- .rspec-ee-unit-parallel
|
||||||
|
|
||||||
rspec-ee integration pg11:
|
rspec-ee integration pg11:
|
||||||
extends: .rspec-ee-base-pg11
|
extends:
|
||||||
parallel: 4
|
- .rspec-ee-base-pg11
|
||||||
|
- .rails:rules:ee-only-integration
|
||||||
|
- .rspec-ee-integration-parallel
|
||||||
|
|
||||||
rspec-ee system pg11:
|
rspec-ee system pg11:
|
||||||
extends: .rspec-ee-base-pg11
|
|
||||||
parallel: 6
|
|
||||||
|
|
||||||
.rspec-ee-base-geo:
|
|
||||||
extends: .rspec-base-ee
|
|
||||||
script:
|
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- scripts/prepare_postgres_fdw.sh
|
|
||||||
- rspec_paralellized_job "--tag ~quarantine --tag geo"
|
|
||||||
|
|
||||||
.rspec-ee-base-geo-pg11:
|
|
||||||
extends:
|
extends:
|
||||||
- .rspec-ee-base-geo
|
- .rspec-ee-base-pg11
|
||||||
- .use-pg11-ee
|
- .rails:rules:ee-only-system
|
||||||
|
- .rspec-ee-system-parallel
|
||||||
|
|
||||||
rspec-ee unit pg11 geo:
|
rspec-ee unit pg11 geo:
|
||||||
extends: .rspec-ee-base-geo-pg11
|
extends:
|
||||||
parallel: 2
|
- .rspec-ee-base-geo-pg11
|
||||||
|
- .rails:rules:ee-only-unit
|
||||||
|
- .rspec-ee-unit-geo-parallel
|
||||||
|
|
||||||
rspec-ee integration pg11 geo:
|
rspec-ee integration pg11 geo:
|
||||||
extends: .rspec-ee-base-geo-pg11
|
extends:
|
||||||
|
- .rspec-ee-base-geo-pg11
|
||||||
|
- .rails:rules:ee-only-integration
|
||||||
|
|
||||||
rspec-ee system pg11 geo:
|
rspec-ee system pg11 geo:
|
||||||
extends: .rspec-ee-base-geo-pg11
|
extends:
|
||||||
|
- .rspec-ee-base-geo-pg11
|
||||||
|
- .rails:rules:ee-only-system
|
||||||
|
|
||||||
db:rollback geo:
|
db:rollback geo:
|
||||||
extends:
|
extends:
|
||||||
- db:rollback
|
- db:rollback
|
||||||
- .rails:rules:ee-only
|
- .rails:rules:ee-only-migration
|
||||||
script:
|
script:
|
||||||
- bundle exec rake geo:db:migrate VERSION=20170627195211
|
- bundle exec rake geo:db:migrate VERSION=20170627195211
|
||||||
- bundle exec rake geo:db:migrate
|
- bundle exec rake geo:db:migrate
|
||||||
# EE: default refs (MRs, master, schedules) jobs #
|
# EE: default refs (MRs, master, schedules) jobs #
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# EE/FOSS: master nightly scheduled jobs #
|
||||||
|
rspec migration pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-base-pg12
|
||||||
|
- .rspec-base-migration
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage
|
||||||
|
- .rspec-migration-parallel
|
||||||
|
|
||||||
|
rspec unit pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-base-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage
|
||||||
|
- .rspec-unit-parallel
|
||||||
|
|
||||||
|
rspec integration pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-base-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage
|
||||||
|
- .rspec-integration-parallel
|
||||||
|
|
||||||
|
rspec system pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-base-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage
|
||||||
|
- .rspec-system-parallel
|
||||||
|
# EE/FOSS: master nightly scheduled jobs #
|
||||||
|
##########################################
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# EE: master nightly scheduled jobs #
|
||||||
|
rspec-ee migration pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg12
|
||||||
|
- .rspec-base-migration
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
- .rspec-ee-migration-parallel
|
||||||
|
|
||||||
|
rspec-ee unit pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
- .rspec-ee-unit-parallel
|
||||||
|
|
||||||
|
rspec-ee integration pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
- .rspec-ee-integration-parallel
|
||||||
|
|
||||||
|
rspec-ee system pg12:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
- .rspec-ee-system-parallel
|
||||||
|
|
||||||
|
rspec-ee unit pg12 geo:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-geo-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
- .rspec-ee-unit-geo-parallel
|
||||||
|
|
||||||
|
rspec-ee integration pg12 geo:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-geo-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
|
||||||
|
rspec-ee system pg12 geo:
|
||||||
|
extends:
|
||||||
|
- .rspec-ee-base-geo-pg12
|
||||||
|
- .rails:rules:master-schedule-nightly--code-backstage-ee-only
|
||||||
|
# EE: master nightly scheduled jobs #
|
||||||
|
#####################################
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# EE: Canonical MR pipelines
|
# EE: Canonical MR pipelines
|
||||||
rspec foss-impact:
|
rspec foss-impact:
|
||||||
extends:
|
extends:
|
||||||
- .rspec-base
|
- .rspec-base-pg11-as-if-foss
|
||||||
- .as-if-foss
|
|
||||||
- .rails:rules:ee-mr-only
|
- .rails:rules:ee-mr-only
|
||||||
- .use-pg11
|
|
||||||
script:
|
script:
|
||||||
- install_gitlab_gem
|
- install_gitlab_gem
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
- source scripts/rspec_helpers.sh
|
- source scripts/rspec_helpers.sh
|
||||||
- tooling/bin/find_foss_tests tmp/matching_foss_tests.txt
|
- tooling/bin/find_foss_tests tmp/matching_foss_tests.txt
|
||||||
- rspec_matched_tests tmp/matching_foss_tests.txt "--tag ~quarantine --tag ~geo --tag ~level:migration"
|
- rspec_matched_tests tmp/matching_foss_tests.txt "--tag ~quarantine"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 7d
|
expire_in: 7d
|
||||||
paths:
|
paths:
|
||||||
- tmp/matching_foss_tests.txt
|
- tmp/matching_foss_tests.txt
|
||||||
- tmp/capybara/
|
- tmp/capybara/
|
||||||
# EE: Merge Request pipelines
|
# EE: Canonical MR pipelines
|
||||||
##################################################
|
##################################################
|
||||||
|
|
|
@ -15,7 +15,7 @@ code_quality:
|
||||||
stage: test
|
stage: test
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.9"
|
CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.10"
|
||||||
script:
|
script:
|
||||||
- |
|
- |
|
||||||
if ! docker info &>/dev/null; then
|
if ! docker info &>/dev/null; then
|
||||||
|
@ -59,6 +59,7 @@ code_quality:
|
||||||
SAST_ANALYZER_IMAGE_TAG: 2
|
SAST_ANALYZER_IMAGE_TAG: 2
|
||||||
SAST_BRAKEMAN_LEVEL: 2 # GitLab-specific
|
SAST_BRAKEMAN_LEVEL: 2 # GitLab-specific
|
||||||
SAST_EXCLUDED_PATHS: qa,spec,doc,ee/spec # GitLab-specific
|
SAST_EXCLUDED_PATHS: qa,spec,doc,ee/spec # GitLab-specific
|
||||||
|
SAST_DISABLE_BABEL: "true"
|
||||||
script:
|
script:
|
||||||
- /analyzer run
|
- /analyzer run
|
||||||
|
|
||||||
|
@ -72,11 +73,10 @@ eslint-sast:
|
||||||
image:
|
image:
|
||||||
name: "$SAST_ANALYZER_IMAGE_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
|
name: "$SAST_ANALYZER_IMAGE_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
|
||||||
|
|
||||||
# Temporary disabled as it's constantly failing. See https://gitlab.com/gitlab-org/gitlab/-/issues/213769.
|
nodejs-scan-sast:
|
||||||
# nodejs-scan-sast:
|
extends: .sast
|
||||||
# extends: .sast
|
image:
|
||||||
# image:
|
name: "$SAST_ANALYZER_IMAGE_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
|
||||||
# name: "$SAST_ANALYZER_IMAGE_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
|
|
||||||
|
|
||||||
secrets-sast:
|
secrets-sast:
|
||||||
extends: .sast
|
extends: .sast
|
||||||
|
@ -172,6 +172,7 @@ dependency_scanning:
|
||||||
# # - 'export DAST_AUTH_URL="${DAST_WEBSITE}/users/sign_in"'
|
# # - 'export DAST_AUTH_URL="${DAST_WEBSITE}/users/sign_in"'
|
||||||
# # - 'export DAST_PASSWORD="${REVIEW_APPS_ROOT_PASSWORD}"'
|
# # - 'export DAST_PASSWORD="${REVIEW_APPS_ROOT_PASSWORD}"'
|
||||||
# - /analyze -t $DAST_WEBSITE
|
# - /analyze -t $DAST_WEBSITE
|
||||||
|
# timeout: 4h
|
||||||
# artifacts:
|
# artifacts:
|
||||||
# paths:
|
# paths:
|
||||||
# - gl-dast-report.json # GitLab-specific
|
# - gl-dast-report.json # GitLab-specific
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
build-qa-image:
|
|
||||||
extends:
|
|
||||||
- .use-kaniko
|
|
||||||
- .review:rules:build-qa-image
|
|
||||||
stage: build-images
|
|
||||||
needs: []
|
|
||||||
script:
|
|
||||||
- export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
|
|
||||||
- /kaniko/executor --context=${CI_PROJECT_DIR} --dockerfile=${CI_PROJECT_DIR}/qa/Dockerfile --destination=${QA_IMAGE} --cache=true
|
|
||||||
retry: 2
|
|
||||||
|
|
||||||
review-cleanup:
|
review-cleanup:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
|
@ -27,25 +16,24 @@ review-cleanup:
|
||||||
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
|
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
|
||||||
- gcp_cleanup
|
- gcp_cleanup
|
||||||
|
|
||||||
# Temporarily disabling review apps
|
review-build-cng:
|
||||||
#review-build-cng:
|
extends:
|
||||||
# extends:
|
- .default-retry
|
||||||
# - .default-retry
|
- .review:rules:review-build-cng
|
||||||
# - .review:rules:review-build-cng
|
image: ruby:2.6-alpine
|
||||||
# image: ruby:2.6-alpine
|
stage: review-prepare
|
||||||
# stage: review-prepare
|
before_script:
|
||||||
# before_script:
|
- source scripts/utils.sh
|
||||||
# - source scripts/utils.sh
|
- install_api_client_dependencies_with_apk
|
||||||
# - install_api_client_dependencies_with_apk
|
- install_gitlab_gem
|
||||||
# - install_gitlab_gem
|
needs:
|
||||||
# needs:
|
- job: compile-production-assets
|
||||||
# - job: compile-production-assets
|
artifacts: false
|
||||||
# artifacts: false
|
script:
|
||||||
# script:
|
- BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
|
||||||
# - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
|
# When the job is manual, review-deploy is also manual and we don't want people
|
||||||
# # When the job is manual, review-deploy is also manual and we don't want people
|
# to have to manually start the jobs in sequence, so we do it for them.
|
||||||
# # to have to manually start the jobs in sequence, so we do it for them.
|
- '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"'
|
||||||
# - '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"'
|
|
||||||
|
|
||||||
.review-workflow-base:
|
.review-workflow-base:
|
||||||
extends:
|
extends:
|
||||||
|
@ -53,45 +41,46 @@ review-cleanup:
|
||||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-helm3-kubectl1.14
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-helm3-kubectl1.14
|
||||||
variables:
|
variables:
|
||||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||||
|
REVIEW_APPS_DOMAIN: "temp.gitlab-review.app" # FIXME: using temporary domain
|
||||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||||
GITLAB_HELM_CHART_REF: "master"
|
GITLAB_HELM_CHART_REF: "v4.1.3"
|
||||||
environment:
|
environment:
|
||||||
name: review/${CI_COMMIT_REF_NAME}
|
name: review/${CI_COMMIT_REF_NAME}
|
||||||
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
||||||
on_stop: review-stop
|
on_stop: review-stop
|
||||||
auto_stop_in: 48 hours
|
auto_stop_in: 48 hours
|
||||||
|
|
||||||
# Temporarily disabling review apps
|
review-deploy:
|
||||||
#review-deploy:
|
extends:
|
||||||
# extends:
|
- .review-workflow-base
|
||||||
# - .review-workflow-base
|
- .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
|
||||||
# - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
|
stage: review
|
||||||
# stage: review
|
dependencies: []
|
||||||
# dependencies: []
|
resource_group: "review/${CI_COMMIT_REF_NAME}"
|
||||||
# resource_group: "review/${CI_COMMIT_REF_NAME}"
|
before_script:
|
||||||
# before_script:
|
- export GITLAB_SHELL_VERSION=$(<GITLAB_SHELL_VERSION)
|
||||||
# - export GITLAB_SHELL_VERSION=$(<GITLAB_SHELL_VERSION)
|
- export GITALY_VERSION=$(<GITALY_SERVER_VERSION)
|
||||||
# - export GITALY_VERSION=$(<GITALY_SERVER_VERSION)
|
- export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
|
||||||
# - export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
|
- echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
|
||||||
# - echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
|
- source ./scripts/utils.sh
|
||||||
# - source ./scripts/utils.sh
|
- install_api_client_dependencies_with_apk
|
||||||
# - install_api_client_dependencies_with_apk
|
- source scripts/review_apps/review-apps.sh
|
||||||
# - source scripts/review_apps/review-apps.sh
|
script:
|
||||||
# script:
|
- check_kube_domain
|
||||||
# - check_kube_domain
|
- ensure_namespace
|
||||||
# - ensure_namespace
|
- install_external_dns
|
||||||
# - install_external_dns
|
- download_chart
|
||||||
# - download_chart
|
- date
|
||||||
# - date
|
- deploy || (display_deployment_debug && exit 1)
|
||||||
# - deploy || (display_deployment_debug && exit 1)
|
- disable_sign_ups
|
||||||
# # When the job is manual, review-qa-smoke is also manual and we don't want people
|
# When the job is manual, review-qa-smoke is also manual and we don't want people
|
||||||
# # to have to manually start the jobs in sequence, so we do it for them.
|
# to have to manually start the jobs in sequence, so we do it for them.
|
||||||
# - '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"'
|
- '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"'
|
||||||
# - '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"'
|
- '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"'
|
||||||
# artifacts:
|
artifacts:
|
||||||
# paths: [environment_url.txt]
|
paths: [environment_url.txt]
|
||||||
# expire_in: 2 days
|
expire_in: 2 days
|
||||||
# when: always
|
when: always
|
||||||
|
|
||||||
.review-stop-base:
|
.review-stop-base:
|
||||||
extends: .review-workflow-base
|
extends: .review-workflow-base
|
||||||
|
@ -124,110 +113,110 @@ review-stop:
|
||||||
script:
|
script:
|
||||||
- delete_release
|
- delete_release
|
||||||
|
|
||||||
# Temporarily disabling review apps
|
.review-qa-base:
|
||||||
#.review-qa-base:
|
extends:
|
||||||
# extends:
|
- .default-retry
|
||||||
# - .default-retry
|
- .use-docker-in-docker
|
||||||
# - .use-docker-in-docker
|
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6
|
||||||
# image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6
|
stage: qa
|
||||||
# stage: qa
|
# This is needed so that manual jobs with needs don't block the pipeline.
|
||||||
# # This is needed so that manual jobs with needs don't block the pipeline.
|
# See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
|
||||||
# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
|
dependencies: ["review-deploy"]
|
||||||
# dependencies: ["review-deploy"]
|
variables:
|
||||||
# variables:
|
QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
|
||||||
# QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
|
QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
|
||||||
# QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
|
QA_DEBUG: "true"
|
||||||
# QA_DEBUG: "true"
|
GITLAB_USERNAME: "root"
|
||||||
# GITLAB_USERNAME: "root"
|
GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
||||||
# GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
GITLAB_ADMIN_USERNAME: "root"
|
||||||
# GITLAB_ADMIN_USERNAME: "root"
|
GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
||||||
# GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
|
||||||
# GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
|
EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
|
||||||
# EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
|
SIGNUP_DISABLED: "true"
|
||||||
# before_script:
|
before_script:
|
||||||
# - export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
|
- export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
|
||||||
# - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
|
- export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
|
||||||
# - echo "${CI_ENVIRONMENT_URL}"
|
- echo "${CI_ENVIRONMENT_URL}"
|
||||||
# - echo "${QA_IMAGE}"
|
- echo "${QA_IMAGE}"
|
||||||
# - source scripts/utils.sh
|
- source scripts/utils.sh
|
||||||
# - install_api_client_dependencies_with_apk
|
- install_api_client_dependencies_with_apk
|
||||||
# - gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}}
|
- gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}}
|
||||||
# artifacts:
|
artifacts:
|
||||||
# paths:
|
paths:
|
||||||
# - ./qa/gitlab-qa-run-*
|
- ./qa/gitlab-qa-run-*
|
||||||
# expire_in: 7 days
|
expire_in: 7 days
|
||||||
# when: always
|
when: always
|
||||||
#
|
|
||||||
#review-qa-smoke:
|
review-qa-smoke:
|
||||||
# extends:
|
extends:
|
||||||
# - .review-qa-base
|
- .review-qa-base
|
||||||
# - .review:rules:review-qa-smoke
|
- .review:rules:review-qa-smoke
|
||||||
# script:
|
script:
|
||||||
# - gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
|
- gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
|
||||||
#
|
|
||||||
#review-qa-all:
|
review-qa-all:
|
||||||
# extends:
|
extends:
|
||||||
# - .review-qa-base
|
- .review-qa-base
|
||||||
# - .review:rules:mr-only-manual
|
- .review:rules:mr-only-manual
|
||||||
# parallel: 5
|
parallel: 5
|
||||||
# script:
|
script:
|
||||||
# - export KNAPSACK_REPORT_PATH=knapsack/master_report.json
|
- export KNAPSACK_REPORT_PATH=knapsack/master_report.json
|
||||||
# - export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
|
- export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
|
||||||
# - gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
|
- gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
|
||||||
#
|
|
||||||
#review-performance:
|
review-performance:
|
||||||
# extends:
|
extends:
|
||||||
# - .default-retry
|
- .default-retry
|
||||||
# - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
|
- .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
|
||||||
# image:
|
image:
|
||||||
# name: sitespeedio/sitespeed.io:6.3.1
|
name: sitespeedio/sitespeed.io:6.3.1
|
||||||
# entrypoint: [""]
|
entrypoint: [""]
|
||||||
# stage: qa
|
stage: qa
|
||||||
# # This is needed so that manual jobs with needs don't block the pipeline.
|
# This is needed so that manual jobs with needs don't block the pipeline.
|
||||||
# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
|
# See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
|
||||||
# dependencies: ["review-deploy"]
|
dependencies: ["review-deploy"]
|
||||||
# before_script:
|
before_script:
|
||||||
# - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
|
- export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
|
||||||
# - echo "${CI_ENVIRONMENT_URL}"
|
- echo "${CI_ENVIRONMENT_URL}"
|
||||||
# - mkdir -p gitlab-exporter
|
- mkdir -p gitlab-exporter
|
||||||
# - wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
|
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
|
||||||
# - mkdir -p sitespeed-results
|
- mkdir -p sitespeed-results
|
||||||
# script:
|
script:
|
||||||
# - /start.sh --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
|
- /start.sh --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
|
||||||
# after_script:
|
after_script:
|
||||||
# - mv sitespeed-results/data/performance.json performance.json
|
- mv sitespeed-results/data/performance.json performance.json
|
||||||
# artifacts:
|
artifacts:
|
||||||
# paths:
|
paths:
|
||||||
# - sitespeed-results/
|
- sitespeed-results/
|
||||||
# reports:
|
reports:
|
||||||
# performance: performance.json
|
performance: performance.json
|
||||||
# expire_in: 31d
|
expire_in: 31d
|
||||||
#
|
|
||||||
#parallel-spec-reports:
|
parallel-spec-reports:
|
||||||
# extends:
|
extends:
|
||||||
# - .review:rules:mr-only-manual
|
- .review:rules:mr-only-manual
|
||||||
# image: ruby:2.6-alpine
|
image: ruby:2.6-alpine
|
||||||
# stage: post-qa
|
stage: post-qa
|
||||||
# dependencies: ["review-qa-all"]
|
dependencies: ["review-qa-all"]
|
||||||
# variables:
|
variables:
|
||||||
# NEW_PARALLEL_SPECS_REPORT: qa/report-new.html
|
NEW_PARALLEL_SPECS_REPORT: qa/report-new.html
|
||||||
# BASE_ARTIFACT_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/qa/"
|
BASE_ARTIFACT_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/qa/"
|
||||||
# script:
|
script:
|
||||||
# - apk add --update build-base libxml2-dev libxslt-dev && rm -rf /var/cache/apk/*
|
- apk add --update build-base libxml2-dev libxslt-dev && rm -rf /var/cache/apk/*
|
||||||
# - gem install nokogiri --no-document
|
- gem install nokogiri --no-document
|
||||||
# - cd qa/gitlab-qa-run-*/gitlab-*
|
- cd qa/gitlab-qa-run-*/gitlab-*
|
||||||
# - ARTIFACT_DIRS=$(pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_)
|
- ARTIFACT_DIRS=$(pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_)
|
||||||
# - cd -
|
- cd -
|
||||||
# - '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}'
|
- '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}'
|
||||||
# - scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm
|
- scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm
|
||||||
# artifacts:
|
artifacts:
|
||||||
# when: always
|
when: always
|
||||||
# paths:
|
paths:
|
||||||
# - qa/report-new.html
|
- qa/report-new.html
|
||||||
# - qa/gitlab-qa-run-*
|
- qa/gitlab-qa-run-*
|
||||||
# reports:
|
reports:
|
||||||
# junit: qa/gitlab-qa-run-*/**/rspec-*.xml
|
junit: qa/gitlab-qa-run-*/**/rspec-*.xml
|
||||||
# expire_in: 31d
|
expire_in: 31d
|
||||||
|
|
||||||
danger-review:
|
danger-review:
|
||||||
extends:
|
extends:
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
if: '$CI_PROJECT_NAME != "gitlab-foss" && $CI_PROJECT_NAME != "gitlab-ce" && $CI_PROJECT_NAME != "gitlabhq"'
|
if: '$CI_PROJECT_NAME != "gitlab-foss" && $CI_PROJECT_NAME != "gitlab-ce" && $CI_PROJECT_NAME != "gitlabhq"'
|
||||||
|
|
||||||
.if-default-refs: &if-default-refs
|
.if-default-refs: &if-default-refs
|
||||||
if: '$CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/ || $CI_COMMIT_REF_NAME =~ /^\d+-\d+-auto-deploy-\d+$/ || $CI_COMMIT_REF_NAME =~ /^security\// || $CI_MERGE_REQUEST_IID || $CI_COMMIT_TAG'
|
if: '$CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/ || $CI_COMMIT_REF_NAME =~ /^\d+-\d+-auto-deploy-\d+$/ || $CI_COMMIT_REF_NAME =~ /^security\// || $CI_MERGE_REQUEST_IID || $CI_COMMIT_TAG || $FORCE_GITLAB_CI'
|
||||||
|
|
||||||
.if-master-refs: &if-master-refs
|
.if-master-refs: &if-master-refs
|
||||||
if: '$CI_COMMIT_REF_NAME == "master"'
|
if: '$CI_COMMIT_REF_NAME == "master"'
|
||||||
|
@ -40,6 +40,9 @@
|
||||||
.if-merge-request-title-update-caches: &if-merge-request-title-update-caches
|
.if-merge-request-title-update-caches: &if-merge-request-title-update-caches
|
||||||
if: '$CI_MERGE_REQUEST_TITLE =~ /UPDATE CACHE/'
|
if: '$CI_MERGE_REQUEST_TITLE =~ /UPDATE CACHE/'
|
||||||
|
|
||||||
|
.if-merge-request-title-run-all-rspec: &if-merge-request-title-run-all-rspec
|
||||||
|
if: '$CI_MERGE_REQUEST_TITLE =~ /RUN ALL RSPEC/'
|
||||||
|
|
||||||
.if-security-merge-request: &if-security-merge-request
|
.if-security-merge-request: &if-security-merge-request
|
||||||
if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security" && $CI_MERGE_REQUEST_IID'
|
if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security" && $CI_MERGE_REQUEST_IID'
|
||||||
|
|
||||||
|
@ -71,6 +74,22 @@
|
||||||
- ".gitlab-ci.yml"
|
- ".gitlab-ci.yml"
|
||||||
- ".gitlab/ci/**/*"
|
- ".gitlab/ci/**/*"
|
||||||
|
|
||||||
|
.ci-build-images-patterns: &ci-build-images-patterns
|
||||||
|
- ".gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/build-images.gitlab-ci.yml"
|
||||||
|
|
||||||
|
.ci-review-patterns: &ci-review-patterns
|
||||||
|
- ".gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/frontend.gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/build-images.gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/review.gitlab-ci.yml"
|
||||||
|
|
||||||
|
.ci-qa-patterns: &ci-qa-patterns
|
||||||
|
- ".gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/frontend.gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/build-images.gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/qa.gitlab-ci.yml"
|
||||||
|
|
||||||
.yaml-patterns: &yaml-patterns
|
.yaml-patterns: &yaml-patterns
|
||||||
- "**/*.yml"
|
- "**/*.yml"
|
||||||
|
|
||||||
|
@ -92,6 +111,21 @@
|
||||||
- "vendor/assets/**/*"
|
- "vendor/assets/**/*"
|
||||||
- "{,ee/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"
|
- "{,ee/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"
|
||||||
|
|
||||||
|
.backend-patterns: &backend-patterns
|
||||||
|
- "Gemfile{,.lock}"
|
||||||
|
- "Rakefile"
|
||||||
|
- "config.ru"
|
||||||
|
# List explicitly all the app/ dirs that are backend (i.e. all except app/assets).
|
||||||
|
- "{,ee/}{app/channels,app/controllers,app/finders,app/graphql,app/helpers,app/mailers,app/models,app/policies,app/presenters,app/serializers,app/services,app/uploaders,app/validators,app/views,app/workers}/**/*"
|
||||||
|
- "{,ee/}{bin,cable,config,db,lib}/**/*"
|
||||||
|
- "{,ee/}spec/**/*.rb"
|
||||||
|
- ".gitlab-ci.yml"
|
||||||
|
- ".gitlab/ci/**/*"
|
||||||
|
|
||||||
|
.db-patterns: &db-patterns
|
||||||
|
- "{,ee/}{,spec/}{db,migrations}/**/*"
|
||||||
|
- "{,ee/}{,spec/}lib/{,ee/}gitlab/background_migration/**/*"
|
||||||
|
|
||||||
.backstage-patterns: &backstage-patterns
|
.backstage-patterns: &backstage-patterns
|
||||||
- "Dangerfile"
|
- "Dangerfile"
|
||||||
- "danger/**/*"
|
- "danger/**/*"
|
||||||
|
@ -197,6 +231,26 @@
|
||||||
- <<: *if-master-schedule-2-hourly
|
- <<: *if-master-schedule-2-hourly
|
||||||
- <<: *if-merge-request-title-update-caches
|
- <<: *if-merge-request-title-update-caches
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Build images rules #
|
||||||
|
######################
|
||||||
|
.build-images:rules:build-qa-image:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||||
|
changes: *ci-build-images-patterns
|
||||||
|
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||||
|
changes: *code-qa-patterns
|
||||||
|
- <<: *if-dot-com-gitlab-org-schedule
|
||||||
|
|
||||||
|
.build-images:rules:build-assets-image:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-canonical-namespace
|
||||||
|
when: never
|
||||||
|
- changes: *ci-build-images-patterns
|
||||||
|
- changes: *code-qa-patterns
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# Cache repo rules #
|
# Cache repo rules #
|
||||||
####################
|
####################
|
||||||
|
@ -263,7 +317,7 @@
|
||||||
- <<: *if-not-canonical-namespace
|
- <<: *if-not-canonical-namespace
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-default-refs
|
- <<: *if-default-refs
|
||||||
changes: *code-backstage-qa-patterns
|
changes: *code-qa-patterns
|
||||||
|
|
||||||
.frontend:rules:compile-test-assets:
|
.frontend:rules:compile-test-assets:
|
||||||
rules:
|
rules:
|
||||||
|
@ -273,11 +327,8 @@
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-security-merge-request
|
- <<: *if-merge-request # Always run for MRs since `compile-test-assets as-if-foss` is either needed by `rspec foss-impact` or the `rspec * as-if-foss` jobs.
|
||||||
changes: *code-backstage-qa-patterns
|
changes: *code-backstage-qa-patterns
|
||||||
- <<: *if-merge-request-title-as-if-foss
|
|
||||||
- <<: *if-merge-request
|
|
||||||
changes: *ci-patterns
|
|
||||||
|
|
||||||
.frontend:rules:default-frontend-jobs:
|
.frontend:rules:default-frontend-jobs:
|
||||||
rules:
|
rules:
|
||||||
|
@ -294,6 +345,15 @@
|
||||||
- <<: *if-merge-request
|
- <<: *if-merge-request
|
||||||
changes: *ci-patterns
|
changes: *ci-patterns
|
||||||
|
|
||||||
|
.frontend:rules:eslint-as-if-foss:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-merge-request-title-as-if-foss
|
||||||
|
when: never
|
||||||
|
- <<: *if-merge-request
|
||||||
|
changes: *frontend-patterns
|
||||||
|
|
||||||
.frontend:rules:ee-mr-and-master-only:
|
.frontend:rules:ee-mr-and-master-only:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
|
@ -341,9 +401,7 @@
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-dot-com-gitlab-org-master
|
- <<: *if-master-schedule-2-hourly
|
||||||
changes: *code-backstage-qa-patterns
|
|
||||||
when: on_success
|
|
||||||
|
|
||||||
############
|
############
|
||||||
# QA rules #
|
# QA rules #
|
||||||
|
@ -367,7 +425,7 @@
|
||||||
.qa:rules:package-and-qa:
|
.qa:rules:package-and-qa:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||||
changes: *ci-patterns
|
changes: *ci-qa-patterns
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||||
changes: *qa-patterns
|
changes: *qa-patterns
|
||||||
|
@ -382,24 +440,95 @@
|
||||||
###############
|
###############
|
||||||
# Rails rules #
|
# Rails rules #
|
||||||
###############
|
###############
|
||||||
.rails:rules:ee-and-foss:
|
.rails:rules:ee-and-foss-migration:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-default-refs
|
- changes: *db-patterns
|
||||||
changes: *code-backstage-patterns
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:ee-and-foss-unit:
|
||||||
|
rules:
|
||||||
|
- changes: *backend-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:ee-and-foss-integration:
|
||||||
|
rules:
|
||||||
|
- changes: *backend-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:ee-and-foss-system:
|
||||||
|
rules:
|
||||||
|
- changes: *code-backstage-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:ee-and-foss-fast_spec_helper:
|
||||||
|
rules:
|
||||||
|
- changes: ["config/**/*"]
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
.rails:rules:default-refs-code-backstage-qa:
|
.rails:rules:default-refs-code-backstage-qa:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-default-refs
|
- <<: *if-default-refs
|
||||||
changes: *code-backstage-qa-patterns
|
changes: *code-backstage-qa-patterns
|
||||||
|
|
||||||
.rails:rules:ee-only:
|
.rails:rules:ee-only-migration:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-default-refs
|
- changes: *db-patterns
|
||||||
changes: *code-backstage-patterns
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
.rails:rules:as-if-foss:
|
.rails:rules:ee-only-unit:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- changes: *backend-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:ee-only-integration:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- changes: *backend-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:ee-only-system:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- changes: *code-backstage-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:as-if-foss-migration:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-security-merge-request
|
||||||
|
changes: *db-patterns
|
||||||
|
- <<: *if-merge-request-title-as-if-foss
|
||||||
|
- <<: *if-merge-request
|
||||||
|
changes: *ci-patterns
|
||||||
|
|
||||||
|
.rails:rules:as-if-foss-unit:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-security-merge-request
|
||||||
|
changes: *backend-patterns
|
||||||
|
- <<: *if-merge-request-title-as-if-foss
|
||||||
|
- <<: *if-merge-request
|
||||||
|
changes: *ci-patterns
|
||||||
|
|
||||||
|
.rails:rules:as-if-foss-integration:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-security-merge-request
|
||||||
|
changes: *backend-patterns
|
||||||
|
- <<: *if-merge-request-title-as-if-foss
|
||||||
|
- <<: *if-merge-request
|
||||||
|
changes: *ci-patterns
|
||||||
|
|
||||||
|
.rails:rules:as-if-foss-system:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
|
@ -413,6 +542,7 @@
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
- <<: *if-merge-request
|
- <<: *if-merge-request
|
||||||
changes: *code-backstage-patterns
|
changes: *code-backstage-patterns
|
||||||
- <<: *if-master-refs
|
- <<: *if-master-refs
|
||||||
|
@ -434,6 +564,27 @@
|
||||||
- <<: *if-merge-request
|
- <<: *if-merge-request
|
||||||
changes: *code-backstage-patterns
|
changes: *code-backstage-patterns
|
||||||
|
|
||||||
|
.rails:rules:rspec-coverage:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-master-schedule-2-hourly
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:master-schedule-nightly--code-backstage:
|
||||||
|
rules:
|
||||||
|
- <<: *if-master-schedule-nightly
|
||||||
|
- <<: *if-merge-request
|
||||||
|
changes: [".gitlab/ci/rails.gitlab-ci.yml"]
|
||||||
|
|
||||||
|
.rails:rules:master-schedule-nightly--code-backstage-ee-only:
|
||||||
|
rules:
|
||||||
|
- <<: *if-not-ee
|
||||||
|
when: never
|
||||||
|
- <<: *if-master-schedule-nightly
|
||||||
|
- <<: *if-merge-request
|
||||||
|
changes: [".gitlab/ci/rails.gitlab-ci.yml"]
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Releases rules #
|
# Releases rules #
|
||||||
##################
|
##################
|
||||||
|
@ -496,18 +647,12 @@
|
||||||
################
|
################
|
||||||
# Review rules #
|
# Review rules #
|
||||||
################
|
################
|
||||||
.review:rules:build-qa-image:
|
.review:rules:review-build-cng:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
|
||||||
changes: *code-qa-patterns
|
|
||||||
- <<: *if-dot-com-gitlab-org-schedule
|
|
||||||
|
|
||||||
.review:rules:review-build-cng:
|
|
||||||
rules:
|
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *ci-patterns
|
changes: *ci-review-patterns
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *frontend-patterns
|
changes: *frontend-patterns
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
|
@ -521,7 +666,7 @@
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *ci-patterns
|
changes: *ci-review-patterns
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *frontend-patterns
|
changes: *frontend-patterns
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
@ -544,7 +689,7 @@
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
when: never
|
when: never
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *ci-patterns
|
changes: *ci-review-patterns
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *frontend-patterns
|
changes: *frontend-patterns
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
|
@ -9,6 +9,7 @@ cache gems:
|
||||||
stage: test
|
stage: test
|
||||||
needs: ["setup-test-env"]
|
needs: ["setup-test-env"]
|
||||||
variables:
|
variables:
|
||||||
|
BUNDLE_INSTALL_FLAGS: --with=production --with=development --with=test --jobs=2 --path=vendor --retry=3 --quiet
|
||||||
SETUP_DB: "false"
|
SETUP_DB: "false"
|
||||||
script:
|
script:
|
||||||
- bundle package --all --all-platforms
|
- bundle package --all --all-platforms
|
||||||
|
|
|
@ -4,11 +4,11 @@ lint-ci-gitlab:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
- .yaml:rules
|
- .yaml:rules
|
||||||
image: sdesbure/yamllint:latest
|
image: pipelinecomponents/yamllint:latest
|
||||||
stage: test
|
stage: test
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs
|
LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs
|
||||||
script:
|
script:
|
||||||
- '[[ ! -d "ee/" ]] || export LINT_PATHS="$LINT_PATHS ee/changelogs"'
|
- '[[ ! -d "ee/" ]] || export LINT_PATHS="$LINT_PATHS ee/changelogs"'
|
||||||
- yamllint $LINT_PATHS
|
- yamllint -f colored $LINT_PATHS
|
||||||
|
|
|
@ -43,7 +43,14 @@ https://about.gitlab.com/handbook/engineering/ux/ux-research-training/user-story
|
||||||
|
|
||||||
### Permissions and Security
|
### Permissions and Security
|
||||||
|
|
||||||
<!-- What permissions are required to perform the described actions? Are they consistent with the existing permissions as documented for users, groups, and projects as appropriate? Is the proposed behavior consistent between the UI, API, and other access methods (e.g. email replies)?-->
|
<!-- What permissions are required to perform the described actions? Are they consistent with the existing permissions as documented for users, groups, and projects as appropriate? Is the proposed behavior consistent between the UI, API, and other access methods (e.g. email replies)?
|
||||||
|
Consider adding checkboxes and expectations of users with certain levels of membership https://docs.gitlab.com/ee/user/permissions.html
|
||||||
|
* [ ] Add expected impact to members with no access (0)
|
||||||
|
* [ ] Add expected impact to Guest (10) members
|
||||||
|
* [ ] Add expected impact to Reporter (20) members
|
||||||
|
* [ ] Add expected impact to Developer (30) members
|
||||||
|
* [ ] Add expected impact to Maintainer (40) members
|
||||||
|
* [ ] Add expected impact to Owner (50) members -->
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,17 @@ Set the title to: `Description of the original issue`
|
||||||
## Prior to starting the security release work
|
## Prior to starting the security release work
|
||||||
|
|
||||||
- [ ] Read the [security process for developers] if you are not familiar with it.
|
- [ ] Read the [security process for developers] if you are not familiar with it.
|
||||||
- [ ] Mark this [issue as related] to the Security Release tracking issue. You can find it on the topic of the `#releases` Slack channel.
|
- [ ] Mark this [issue as related] to the Security Release Tracking Issue. You can find it on the topic of the `#releases` Slack channel.
|
||||||
- [ ] Run `scripts/security-harness` in your local repository to prevent accidentally pushing to any remote besides `gitlab.com/gitlab-org/security`.
|
|
||||||
- Fill out the [Links section](#links):
|
- Fill out the [Links section](#links):
|
||||||
- [ ] Next to **Issue on GitLab**, add a link to the `gitlab-org/gitlab` issue that describes the security vulnerability.
|
- [ ] Next to **Issue on GitLab**, add a link to the `gitlab-org/gitlab` issue that describes the security vulnerability.
|
||||||
- [ ] Next to **Security Release tracking issue**, add a link to the security release issue that will include this security issue.
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
- [ ] Run `scripts/security-harness` in your local repository to prevent accidentally pushing to any remote besides `gitlab.com/gitlab-org/security`.
|
||||||
- [ ] Create a new branch prefixing it with `security-`.
|
- [ ] Create a new branch prefixing it with `security-`.
|
||||||
- [ ] Create a merge request targeting `master` on `gitlab.com/gitlab-org/security` and use the [Security Release merge request template].
|
- [ ] Create a merge request targeting `master` on `gitlab.com/gitlab-org/security` and use the [Security Release merge request template].
|
||||||
- [ ] Follow the same [code review process]: Assign to a reviewer, then to a maintainer.
|
|
||||||
|
|
||||||
After your merge request has been approved according to our [approval guidelines], you're ready to prepare the backports
|
After your merge request has been approved according to our [approval guidelines] and by a team member of the AppSec team, you're ready to prepare the backports
|
||||||
|
|
||||||
## Backports
|
## Backports
|
||||||
|
|
||||||
|
@ -41,7 +39,6 @@ After your merge request has been approved according to our [approval guidelines
|
||||||
- [ ] Fill in any upgrade notes that users may need to take into account in the [details section](#details)
|
- [ ] Fill in any upgrade notes that users may need to take into account in the [details section](#details)
|
||||||
- [ ] Add Yes/No and further details if needed to the migration and settings columns in the [details section](#details)
|
- [ ] Add Yes/No and further details if needed to the migration and settings columns in the [details section](#details)
|
||||||
- [ ] Add the nickname of the external user who found the issue (and/or HackerOne profile) to the Thanks row in the [details section](#details)
|
- [ ] Add the nickname of the external user who found the issue (and/or HackerOne profile) to the Thanks row in the [details section](#details)
|
||||||
- [ ] Once your `master` MR is merged, comment on the original security issue with a link to that MR indicating the issue is fixed.
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
@ -50,7 +47,6 @@ After your merge request has been approved according to our [approval guidelines
|
||||||
| Description | Link |
|
| Description | Link |
|
||||||
| -------- | -------- |
|
| -------- | -------- |
|
||||||
| Issue on [GitLab](https://gitlab.com/gitlab-org/gitlab/issues) | #TODO |
|
| Issue on [GitLab](https://gitlab.com/gitlab-org/gitlab/issues) | #TODO |
|
||||||
| Security Release tracking issue | #TODO |
|
|
||||||
|
|
||||||
### Details
|
### Details
|
||||||
|
|
||||||
|
@ -64,7 +60,7 @@ After your merge request has been approved according to our [approval guidelines
|
||||||
| Thanks | | |
|
| Thanks | | |
|
||||||
|
|
||||||
[security process for developers]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md
|
[security process for developers]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md
|
||||||
[secpick documentation]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#secpick-script
|
[secpick documentation]: https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/security/utilities/secpick_script.md
|
||||||
[security Release merge request template]: https://gitlab.com/gitlab-org/security/gitlab/blob/master/.gitlab/merge_request_templates/Security%20Release.md
|
[security Release merge request template]: https://gitlab.com/gitlab-org/security/gitlab/blob/master/.gitlab/merge_request_templates/Security%20Release.md
|
||||||
[code review process]: https://docs.gitlab.com/ee/development/code_review.html
|
[code review process]: https://docs.gitlab.com/ee/development/code_review.html
|
||||||
[approval guidelines]: https://docs.gitlab.com/ee/development/code_review.html#approval-guidelines
|
[approval guidelines]: https://docs.gitlab.com/ee/development/code_review.html#approval-guidelines
|
||||||
|
|
|
@ -45,9 +45,11 @@ All reviewers can help ensure accuracy, clarity, completeness, and adherence to
|
||||||
|
|
||||||
**2. Technical Writer**
|
**2. Technical Writer**
|
||||||
|
|
||||||
- [ ] Optional: Technical writer review. If not requested for this MR, must be scheduled post-merge. To request for this MR, assign the writer listed for the applicable [DevOps stage](https://about.gitlab.com/handbook/product/categories/#devops-stages).
|
- [ ] Technical writer review. If not requested for this MR, must be scheduled post-merge. To request for this MR, assign the writer listed for the applicable [DevOps stage](https://about.gitlab.com/handbook/product/product-categories/#devops-stages).
|
||||||
- [ ] Add ~"Technical Writing" and `docs::` workflow label.
|
- [ ] Ensure ~"Technical Writing", ~"documentation", and a `docs::` scoped label are added.
|
||||||
- [ ] Add ~docs-only when the only files changed are under `doc/*`.
|
- [ ] Add ~docs-only when the only files changed are under `doc/*`.
|
||||||
|
- [ ] Add ~"tw::doing" when starting work on the MR.
|
||||||
|
- [ ] Add ~"tw::finished" if Technical Writing team work on the MR is complete but it remains open.
|
||||||
|
|
||||||
**3. Maintainer**
|
**3. Maintainer**
|
||||||
|
|
||||||
|
|
|
@ -13,25 +13,33 @@ See [the general developer security release guidelines](https://gitlab.com/gitla
|
||||||
## Developer checklist
|
## Developer checklist
|
||||||
|
|
||||||
- [ ] **On "Related issues" section, write down the [GitLab Security] issue it belongs to (i.e. `Related to <issue_id>`).**
|
- [ ] **On "Related issues" section, write down the [GitLab Security] issue it belongs to (i.e. `Related to <issue_id>`).**
|
||||||
- [ ] Merge request targets `master`, or `X-Y-stable` for backports.
|
- [ ] Merge request targets `master`, or a versioned stable branch (`X-Y-stable-ee`).
|
||||||
- [ ] Milestone is set for the version this merge request applies to. A closed milestone can be assigned via [quick actions].
|
- [ ] Milestone is set for the version this merge request applies to. A closed milestone can be assigned via [quick actions].
|
||||||
- [ ] Title of this merge request is the same as for all backports.
|
- [ ] Title of this merge request is the same as for all backports.
|
||||||
- [ ] A [CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html) is added without a `merge_request` value, with `type` set to `security`
|
- [ ] A [CHANGELOG entry] is added without a `merge_request` value, with `type` set to `security`
|
||||||
- [ ] Assign to a reviewer and maintainer, per our [Code Review process].
|
|
||||||
- [ ] For the MR targeting `master`:
|
- [ ] For the MR targeting `master`:
|
||||||
- [ ] Ask for a non-blocking review from the AppSec team member associated to the issue in the [Canonical repository](https://gitlab.com/gitlab-org/gitlab). If you're unsure who to ping, ask on `#sec-appsec` Slack channel.
|
- [ ] Assign to a reviewer and maintainer, per our [Code Review process].
|
||||||
- [ ] Ensure it's approved according to our [Approval Guidelines].
|
- [ ] Ensure it's approved according to our [Approval Guidelines].
|
||||||
- [ ] Merge request _must not_ close the corresponding security issue, _unless_ it targets `master`.
|
- [ ] Ensure it's approved by an AppSec engineer.
|
||||||
|
- If you're unsure who should approve, find the AppSec engineer associated to the issue in the [Canonical repository], or ask #sec-appsec on Slack.
|
||||||
|
- Trigger the [`package-and-qa` build]. The docker image generated will be used by the AppSec engineer to validate the security vulnerability has been remediated.
|
||||||
|
- [ ] Merge request _must_ close the corresponding security issue.
|
||||||
|
- [ ] For a backport MR targeting a versioned stable branch (`X-Y-stable-ee`)
|
||||||
|
- [ ] Ensure it's approved by a maintainer.
|
||||||
|
|
||||||
**Note:** Reviewer/maintainer should not be a Release Manager
|
**Note:** Reviewer/maintainer should not be a Release Manager
|
||||||
|
|
||||||
## Maintainer checklist
|
## Maintainer checklist
|
||||||
|
|
||||||
- [ ] Correct milestone is applied and the title is matching across all backports
|
- [ ] Correct milestone is applied and the title is matching across all backports
|
||||||
- [ ] Assigned to `@gitlab-release-tools-bot` with passing CI pipelines and **when all backports including the MR targeting master are ready.**
|
- [ ] Assigned to `@gitlab-release-tools-bot` with passing CI pipelines and **when all backports including the MR targeting master are ready.**
|
||||||
|
|
||||||
/label ~security
|
/label ~security
|
||||||
|
|
||||||
[GitLab Security]: https://gitlab.com/gitlab-org/security/gitlab
|
[GitLab Security]: https://gitlab.com/gitlab-org/security/gitlab
|
||||||
[approval guidelines]: https://docs.gitlab.com/ee/development/code_review.html#approval-guidelines
|
|
||||||
[Code Review process]: https://docs.gitlab.com/ee/development/code_review.html
|
|
||||||
[quick actions]: https://docs.gitlab.com/ee/user/project/quick_actions.html#quick-actions-for-issues-merge-requests-and-epics
|
[quick actions]: https://docs.gitlab.com/ee/user/project/quick_actions.html#quick-actions-for-issues-merge-requests-and-epics
|
||||||
|
[CHANGELOG entry]: https://docs.gitlab.com/ee/development/changelog.html
|
||||||
|
[Code Review process]: https://docs.gitlab.com/ee/development/code_review.html
|
||||||
|
[Approval Guidelines]: https://docs.gitlab.com/ee/development/code_review.html#approval-guidelines
|
||||||
|
[Canonical repository]: https://gitlab.com/gitlab-org/gitlab
|
||||||
|
[`package-and-qa` build]: https://docs.gitlab.com/ee/development/testing_guide/end_to_end/#using-the-package-and-qa-job
|
||||||
|
|
|
@ -8,6 +8,7 @@ exclude:
|
||||||
- 'spec/**/*'
|
- 'spec/**/*'
|
||||||
require:
|
require:
|
||||||
- './haml_lint/linter/no_plain_nodes.rb'
|
- './haml_lint/linter/no_plain_nodes.rb'
|
||||||
|
- './haml_lint/linter/documentation_links.rb'
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
AltText:
|
AltText:
|
||||||
|
@ -26,6 +27,12 @@ linters:
|
||||||
enabled: false
|
enabled: false
|
||||||
max_consecutive: 2
|
max_consecutive: 2
|
||||||
|
|
||||||
|
DocumentationLinks:
|
||||||
|
enabled: true
|
||||||
|
include:
|
||||||
|
- 'app/views/**/*.haml'
|
||||||
|
- 'ee/app/views/**/*.haml'
|
||||||
|
|
||||||
EmptyObjectReference:
|
EmptyObjectReference:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ linters:
|
||||||
- "app/views/admin/hooks/edit.html.haml"
|
- "app/views/admin/hooks/edit.html.haml"
|
||||||
- "app/views/admin/logs/show.html.haml"
|
- "app/views/admin/logs/show.html.haml"
|
||||||
- "app/views/admin/projects/_projects.html.haml"
|
- "app/views/admin/projects/_projects.html.haml"
|
||||||
- "app/views/admin/projects/show.html.haml"
|
|
||||||
- "app/views/admin/requests_profiles/index.html.haml"
|
- "app/views/admin/requests_profiles/index.html.haml"
|
||||||
- "app/views/admin/runners/_runner.html.haml"
|
- "app/views/admin/runners/_runner.html.haml"
|
||||||
- "app/views/admin/runners/index.html.haml"
|
- "app/views/admin/runners/index.html.haml"
|
||||||
|
@ -57,7 +56,6 @@ linters:
|
||||||
- "app/views/admin/spam_logs/_spam_log.html.haml"
|
- "app/views/admin/spam_logs/_spam_log.html.haml"
|
||||||
- "app/views/admin/spam_logs/index.html.haml"
|
- "app/views/admin/spam_logs/index.html.haml"
|
||||||
- "app/views/admin/system_info/show.html.haml"
|
- "app/views/admin/system_info/show.html.haml"
|
||||||
- "app/views/admin/users/_access_levels.html.haml"
|
|
||||||
- "app/views/admin/users/_form.html.haml"
|
- "app/views/admin/users/_form.html.haml"
|
||||||
- "app/views/admin/users/_head.html.haml"
|
- "app/views/admin/users/_head.html.haml"
|
||||||
- "app/views/admin/users/_profile.html.haml"
|
- "app/views/admin/users/_profile.html.haml"
|
||||||
|
@ -280,7 +278,6 @@ linters:
|
||||||
- "app/views/shared/_no_password.html.haml"
|
- "app/views/shared/_no_password.html.haml"
|
||||||
- "app/views/shared/_ping_consent.html.haml"
|
- "app/views/shared/_ping_consent.html.haml"
|
||||||
- "app/views/shared/_project_limit.html.haml"
|
- "app/views/shared/_project_limit.html.haml"
|
||||||
- "app/views/shared/boards/components/_board.html.haml"
|
|
||||||
- "app/views/shared/boards/components/_sidebar.html.haml"
|
- "app/views/shared/boards/components/_sidebar.html.haml"
|
||||||
- "app/views/shared/boards/components/sidebar/_due_date.html.haml"
|
- "app/views/shared/boards/components/sidebar/_due_date.html.haml"
|
||||||
- "app/views/shared/boards/components/sidebar/_labels.html.haml"
|
- "app/views/shared/boards/components/sidebar/_labels.html.haml"
|
||||||
|
@ -358,7 +355,6 @@ linters:
|
||||||
- "ee/app/views/notify/unapproved_merge_request_email.html.haml"
|
- "ee/app/views/notify/unapproved_merge_request_email.html.haml"
|
||||||
- "ee/app/views/oauth/geo_auth/error.html.haml"
|
- "ee/app/views/oauth/geo_auth/error.html.haml"
|
||||||
- "ee/app/views/projects/commits/_mirror_status.html.haml"
|
- "ee/app/views/projects/commits/_mirror_status.html.haml"
|
||||||
- "ee/app/views/projects/jobs/_shared_runner_limit_warning.html.haml"
|
|
||||||
- "ee/app/views/projects/merge_requests/_approvals_count.html.haml"
|
- "ee/app/views/projects/merge_requests/_approvals_count.html.haml"
|
||||||
- "ee/app/views/projects/merge_requests/widget/open/_geo.html.haml"
|
- "ee/app/views/projects/merge_requests/widget/open/_geo.html.haml"
|
||||||
- "ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml"
|
- "ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml"
|
||||||
|
@ -372,7 +368,6 @@ linters:
|
||||||
- "ee/app/views/projects/services/gitlab_slack_application/_slack_integration_form.html.haml"
|
- "ee/app/views/projects/services/gitlab_slack_application/_slack_integration_form.html.haml"
|
||||||
- "ee/app/views/projects/settings/slacks/edit.html.haml"
|
- "ee/app/views/projects/settings/slacks/edit.html.haml"
|
||||||
- "ee/app/views/shared/_mirror_update_button.html.haml"
|
- "ee/app/views/shared/_mirror_update_button.html.haml"
|
||||||
- "ee/app/views/shared/boards/components/_list_weight.html.haml"
|
|
||||||
- "ee/app/views/shared/epic/_search_bar.html.haml"
|
- "ee/app/views/shared/epic/_search_bar.html.haml"
|
||||||
- "ee/app/views/shared/issuable/_approvals.html.haml"
|
- "ee/app/views/shared/issuable/_approvals.html.haml"
|
||||||
- "ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml"
|
- "ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml"
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
"Jira Cloud",
|
"Jira Cloud",
|
||||||
"Jira Server",
|
"Jira Server",
|
||||||
"jQuery",
|
"jQuery",
|
||||||
|
"JSON",
|
||||||
"JupyterHub",
|
"JupyterHub",
|
||||||
"Karma",
|
"Karma",
|
||||||
"Kerberos",
|
"Kerberos",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
/public/
|
/public/
|
||||||
/vendor/
|
/vendor/
|
||||||
/tmp/
|
/tmp/
|
||||||
|
doc/api/graphql/reference/gitlab_schema.graphql
|
||||||
|
|
||||||
# ignore stylesheets for now as this clashes with our linter
|
# ignore stylesheets for now as this clashes with our linter
|
||||||
*.css
|
*.css
|
||||||
|
|
22
.rubocop.yml
22
.rubocop.yml
|
@ -308,6 +308,18 @@ Gitlab/Union:
|
||||||
- 'spec/**/*'
|
- 'spec/**/*'
|
||||||
- 'ee/spec/**/*'
|
- 'ee/spec/**/*'
|
||||||
|
|
||||||
|
API/GrapeAPIInstance:
|
||||||
|
Enabled: true
|
||||||
|
Include:
|
||||||
|
- 'lib/**/api/**/*.rb'
|
||||||
|
- 'ee/**/api/**/*.rb'
|
||||||
|
|
||||||
|
API/GrapeArrayMissingCoerce:
|
||||||
|
Enabled: true
|
||||||
|
Include:
|
||||||
|
- 'lib/**/api/**/*.rb'
|
||||||
|
- 'ee/**/api/**/*.rb'
|
||||||
|
|
||||||
Cop/SidekiqOptionsQueue:
|
Cop/SidekiqOptionsQueue:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Exclude:
|
Exclude:
|
||||||
|
@ -316,6 +328,9 @@ Cop/SidekiqOptionsQueue:
|
||||||
|
|
||||||
Graphql/AuthorizeTypes:
|
Graphql/AuthorizeTypes:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
Include:
|
||||||
|
- 'app/graphql/types/**/*'
|
||||||
|
- 'ee/app/graphql/types/**/*'
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'spec/**/*.rb'
|
- 'spec/**/*.rb'
|
||||||
- 'ee/spec/**/*.rb'
|
- 'ee/spec/**/*.rb'
|
||||||
|
@ -450,10 +465,17 @@ Rails/TimeZone:
|
||||||
- 'spec/models/**/*'
|
- 'spec/models/**/*'
|
||||||
- 'ee/app/models/**/*'
|
- 'ee/app/models/**/*'
|
||||||
- 'ee/spec/models/**/*'
|
- 'ee/spec/models/**/*'
|
||||||
|
- 'app/workers/**/*'
|
||||||
|
- 'spec/workers/**/*'
|
||||||
|
- 'ee/app/workers/**/*'
|
||||||
|
- 'ee/spec/workers/**/*'
|
||||||
|
|
||||||
|
|
||||||
# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
|
# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
|
||||||
Rails/SaveBang:
|
Rails/SaveBang:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
AllowImplicitReturn: false
|
||||||
|
AllowedReceivers: ['ActionDispatch::TestRequest']
|
||||||
Include:
|
Include:
|
||||||
- 'spec/**/*.rb'
|
- 'spec/**/*.rb'
|
||||||
- 'ee/spec/**/*.rb'
|
- 'ee/spec/**/*.rb'
|
||||||
|
|
|
@ -303,6 +303,11 @@ Performance/Detect:
|
||||||
RSpec/ContextWording:
|
RSpec/ContextWording:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 626
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
RSpec/EmptyLineAfterLetBlock:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 1121
|
# Offense count: 1121
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
@ -560,30 +565,6 @@ Style/GuardClause:
|
||||||
Style/HashEachMethods:
|
Style/HashEachMethods:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 6
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/HashTransformKeys:
|
|
||||||
Exclude:
|
|
||||||
- 'ee/app/models/vulnerabilities/occurrence.rb'
|
|
||||||
- 'ee/spec/lib/gitlab/ci/templates/dependency_scanning_gitlab_ci_yaml_spec.rb'
|
|
||||||
- 'lib/banzai/filter/commit_trailers_filter.rb'
|
|
||||||
- 'lib/gitlab/analytics/cycle_analytics/stage_events.rb'
|
|
||||||
|
|
||||||
# Offense count: 10
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/HashTransformValues:
|
|
||||||
Exclude:
|
|
||||||
- 'app/validators/addressable_url_validator.rb'
|
|
||||||
- 'config/initializers/action_dispatch_journey_formatter.rb'
|
|
||||||
- 'ee/app/helpers/compliance_management/compliance_framework/project_settings_helper.rb'
|
|
||||||
- 'ee/app/services/packages/nuget/metadata_extraction_service.rb'
|
|
||||||
- 'lib/gitlab/config/entry/configurable.rb'
|
|
||||||
- 'lib/gitlab/config/entry/node.rb'
|
|
||||||
- 'lib/gitlab/discussions_diff/file_collection.rb'
|
|
||||||
- 'lib/gitlab/error_tracking.rb'
|
|
||||||
- 'lib/rspec_flaky/flaky_examples_collection.rb'
|
|
||||||
- 'spec/lib/gitlab/database_importers/common_metrics/prometheus_metric_spec.rb'
|
|
||||||
|
|
||||||
# Offense count: 31
|
# Offense count: 31
|
||||||
# Configuration parameters: AllowIfModifier.
|
# Configuration parameters: AllowIfModifier.
|
||||||
Style/IfInsideElse:
|
Style/IfInsideElse:
|
||||||
|
@ -639,12 +620,122 @@ Style/Next:
|
||||||
Style/NumericLiteralPrefix:
|
Style/NumericLiteralPrefix:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 255
|
# Offense count: 130
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
|
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
|
||||||
# SupportedStyles: predicate, comparison
|
# SupportedStyles: predicate, comparison
|
||||||
|
# We use EnforcedStyle of comparison here due to it being better
|
||||||
|
# performing code as seen https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36221#note_375659681
|
||||||
Style/NumericPredicate:
|
Style/NumericPredicate:
|
||||||
Enabled: false
|
EnforcedStyle: comparison
|
||||||
|
Exclude:
|
||||||
|
- 'spec/**/*'
|
||||||
|
- 'app/views/**/*'
|
||||||
|
- 'ee/app/views/**/*'
|
||||||
|
- 'app/controllers/concerns/issuable_collections.rb'
|
||||||
|
- 'app/controllers/concerns/paginated_collection.rb'
|
||||||
|
- 'app/helpers/graph_helper.rb'
|
||||||
|
- 'app/helpers/timeboxes_helper.rb'
|
||||||
|
- 'app/models/ci/pipeline.rb'
|
||||||
|
- 'app/models/ci/stage.rb'
|
||||||
|
- 'app/models/concerns/update_project_statistics.rb'
|
||||||
|
- 'app/models/merge_request_diff.rb'
|
||||||
|
- 'app/models/milestone.rb'
|
||||||
|
- 'app/models/network/graph.rb'
|
||||||
|
- 'app/models/postgresql/replication_slot.rb'
|
||||||
|
- 'app/models/project.rb'
|
||||||
|
- 'app/models/suggestion.rb'
|
||||||
|
- 'app/models/user.rb'
|
||||||
|
- 'app/serializers/merge_request_widget_entity.rb'
|
||||||
|
- 'app/services/boards/issues/move_service.rb'
|
||||||
|
- 'app/services/cohorts_service.rb'
|
||||||
|
- 'app/services/discussions/resolve_service.rb'
|
||||||
|
- 'app/services/issues/reorder_service.rb'
|
||||||
|
- 'app/services/notes/create_service.rb'
|
||||||
|
- 'app/services/packages/nuget/metadata_extraction_service.rb'
|
||||||
|
- 'app/services/packages/nuget/search_service.rb'
|
||||||
|
- 'app/services/projects/auto_devops/disable_service.rb'
|
||||||
|
- 'app/services/projects/update_pages_service.rb'
|
||||||
|
- 'app/services/search_service.rb'
|
||||||
|
- 'app/workers/admin_email_worker.rb'
|
||||||
|
- 'app/workers/gitlab/import/advance_stage.rb'
|
||||||
|
- 'config/initializers/validate_puma.rb'
|
||||||
|
- 'ee/app/controllers/security/projects_controller.rb'
|
||||||
|
- 'ee/app/graphql/mutations/instance_security_dashboard/remove_project.rb'
|
||||||
|
- 'ee/app/helpers/ee/timeboxes_helper.rb'
|
||||||
|
- 'ee/app/models/ci/minutes/quota.rb'
|
||||||
|
- 'ee/app/models/ee/ci/runner.rb'
|
||||||
|
- 'ee/app/models/geo_node_status.rb'
|
||||||
|
- 'ee/app/models/license.rb'
|
||||||
|
- 'ee/app/models/namespace_statistics.rb'
|
||||||
|
- 'ee/app/services/ee/issues/base_service.rb'
|
||||||
|
- 'ee/app/services/ee/merge_requests/approval_service.rb'
|
||||||
|
- 'ee/app/services/ee/quick_actions/target_service.rb'
|
||||||
|
- 'ee/app/services/elastic/indexing_control_service.rb'
|
||||||
|
- 'ee/app/services/geo/hashed_storage_migration_service.rb'
|
||||||
|
- 'ee/app/services/geo/prune_event_log_service.rb'
|
||||||
|
- 'ee/app/services/security/waf_anomaly_summary_service.rb'
|
||||||
|
- 'ee/app/services/update_build_minutes_service.rb'
|
||||||
|
- 'ee/app/workers/geo/container_repository_sync_dispatch_worker.rb'
|
||||||
|
- 'ee/app/workers/geo/file_download_dispatch_worker.rb'
|
||||||
|
- 'ee/app/workers/geo/registry_sync_worker.rb'
|
||||||
|
- 'ee/app/workers/geo/repository_shard_sync_worker.rb'
|
||||||
|
- 'ee/app/workers/geo/repository_verification/primary/shard_worker.rb'
|
||||||
|
- 'ee/lib/api/helpers/packages/conan/api_helpers.rb'
|
||||||
|
- 'ee/lib/ee/gitlab/auth/ldap/person.rb'
|
||||||
|
- 'ee/lib/ee/gitlab/background_migration/prune_orphaned_geo_events.rb'
|
||||||
|
- 'ee/lib/ee/gitlab/checks/push_rules/file_size_check.rb'
|
||||||
|
- 'ee/lib/ee/gitlab/geo_git_access.rb'
|
||||||
|
- 'ee/lib/gitlab/geo/fdw.rb'
|
||||||
|
- 'ee/lib/gitlab/geo/log_cursor/lease.rb'
|
||||||
|
- 'ee/lib/tasks/gitlab/elastic.rake'
|
||||||
|
- 'lib/api/entities/feature.rb'
|
||||||
|
- 'lib/api/helpers/pagination_strategies.rb'
|
||||||
|
- 'lib/backup/files.rb'
|
||||||
|
- 'lib/banzai/filter/gollum_tags_filter.rb'
|
||||||
|
- 'lib/bitbucket_server/paginator.rb'
|
||||||
|
- 'lib/declarative_policy/runner.rb'
|
||||||
|
- 'lib/gitlab/auth/ldap/adapter.rb'
|
||||||
|
- 'lib/gitlab/bare_repository_import/importer.rb'
|
||||||
|
- 'lib/gitlab/ci/config/external/context.rb'
|
||||||
|
- 'lib/gitlab/ci/reports/accessibility_reports_comparer.rb'
|
||||||
|
- 'lib/gitlab/cycle_analytics/summary/value.rb'
|
||||||
|
- 'lib/gitlab/cycle_analytics/summary_helper.rb'
|
||||||
|
- 'lib/gitlab/danger/teammate.rb'
|
||||||
|
- 'lib/gitlab/database.rb'
|
||||||
|
- 'lib/gitlab/database/connection_timer.rb'
|
||||||
|
- 'lib/gitlab/database/migration_helpers.rb'
|
||||||
|
- 'lib/gitlab/exclusive_lease.rb'
|
||||||
|
- 'lib/gitlab/exclusive_lease_helpers/sleeping_lock.rb'
|
||||||
|
- 'lib/gitlab/experimentation.rb'
|
||||||
|
- 'lib/gitlab/file_hook.rb'
|
||||||
|
- 'lib/gitlab/git/commit.rb'
|
||||||
|
- 'lib/gitlab/git/repository.rb'
|
||||||
|
- 'lib/gitlab/git/rugged_impl/blob.rb'
|
||||||
|
- 'lib/gitlab/gitaly_client.rb'
|
||||||
|
- 'lib/gitlab/github_import/user_finder.rb'
|
||||||
|
- 'lib/gitlab/hashed_storage/migrator.rb'
|
||||||
|
- 'lib/gitlab/import_export/command_line_util.rb'
|
||||||
|
- 'lib/gitlab/multi_collection_paginator.rb'
|
||||||
|
- 'lib/gitlab/polling_interval.rb'
|
||||||
|
- 'lib/gitlab/project_search_results.rb'
|
||||||
|
- 'lib/gitlab/seeder.rb'
|
||||||
|
- 'lib/gitlab/sidekiq_cluster.rb'
|
||||||
|
- 'lib/gitlab/sidekiq_daemon/memory_killer.rb'
|
||||||
|
- 'lib/gitlab/sidekiq_middleware/memory_killer.rb'
|
||||||
|
- 'lib/gitlab/sidekiq_status.rb'
|
||||||
|
- 'lib/gitlab/slash_commands/presenters/issue_show.rb'
|
||||||
|
- 'lib/gitlab/task_helpers.rb'
|
||||||
|
- 'lib/gitlab/untrusted_regexp.rb'
|
||||||
|
- 'lib/gitlab/utils.rb'
|
||||||
|
- 'lib/system_check/sidekiq_check.rb'
|
||||||
|
- 'lib/tasks/gitlab/gitaly.rake'
|
||||||
|
- 'lib/tasks/gitlab/snippets.rake'
|
||||||
|
- 'lib/tasks/gitlab/workhorse.rake'
|
||||||
|
- 'qa/qa/git/repository.rb'
|
||||||
|
- 'qa/qa/support/wait_for_requests.rb'
|
||||||
|
- 'ee/app/models/ee/project.rb'
|
||||||
|
- 'lib/gitlab/usage_data/topology.rb'
|
||||||
|
|
||||||
# Offense count: 117
|
# Offense count: 117
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
|
@ -690,18 +781,6 @@ Style/RedundantFreeze:
|
||||||
Style/RedundantInterpolation:
|
Style/RedundantInterpolation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 6
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/RedundantParentheses:
|
|
||||||
Exclude:
|
|
||||||
- 'ee/app/models/ee/merge_request.rb'
|
|
||||||
|
|
||||||
# Offense count: 33
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
# Configuration parameters: AllowMultipleReturnValues.
|
|
||||||
Style/RedundantReturn:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 801
|
# Offense count: 801
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/RedundantSelf:
|
Style/RedundantSelf:
|
||||||
|
@ -711,8 +790,8 @@ Style/RedundantSelf:
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/RedundantSort:
|
Style/RedundantSort:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'ee/app/presenters/packages/nuget/search_results_presenter.rb'
|
- 'app/presenters/packages/nuget/search_results_presenter.rb'
|
||||||
- 'ee/spec/presenters/packages/nuget/search_results_presenter_spec.rb'
|
- 'spec/presenters/packages/nuget/search_results_presenter_spec.rb'
|
||||||
|
|
||||||
# Offense count: 120
|
# Offense count: 120
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
|
@ -769,25 +848,20 @@ Style/StringLiteralsInInterpolation:
|
||||||
Style/SymbolProc:
|
Style/SymbolProc:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 1478
|
# Offense count: 2362
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AllowImplicitReturn, AllowedReceivers.
|
# Configuration parameters: AllowImplicitReturn, AllowedReceivers.
|
||||||
Rails/SaveBang:
|
Rails/SaveBang:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'ee/spec/controllers/groups/epic_issues_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/groups/epic_links_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/groups/epics_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/groups/roadmap_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/projects/environments_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/projects/issues_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/projects/merge_requests/creations_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
|
- 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
|
||||||
- 'ee/spec/controllers/projects/service_desk_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/projects/subscriptions_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
|
|
||||||
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
|
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
|
||||||
|
- 'ee/spec/factories/ci/job_artifacts.rb'
|
||||||
|
- 'ee/spec/factories/epics.rb'
|
||||||
|
- 'ee/spec/factories/licenses.rb'
|
||||||
- 'ee/spec/factories/merge_requests.rb'
|
- 'ee/spec/factories/merge_requests.rb'
|
||||||
|
- 'ee/spec/features/admin/admin_users_spec.rb'
|
||||||
- 'ee/spec/features/admin/geo/admin_geo_nodes_spec.rb'
|
- 'ee/spec/features/admin/geo/admin_geo_nodes_spec.rb'
|
||||||
|
- 'ee/spec/features/admin/licenses/admin_views_license_spec.rb'
|
||||||
- 'ee/spec/features/boards/scoped_issue_board_spec.rb'
|
- 'ee/spec/features/boards/scoped_issue_board_spec.rb'
|
||||||
- 'ee/spec/features/ci_shared_runner_warnings_spec.rb'
|
- 'ee/spec/features/ci_shared_runner_warnings_spec.rb'
|
||||||
- 'ee/spec/features/dashboards/operations_spec.rb'
|
- 'ee/spec/features/dashboards/operations_spec.rb'
|
||||||
|
@ -796,13 +870,19 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
|
- 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
|
||||||
- 'ee/spec/features/projects/members/invite_group_and_members_spec.rb'
|
- 'ee/spec/features/projects/members/invite_group_and_members_spec.rb'
|
||||||
- 'ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb'
|
- 'ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb'
|
||||||
|
- 'ee/spec/features/projects/mirror_spec.rb'
|
||||||
- 'ee/spec/features/projects/new_project_spec.rb'
|
- 'ee/spec/features/projects/new_project_spec.rb'
|
||||||
- 'ee/spec/features/projects/settings/user_manages_approval_settings_spec.rb'
|
- 'ee/spec/features/projects/settings/user_manages_approval_settings_spec.rb'
|
||||||
- 'ee/spec/features/projects/settings/user_manages_members_spec.rb'
|
- 'ee/spec/features/projects/settings/user_manages_members_spec.rb'
|
||||||
- 'ee/spec/features/search/elastic/global_search_spec.rb'
|
- 'ee/spec/features/search/elastic/global_search_spec.rb'
|
||||||
|
- 'ee/spec/features/security/project/internal_access_spec.rb'
|
||||||
|
- 'ee/spec/features/security/project/public_access_spec.rb'
|
||||||
- 'ee/spec/finders/epics_finder_spec.rb'
|
- 'ee/spec/finders/epics_finder_spec.rb'
|
||||||
|
- 'ee/spec/finders/security/vulnerabilities_finder_spec.rb'
|
||||||
- 'ee/spec/frontend/fixtures/analytics.rb'
|
- 'ee/spec/frontend/fixtures/analytics.rb'
|
||||||
|
- 'ee/spec/graphql/resolvers/vulnerabilities_resolver_spec.rb'
|
||||||
- 'ee/spec/helpers/application_helper_spec.rb'
|
- 'ee/spec/helpers/application_helper_spec.rb'
|
||||||
|
- 'ee/spec/helpers/ee/dashboard_helper_spec.rb'
|
||||||
- 'ee/spec/helpers/ee/issues_helper_spec.rb'
|
- 'ee/spec/helpers/ee/issues_helper_spec.rb'
|
||||||
- 'ee/spec/initializers/fog_google_https_private_urls_spec.rb'
|
- 'ee/spec/initializers/fog_google_https_private_urls_spec.rb'
|
||||||
- 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb'
|
- 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb'
|
||||||
|
@ -811,60 +891,84 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/lib/ee/gitlab/background_migration/move_epic_issues_after_epics_spec.rb'
|
- 'ee/spec/lib/ee/gitlab/background_migration/move_epic_issues_after_epics_spec.rb'
|
||||||
- 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_merge_requests_spec.rb'
|
- 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_merge_requests_spec.rb'
|
||||||
- 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_projects_spec.rb'
|
- 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_projects_spec.rb'
|
||||||
|
- 'ee/spec/lib/ee/gitlab/background_migration/prune_orphaned_geo_events_spec.rb'
|
||||||
- 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb'
|
- 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb'
|
||||||
- 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb'
|
- 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb'
|
- 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb'
|
- 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/auth/saml/user_spec.rb'
|
- 'ee/spec/lib/gitlab/auth/saml/user_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/background_migration/fix_orphan_promoted_issues_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/elastic/search_results_spec.rb'
|
- 'ee/spec/lib/gitlab/elastic/search_results_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb'
|
- 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/cron_manager_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb'
|
- 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
|
- 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/geo_spec.rb'
|
- 'ee/spec/lib/gitlab/geo_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/git_access_spec.rb'
|
- 'ee/spec/lib/gitlab/git_access_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/mirror_spec.rb'
|
||||||
- 'ee/spec/mailers/notify_spec.rb'
|
- 'ee/spec/mailers/notify_spec.rb'
|
||||||
|
- 'ee/spec/migrations/fix_any_approver_rule_for_projects_spec.rb'
|
||||||
- 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb'
|
- 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb'
|
||||||
- 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb'
|
- 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb'
|
||||||
|
- 'ee/spec/migrations/schedule_merge_request_any_approval_rule_migration_spec.rb'
|
||||||
- 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb'
|
- 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb'
|
||||||
- 'ee/spec/models/application_setting_spec.rb'
|
- 'ee/spec/models/application_setting_spec.rb'
|
||||||
- 'ee/spec/models/approval_merge_request_rule_spec.rb'
|
- 'ee/spec/models/approval_merge_request_rule_spec.rb'
|
||||||
|
- 'ee/spec/models/approval_project_rule_spec.rb'
|
||||||
- 'ee/spec/models/approval_state_spec.rb'
|
- 'ee/spec/models/approval_state_spec.rb'
|
||||||
- 'ee/spec/models/burndown_spec.rb'
|
- 'ee/spec/models/burndown_spec.rb'
|
||||||
- 'ee/spec/models/ci/build_spec.rb'
|
- 'ee/spec/models/ci/build_spec.rb'
|
||||||
- 'ee/spec/models/ci/pipeline_spec.rb'
|
- 'ee/spec/models/ci/pipeline_spec.rb'
|
||||||
- 'ee/spec/models/ci/subscriptions/project_spec.rb'
|
- 'ee/spec/models/ci/subscriptions/project_spec.rb'
|
||||||
|
- 'ee/spec/models/concerns/approver_migrate_hook_spec.rb'
|
||||||
- 'ee/spec/models/concerns/deprecated_approvals_before_merge_spec.rb'
|
- 'ee/spec/models/concerns/deprecated_approvals_before_merge_spec.rb'
|
||||||
- 'ee/spec/models/concerns/elastic/note_spec.rb'
|
- 'ee/spec/models/concerns/elastic/note_spec.rb'
|
||||||
|
- 'ee/spec/models/ee/appearance_spec.rb'
|
||||||
|
- 'ee/spec/models/ee/ci/job_artifact_spec.rb'
|
||||||
- 'ee/spec/models/ee/protected_branch_spec.rb'
|
- 'ee/spec/models/ee/protected_branch_spec.rb'
|
||||||
- 'ee/spec/models/ee/protected_ref_access_spec.rb'
|
- 'ee/spec/models/ee/protected_ref_access_spec.rb'
|
||||||
- 'ee/spec/models/ee/protected_ref_spec.rb'
|
- 'ee/spec/models/ee/protected_ref_spec.rb'
|
||||||
|
- 'ee/spec/models/elasticsearch_indexed_namespace_spec.rb'
|
||||||
|
- 'ee/spec/models/environment_spec.rb'
|
||||||
- 'ee/spec/models/epic_spec.rb'
|
- 'ee/spec/models/epic_spec.rb'
|
||||||
- 'ee/spec/models/geo/project_registry_spec.rb'
|
- 'ee/spec/models/geo/project_registry_spec.rb'
|
||||||
- 'ee/spec/models/geo_node_spec.rb'
|
- 'ee/spec/models/geo_node_spec.rb'
|
||||||
- 'ee/spec/models/geo_node_status_spec.rb'
|
- 'ee/spec/models/geo_node_status_spec.rb'
|
||||||
|
- 'ee/spec/models/gitlab_subscription_spec.rb'
|
||||||
- 'ee/spec/models/group_spec.rb'
|
- 'ee/spec/models/group_spec.rb'
|
||||||
- 'ee/spec/models/issue_spec.rb'
|
- 'ee/spec/models/issue_spec.rb'
|
||||||
- 'ee/spec/models/label_note_spec.rb'
|
- 'ee/spec/models/label_note_spec.rb'
|
||||||
|
- 'ee/spec/models/lfs_object_spec.rb'
|
||||||
- 'ee/spec/models/license_spec.rb'
|
- 'ee/spec/models/license_spec.rb'
|
||||||
- 'ee/spec/models/merge_request_spec.rb'
|
- 'ee/spec/models/merge_request_spec.rb'
|
||||||
|
- 'ee/spec/models/merge_train_spec.rb'
|
||||||
- 'ee/spec/models/operations/feature_flag_scope_spec.rb'
|
- 'ee/spec/models/operations/feature_flag_scope_spec.rb'
|
||||||
- 'ee/spec/models/operations/feature_flag_spec.rb'
|
- 'ee/spec/models/operations/feature_flag_spec.rb'
|
||||||
- 'ee/spec/models/operations/feature_flags/strategy_spec.rb'
|
- 'ee/spec/models/operations/feature_flags/strategy_spec.rb'
|
||||||
- 'ee/spec/models/operations/feature_flags/user_list_spec.rb'
|
- 'ee/spec/models/operations/feature_flags/user_list_spec.rb'
|
||||||
|
- 'spec/models/packages/package_spec.rb'
|
||||||
|
- 'ee/spec/models/project_ci_cd_setting_spec.rb'
|
||||||
- 'ee/spec/models/project_services/github_service_spec.rb'
|
- 'ee/spec/models/project_services/github_service_spec.rb'
|
||||||
- 'ee/spec/models/project_services/jenkins_service_spec.rb'
|
- 'ee/spec/models/project_services/jenkins_service_spec.rb'
|
||||||
- 'ee/spec/models/project_spec.rb'
|
- 'ee/spec/models/project_spec.rb'
|
||||||
|
- 'ee/spec/models/protected_environment_spec.rb'
|
||||||
|
- 'ee/spec/models/repository_spec.rb'
|
||||||
- 'ee/spec/models/scim_identity_spec.rb'
|
- 'ee/spec/models/scim_identity_spec.rb'
|
||||||
- 'ee/spec/models/scim_oauth_access_token_spec.rb'
|
- 'ee/spec/models/scim_oauth_access_token_spec.rb'
|
||||||
|
- 'ee/spec/models/upload_spec.rb'
|
||||||
- 'ee/spec/models/user_preference_spec.rb'
|
- 'ee/spec/models/user_preference_spec.rb'
|
||||||
- 'ee/spec/models/user_spec.rb'
|
- 'ee/spec/models/user_spec.rb'
|
||||||
- 'ee/spec/models/visible_approvable_spec.rb'
|
- 'ee/spec/models/visible_approvable_spec.rb'
|
||||||
- 'ee/spec/models/vulnerabilities/feedback_spec.rb'
|
- 'ee/spec/models/vulnerabilities/feedback_spec.rb'
|
||||||
- 'ee/spec/models/vulnerabilities/issue_link_spec.rb'
|
- 'ee/spec/models/vulnerabilities/issue_link_spec.rb'
|
||||||
|
- 'ee/spec/policies/group_policy_spec.rb'
|
||||||
|
- 'ee/spec/policies/note_policy_spec.rb'
|
||||||
|
- 'ee/spec/policies/project_policy_spec.rb'
|
||||||
- 'ee/spec/policies/protected_branch_policy_spec.rb'
|
- 'ee/spec/policies/protected_branch_policy_spec.rb'
|
||||||
|
- 'ee/spec/policies/vulnerabilities/feedback_policy_spec.rb'
|
||||||
- 'ee/spec/presenters/audit_event_presenter_spec.rb'
|
- 'ee/spec/presenters/audit_event_presenter_spec.rb'
|
||||||
- 'ee/spec/presenters/epic_presenter_spec.rb'
|
- 'ee/spec/presenters/epic_presenter_spec.rb'
|
||||||
- 'ee/spec/presenters/packages/conan/package_presenter_spec.rb'
|
|
||||||
- 'ee/spec/requests/api/boards_spec.rb'
|
- 'ee/spec/requests/api/boards_spec.rb'
|
||||||
- 'ee/spec/requests/api/epic_issues_spec.rb'
|
- 'ee/spec/requests/api/epic_issues_spec.rb'
|
||||||
- 'ee/spec/requests/api/epic_links_spec.rb'
|
- 'ee/spec/requests/api/epic_links_spec.rb'
|
||||||
|
@ -876,7 +980,6 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/requests/api/groups_spec.rb'
|
- 'ee/spec/requests/api/groups_spec.rb'
|
||||||
- 'ee/spec/requests/api/issues_spec.rb'
|
- 'ee/spec/requests/api/issues_spec.rb'
|
||||||
- 'ee/spec/requests/api/ldap_group_links_spec.rb'
|
- 'ee/spec/requests/api/ldap_group_links_spec.rb'
|
||||||
- 'ee/spec/requests/api/maven_packages_spec.rb'
|
|
||||||
- 'ee/spec/requests/api/merge_request_approval_rules_spec.rb'
|
- 'ee/spec/requests/api/merge_request_approval_rules_spec.rb'
|
||||||
- 'ee/spec/requests/api/merge_request_approvals_spec.rb'
|
- 'ee/spec/requests/api/merge_request_approvals_spec.rb'
|
||||||
- 'ee/spec/requests/api/merge_requests_spec.rb'
|
- 'ee/spec/requests/api/merge_requests_spec.rb'
|
||||||
|
@ -885,9 +988,15 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/requests/api/protected_branches_spec.rb'
|
- 'ee/spec/requests/api/protected_branches_spec.rb'
|
||||||
- 'ee/spec/requests/api/scim_spec.rb'
|
- 'ee/spec/requests/api/scim_spec.rb'
|
||||||
- 'ee/spec/requests/api/todos_spec.rb'
|
- 'ee/spec/requests/api/todos_spec.rb'
|
||||||
|
- 'ee/spec/requests/lfs_http_spec.rb'
|
||||||
- 'ee/spec/services/approval_rules/finalize_service_spec.rb'
|
- 'ee/spec/services/approval_rules/finalize_service_spec.rb'
|
||||||
|
- 'ee/spec/services/approval_rules/update_service_spec.rb'
|
||||||
|
- 'ee/spec/services/ci/minutes/email_notification_service_spec.rb'
|
||||||
|
- 'ee/spec/services/ci/process_build_service_spec.rb'
|
||||||
- 'ee/spec/services/ci/register_job_service_spec.rb'
|
- 'ee/spec/services/ci/register_job_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/boards/issues/create_service_spec.rb'
|
- 'ee/spec/services/ee/boards/issues/create_service_spec.rb'
|
||||||
|
- 'ee/spec/services/ee/boards/issues/list_service_spec.rb'
|
||||||
|
- 'ee/spec/services/ee/boards/lists/list_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb'
|
- 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb'
|
||||||
- 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb'
|
- 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/issues/update_service_spec.rb'
|
- 'ee/spec/services/ee/issues/update_service_spec.rb'
|
||||||
|
@ -896,13 +1005,15 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/services/ee/notes/quick_actions_service_spec.rb'
|
- 'ee/spec/services/ee/notes/quick_actions_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/notification_service_spec.rb'
|
- 'ee/spec/services/ee/notification_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/resource_events/change_weight_service_spec.rb'
|
- 'ee/spec/services/ee/resource_events/change_weight_service_spec.rb'
|
||||||
- 'ee/spec/services/elastic/index_record_service_spec.rb'
|
|
||||||
- 'ee/spec/services/epic_links/create_service_spec.rb'
|
- 'ee/spec/services/epic_links/create_service_spec.rb'
|
||||||
|
- 'ee/spec/services/epics/close_service_spec.rb'
|
||||||
- 'ee/spec/services/epics/issue_promote_service_spec.rb'
|
- 'ee/spec/services/epics/issue_promote_service_spec.rb'
|
||||||
|
- 'ee/spec/services/epics/reopen_service_spec.rb'
|
||||||
- 'ee/spec/services/epics/tree_reorder_service_spec.rb'
|
- 'ee/spec/services/epics/tree_reorder_service_spec.rb'
|
||||||
- 'ee/spec/services/epics/update_dates_service_spec.rb'
|
- 'ee/spec/services/epics/update_dates_service_spec.rb'
|
||||||
- 'ee/spec/services/epics/update_service_spec.rb'
|
- 'ee/spec/services/epics/update_service_spec.rb'
|
||||||
- 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb'
|
- 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb'
|
||||||
|
- 'ee/spec/services/geo/files_expire_service_spec.rb'
|
||||||
- 'ee/spec/services/geo/metrics_update_service_spec.rb'
|
- 'ee/spec/services/geo/metrics_update_service_spec.rb'
|
||||||
- 'ee/spec/services/geo/registry_consistency_service_spec.rb'
|
- 'ee/spec/services/geo/registry_consistency_service_spec.rb'
|
||||||
- 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb'
|
- 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb'
|
||||||
|
@ -911,8 +1022,11 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/services/lfs/unlock_file_service_spec.rb'
|
- 'ee/spec/services/lfs/unlock_file_service_spec.rb'
|
||||||
- 'ee/spec/services/merge_requests/approval_service_spec.rb'
|
- 'ee/spec/services/merge_requests/approval_service_spec.rb'
|
||||||
- 'ee/spec/services/merge_requests/remove_approval_service_spec.rb'
|
- 'ee/spec/services/merge_requests/remove_approval_service_spec.rb'
|
||||||
|
- 'ee/spec/services/merge_requests/update_blocks_service_spec.rb'
|
||||||
- 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb'
|
- 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb'
|
||||||
- 'ee/spec/services/projects/after_rename_service_spec.rb'
|
- 'ee/spec/services/projects/after_rename_service_spec.rb'
|
||||||
|
- 'ee/spec/services/projects/import_export/export_service_spec.rb'
|
||||||
|
- 'ee/spec/services/projects/update_mirror_service_spec.rb'
|
||||||
- 'ee/spec/services/projects/update_service_spec.rb'
|
- 'ee/spec/services/projects/update_service_spec.rb'
|
||||||
- 'ee/spec/services/quick_actions/interpret_service_spec.rb'
|
- 'ee/spec/services/quick_actions/interpret_service_spec.rb'
|
||||||
- 'ee/spec/services/slash_commands/global_slack_handler_spec.rb'
|
- 'ee/spec/services/slash_commands/global_slack_handler_spec.rb'
|
||||||
|
@ -920,50 +1034,92 @@ Rails/SaveBang:
|
||||||
- 'ee/spec/services/status_page/trigger_publish_service_spec.rb'
|
- 'ee/spec/services/status_page/trigger_publish_service_spec.rb'
|
||||||
- 'ee/spec/services/todo_service_spec.rb'
|
- 'ee/spec/services/todo_service_spec.rb'
|
||||||
- 'ee/spec/services/update_build_minutes_service_spec.rb'
|
- 'ee/spec/services/update_build_minutes_service_spec.rb'
|
||||||
|
- 'ee/spec/services/vulnerability_feedback/create_service_spec.rb'
|
||||||
|
- 'ee/spec/support/helpers/ee/geo_helpers.rb'
|
||||||
|
- 'ee/spec/support/protected_tags/access_control_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/models/concerns/replicator_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/models/concerns/replicator_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/models/elasticsearch_indexed_container_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/models/member_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/models/member_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/models/mentionable_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/models/mentionable_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/requests/api/graphql/geo/registries_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb'
|
||||||
|
- 'ee/spec/support/shared_examples/services/build_execute_shared_examples.rb'
|
||||||
- 'ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb'
|
- 'ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb'
|
||||||
- 'ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb'
|
- 'ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb'
|
||||||
- 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb'
|
- 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb'
|
||||||
|
- 'ee/spec/workers/clear_shared_runners_minutes_worker_spec.rb'
|
||||||
- 'ee/spec/workers/create_github_webhook_worker_spec.rb'
|
- 'ee/spec/workers/create_github_webhook_worker_spec.rb'
|
||||||
- 'ee/spec/workers/elastic_indexer_worker_spec.rb'
|
- 'ee/spec/workers/elastic_namespace_rollout_worker_spec.rb'
|
||||||
- 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb'
|
- 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb'
|
||||||
- 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb'
|
- 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb'
|
||||||
|
- 'ee/spec/workers/geo/prune_event_log_worker_spec.rb'
|
||||||
|
- 'ee/spec/workers/geo/registry_sync_worker_spec.rb'
|
||||||
- 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb'
|
- 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb'
|
||||||
- 'ee/spec/workers/repository_import_worker_spec.rb'
|
- 'ee/spec/workers/repository_import_worker_spec.rb'
|
||||||
- 'ee/spec/workers/update_all_mirrors_worker_spec.rb'
|
- 'ee/spec/workers/update_all_mirrors_worker_spec.rb'
|
||||||
- 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb'
|
- 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb'
|
||||||
- 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb'
|
- 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb'
|
||||||
|
- 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb'
|
||||||
- 'spec/controllers/abuse_reports_controller_spec.rb'
|
- 'spec/controllers/abuse_reports_controller_spec.rb'
|
||||||
- 'spec/controllers/admin/impersonations_controller_spec.rb'
|
- 'spec/controllers/admin/impersonations_controller_spec.rb'
|
||||||
- 'spec/controllers/admin/runners_controller_spec.rb'
|
- 'spec/controllers/admin/runners_controller_spec.rb'
|
||||||
|
- 'spec/controllers/admin/services_controller_spec.rb'
|
||||||
- 'spec/controllers/boards/issues_controller_spec.rb'
|
- 'spec/controllers/boards/issues_controller_spec.rb'
|
||||||
|
- 'spec/controllers/groups/milestones_controller_spec.rb'
|
||||||
- 'spec/controllers/groups/runners_controller_spec.rb'
|
- 'spec/controllers/groups/runners_controller_spec.rb'
|
||||||
|
- 'spec/controllers/groups/uploads_controller_spec.rb'
|
||||||
|
- 'spec/controllers/groups_controller_spec.rb'
|
||||||
- 'spec/controllers/oauth/authorizations_controller_spec.rb'
|
- 'spec/controllers/oauth/authorizations_controller_spec.rb'
|
||||||
- 'spec/controllers/omniauth_callbacks_controller_spec.rb'
|
- 'spec/controllers/omniauth_callbacks_controller_spec.rb'
|
||||||
- 'spec/controllers/profiles/emails_controller_spec.rb'
|
- 'spec/controllers/profiles/emails_controller_spec.rb'
|
||||||
- 'spec/controllers/profiles/notifications_controller_spec.rb'
|
- 'spec/controllers/profiles/notifications_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/artifacts_controller_spec.rb'
|
- 'spec/controllers/projects/artifacts_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/cycle_analytics/events_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/cycle_analytics_controller_spec.rb'
|
- 'spec/controllers/projects/cycle_analytics_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/discussions_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/forks_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/group_links_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/imports_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/issues_controller_spec.rb'
|
- 'spec/controllers/projects/issues_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/labels_controller_spec.rb'
|
- 'spec/controllers/projects/labels_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/merge_requests_controller_spec.rb'
|
- 'spec/controllers/projects/merge_requests_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/milestones_controller_spec.rb'
|
- 'spec/controllers/projects/milestones_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/notes_controller_spec.rb'
|
- 'spec/controllers/projects/notes_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/pipelines_controller_spec.rb'
|
- 'spec/controllers/projects/pipelines_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/releases/evidences_controller_spec.rb'
|
||||||
- 'spec/controllers/projects/runners_controller_spec.rb'
|
- 'spec/controllers/projects/runners_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/starrers_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/uploads_controller_spec.rb'
|
||||||
- 'spec/controllers/projects_controller_spec.rb'
|
- 'spec/controllers/projects_controller_spec.rb'
|
||||||
|
- 'spec/controllers/sent_notifications_controller_spec.rb'
|
||||||
|
- 'spec/controllers/sessions_controller_spec.rb'
|
||||||
|
- 'spec/controllers/users_controller_spec.rb'
|
||||||
|
- 'spec/factories/alert_management/alerts.rb'
|
||||||
|
- 'spec/factories/boards.rb'
|
||||||
- 'spec/factories/ci/pipelines.rb'
|
- 'spec/factories/ci/pipelines.rb'
|
||||||
- 'spec/factories/design_management/designs.rb'
|
- 'spec/factories/design_management/designs.rb'
|
||||||
- 'spec/factories/design_management/versions.rb'
|
- 'spec/factories/design_management/versions.rb'
|
||||||
|
- 'spec/factories/emails.rb'
|
||||||
|
- 'spec/factories/issues.rb'
|
||||||
- 'spec/factories/labels.rb'
|
- 'spec/factories/labels.rb'
|
||||||
|
- 'spec/factories/merge_requests.rb'
|
||||||
|
- 'spec/factories/plans.rb'
|
||||||
- 'spec/factories/projects.rb'
|
- 'spec/factories/projects.rb'
|
||||||
|
- 'spec/factories/services.rb'
|
||||||
|
- 'spec/factories/wiki_pages.rb'
|
||||||
|
- 'spec/factories_spec.rb'
|
||||||
|
- 'spec/features/admin/admin_appearance_spec.rb'
|
||||||
|
- 'spec/features/admin/admin_labels_spec.rb'
|
||||||
- 'spec/features/admin/admin_mode/login_spec.rb'
|
- 'spec/features/admin/admin_mode/login_spec.rb'
|
||||||
- 'spec/features/admin/admin_runners_spec.rb'
|
- 'spec/features/admin/admin_runners_spec.rb'
|
||||||
|
- 'spec/features/admin/admin_sees_project_statistics_spec.rb'
|
||||||
|
- 'spec/features/admin/admin_sees_projects_statistics_spec.rb'
|
||||||
- 'spec/features/admin/admin_users_impersonation_tokens_spec.rb'
|
- 'spec/features/admin/admin_users_impersonation_tokens_spec.rb'
|
||||||
- 'spec/features/admin/admin_users_spec.rb'
|
- 'spec/features/admin/admin_users_spec.rb'
|
||||||
- 'spec/features/boards/sidebar_spec.rb'
|
- 'spec/features/boards/sidebar_spec.rb'
|
||||||
|
@ -975,6 +1131,7 @@ Rails/SaveBang:
|
||||||
- 'spec/features/dashboard/projects_spec.rb'
|
- 'spec/features/dashboard/projects_spec.rb'
|
||||||
- 'spec/features/error_tracking/user_sees_error_index_spec.rb'
|
- 'spec/features/error_tracking/user_sees_error_index_spec.rb'
|
||||||
- 'spec/features/groups/members/request_access_spec.rb'
|
- 'spec/features/groups/members/request_access_spec.rb'
|
||||||
|
- 'spec/features/issuables/close_reopen_report_toggle_spec.rb'
|
||||||
- 'spec/features/issues/bulk_assignment_labels_spec.rb'
|
- 'spec/features/issues/bulk_assignment_labels_spec.rb'
|
||||||
- 'spec/features/issues/gfm_autocomplete_spec.rb'
|
- 'spec/features/issues/gfm_autocomplete_spec.rb'
|
||||||
- 'spec/features/issues/issue_sidebar_spec.rb'
|
- 'spec/features/issues/issue_sidebar_spec.rb'
|
||||||
|
@ -989,30 +1146,45 @@ Rails/SaveBang:
|
||||||
- 'spec/features/merge_request/user_posts_diff_notes_spec.rb'
|
- 'spec/features/merge_request/user_posts_diff_notes_spec.rb'
|
||||||
- 'spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb'
|
- 'spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb'
|
||||||
- 'spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb'
|
- 'spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb'
|
||||||
|
- 'spec/features/merge_request/user_sees_discussions_spec.rb'
|
||||||
- 'spec/features/merge_request/user_sees_merge_widget_spec.rb'
|
- 'spec/features/merge_request/user_sees_merge_widget_spec.rb'
|
||||||
|
- 'spec/features/merge_request/user_sees_versions_spec.rb'
|
||||||
- 'spec/features/merge_requests/user_mass_updates_spec.rb'
|
- 'spec/features/merge_requests/user_mass_updates_spec.rb'
|
||||||
- 'spec/features/profiles/emails_spec.rb'
|
- 'spec/features/profiles/emails_spec.rb'
|
||||||
- 'spec/features/profiles/password_spec.rb'
|
- 'spec/features/profiles/password_spec.rb'
|
||||||
- 'spec/features/profiles/personal_access_tokens_spec.rb'
|
- 'spec/features/profiles/personal_access_tokens_spec.rb'
|
||||||
- 'spec/features/projects/features_visibility_spec.rb'
|
- 'spec/features/projects/features_visibility_spec.rb'
|
||||||
|
- 'spec/features/projects/fork_spec.rb'
|
||||||
|
- 'spec/features/projects/jobs/permissions_spec.rb'
|
||||||
- 'spec/features/projects/jobs_spec.rb'
|
- 'spec/features/projects/jobs_spec.rb'
|
||||||
- 'spec/features/projects/members/user_requests_access_spec.rb'
|
- 'spec/features/projects/members/user_requests_access_spec.rb'
|
||||||
- 'spec/features/projects/pages_lets_encrypt_spec.rb'
|
- 'spec/features/projects/pages_lets_encrypt_spec.rb'
|
||||||
- 'spec/features/projects/pages_spec.rb'
|
- 'spec/features/projects/pages_spec.rb'
|
||||||
|
- 'spec/features/projects/pipelines/pipeline_spec.rb'
|
||||||
|
- 'spec/features/projects/pipelines/pipelines_spec.rb'
|
||||||
- 'spec/features/projects/remote_mirror_spec.rb'
|
- 'spec/features/projects/remote_mirror_spec.rb'
|
||||||
- 'spec/features/projects/services/user_activates_slack_notifications_spec.rb'
|
- 'spec/features/projects/services/user_activates_slack_notifications_spec.rb'
|
||||||
- 'spec/features/projects/settings/access_tokens_spec.rb'
|
- 'spec/features/projects/settings/access_tokens_spec.rb'
|
||||||
- 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb'
|
- 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb'
|
||||||
- 'spec/features/projects/user_sees_sidebar_spec.rb'
|
- 'spec/features/projects/user_sees_sidebar_spec.rb'
|
||||||
- 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb'
|
- 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb'
|
||||||
|
- 'spec/features/projects/wiki/user_views_wiki_page_spec.rb'
|
||||||
- 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb'
|
- 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb'
|
||||||
|
- 'spec/features/runners_spec.rb'
|
||||||
|
- 'spec/features/security/project/internal_access_spec.rb'
|
||||||
- 'spec/features/security/project/private_access_spec.rb'
|
- 'spec/features/security/project/private_access_spec.rb'
|
||||||
|
- 'spec/features/security/project/public_access_spec.rb'
|
||||||
- 'spec/features/users/login_spec.rb'
|
- 'spec/features/users/login_spec.rb'
|
||||||
- 'spec/features/users/show_spec.rb'
|
- 'spec/features/users/show_spec.rb'
|
||||||
|
- 'spec/finders/admin/projects_finder_spec.rb'
|
||||||
- 'spec/finders/autocomplete/move_to_project_finder_spec.rb'
|
- 'spec/finders/autocomplete/move_to_project_finder_spec.rb'
|
||||||
|
- 'spec/finders/ci/pipelines_for_merge_request_finder_spec.rb'
|
||||||
- 'spec/finders/group_descendants_finder_spec.rb'
|
- 'spec/finders/group_descendants_finder_spec.rb'
|
||||||
|
- 'spec/finders/group_projects_finder_spec.rb'
|
||||||
- 'spec/finders/issues_finder_spec.rb'
|
- 'spec/finders/issues_finder_spec.rb'
|
||||||
|
- 'spec/finders/joined_groups_finder_spec.rb'
|
||||||
- 'spec/finders/merge_requests_finder_spec.rb'
|
- 'spec/finders/merge_requests_finder_spec.rb'
|
||||||
|
- 'spec/finders/personal_projects_finder_spec.rb'
|
||||||
- 'spec/finders/projects_finder_spec.rb'
|
- 'spec/finders/projects_finder_spec.rb'
|
||||||
- 'spec/finders/uploader_finder_spec.rb'
|
- 'spec/finders/uploader_finder_spec.rb'
|
||||||
- 'spec/frontend/fixtures/issues.rb'
|
- 'spec/frontend/fixtures/issues.rb'
|
||||||
|
@ -1021,6 +1193,11 @@ Rails/SaveBang:
|
||||||
- 'spec/graphql/mutations/merge_requests/set_wip_spec.rb'
|
- 'spec/graphql/mutations/merge_requests/set_wip_spec.rb'
|
||||||
- 'spec/graphql/resolvers/boards_resolver_spec.rb'
|
- 'spec/graphql/resolvers/boards_resolver_spec.rb'
|
||||||
- 'spec/helpers/appearances_helper_spec.rb'
|
- 'spec/helpers/appearances_helper_spec.rb'
|
||||||
|
- 'spec/helpers/auto_devops_helper_spec.rb'
|
||||||
|
- 'spec/helpers/issuables_helper_spec.rb'
|
||||||
|
- 'spec/helpers/issues_helper_spec.rb'
|
||||||
|
- 'spec/helpers/members_helper_spec.rb'
|
||||||
|
- 'spec/helpers/notes_helper_spec.rb'
|
||||||
- 'spec/helpers/profiles_helper_spec.rb'
|
- 'spec/helpers/profiles_helper_spec.rb'
|
||||||
- 'spec/helpers/projects/alert_management_helper_spec.rb'
|
- 'spec/helpers/projects/alert_management_helper_spec.rb'
|
||||||
- 'spec/helpers/projects_helper_spec.rb'
|
- 'spec/helpers/projects_helper_spec.rb'
|
||||||
|
@ -1030,18 +1207,23 @@ Rails/SaveBang:
|
||||||
- 'spec/lib/after_commit_queue_spec.rb'
|
- 'spec/lib/after_commit_queue_spec.rb'
|
||||||
- 'spec/lib/backup/manager_spec.rb'
|
- 'spec/lib/backup/manager_spec.rb'
|
||||||
- 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb'
|
- 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb'
|
||||||
|
- 'spec/lib/banzai/reference_redactor_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/alerting/alert_spec.rb'
|
||||||
- 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb'
|
- 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb'
|
||||||
- 'spec/lib/gitlab/auth/ldap/user_spec.rb'
|
- 'spec/lib/gitlab/auth/ldap/user_spec.rb'
|
||||||
- 'spec/lib/gitlab/auth/o_auth/user_spec.rb'
|
- 'spec/lib/gitlab/auth/o_auth/user_spec.rb'
|
||||||
- 'spec/lib/gitlab/auth/saml/user_spec.rb'
|
- 'spec/lib/gitlab/auth/saml/user_spec.rb'
|
||||||
- 'spec/lib/gitlab/auth_spec.rb'
|
- 'spec/lib/gitlab/auth_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/authorized_keys_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb'
|
- 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb'
|
- 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb'
|
- 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb'
|
- 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/digest_column_spec.rb'
|
- 'spec/lib/gitlab/background_migration/digest_column_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb'
|
- 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb'
|
- 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb'
|
- 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb'
|
- 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb'
|
- 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb'
|
||||||
|
@ -1056,82 +1238,130 @@ Rails/SaveBang:
|
||||||
- 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb'
|
- 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb'
|
- 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb'
|
- 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/background_migration/reset_merge_status_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb'
|
- 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb'
|
||||||
- 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb'
|
- 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb'
|
||||||
- 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb'
|
- 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb'
|
||||||
- 'spec/lib/gitlab/ci/ansi2json/style_spec.rb'
|
- 'spec/lib/gitlab/ci/ansi2json/style_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/ci/status/build/common_spec.rb'
|
||||||
- 'spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb'
|
- 'spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb'
|
||||||
- 'spec/lib/gitlab/cycle_analytics/events_spec.rb'
|
- 'spec/lib/gitlab/cycle_analytics/events_spec.rb'
|
||||||
- 'spec/lib/gitlab/database/custom_structure_spec.rb'
|
- 'spec/lib/gitlab/database/custom_structure_spec.rb'
|
||||||
- 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb'
|
- 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb'
|
||||||
- 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb'
|
- 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/gfm/reference_rewriter_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/git/object_pool_spec.rb'
|
||||||
- 'spec/lib/gitlab/git/remote_mirror_spec.rb'
|
- 'spec/lib/gitlab/git/remote_mirror_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/git/repository_spec.rb'
|
||||||
- 'spec/lib/gitlab/git_access_spec.rb'
|
- 'spec/lib/gitlab/git_access_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/gitaly_client/object_pool_service_spec.rb'
|
||||||
- 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb'
|
- 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/avatar_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/avatar_saver_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/import_export/base/relation_factory_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb'
|
- 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/fork_spec.rb'
|
- 'spec/lib/gitlab/import_export/fork_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/import_export/group/relation_factory_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/import_export/group/tree_saver_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/importer_spec.rb'
|
- 'spec/lib/gitlab/import_export/importer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/lfs_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/lfs_saver_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/members_mapper_spec.rb'
|
- 'spec/lib/gitlab/import_export/members_mapper_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/repo_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/repo_restorer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/saver_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/uploads_manager_spec.rb'
|
- 'spec/lib/gitlab/import_export/uploads_manager_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/uploads_saver_spec.rb'
|
- 'spec/lib/gitlab/import_export/uploads_saver_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/legacy_github_import/importer_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/legacy_github_import/issue_formatter_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/legacy_github_import/milestone_formatter_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/legacy_github_import/pull_request_formatter_spec.rb'
|
||||||
- 'spec/lib/gitlab/lets_encrypt/client_spec.rb'
|
- 'spec/lib/gitlab/lets_encrypt/client_spec.rb'
|
||||||
- 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb'
|
- 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb'
|
||||||
- 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb'
|
- 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/middleware/go_spec.rb'
|
||||||
- 'spec/lib/gitlab/shard_health_cache_spec.rb'
|
- 'spec/lib/gitlab/shard_health_cache_spec.rb'
|
||||||
|
- 'spec/lib/mattermost/command_spec.rb'
|
||||||
|
- 'spec/lib/mattermost/session_spec.rb'
|
||||||
|
- 'spec/lib/mattermost/team_spec.rb'
|
||||||
- 'spec/mailers/notify_spec.rb'
|
- 'spec/mailers/notify_spec.rb'
|
||||||
|
- 'spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb'
|
||||||
- 'spec/migrations/20200122123016_backfill_project_settings_spec.rb'
|
- 'spec/migrations/20200122123016_backfill_project_settings_spec.rb'
|
||||||
- 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb'
|
- 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb'
|
||||||
- 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb'
|
- 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb'
|
||||||
|
- 'spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb'
|
||||||
|
- 'spec/migrations/20200313203550_remove_orphaned_chat_names_spec.rb'
|
||||||
- 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb'
|
- 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb'
|
||||||
|
- 'spec/migrations/20200526115436_dedup_mr_metrics_spec.rb'
|
||||||
|
- 'spec/migrations/add_deploy_token_type_to_deploy_tokens_spec.rb'
|
||||||
|
- 'spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb'
|
||||||
- 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb'
|
- 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb'
|
||||||
- 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb'
|
- 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb'
|
||||||
|
- 'spec/migrations/backfill_imported_snippet_repositories_spec.rb'
|
||||||
- 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb'
|
- 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb'
|
||||||
|
- 'spec/migrations/backfill_snippet_repositories_spec.rb'
|
||||||
- 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb'
|
- 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb'
|
||||||
|
- 'spec/migrations/enqueue_reset_merge_status_second_run_spec.rb'
|
||||||
|
- 'spec/migrations/enqueue_reset_merge_status_spec.rb'
|
||||||
- 'spec/migrations/fill_file_store_lfs_objects_spec.rb'
|
- 'spec/migrations/fill_file_store_lfs_objects_spec.rb'
|
||||||
- 'spec/migrations/fill_store_uploads_spec.rb'
|
- 'spec/migrations/fill_store_uploads_spec.rb'
|
||||||
- 'spec/migrations/fix_null_type_labels_spec.rb'
|
- 'spec/migrations/fix_null_type_labels_spec.rb'
|
||||||
- 'spec/migrations/fix_pool_repository_source_project_id_spec.rb'
|
- 'spec/migrations/fix_pool_repository_source_project_id_spec.rb'
|
||||||
|
- 'spec/migrations/fix_projects_without_project_feature_spec.rb'
|
||||||
|
- 'spec/migrations/fix_projects_without_prometheus_services_spec.rb'
|
||||||
- 'spec/migrations/fix_wrong_pages_access_level_spec.rb'
|
- 'spec/migrations/fix_wrong_pages_access_level_spec.rb'
|
||||||
- 'spec/migrations/insert_project_hooks_plan_limits_spec.rb'
|
- 'spec/migrations/insert_project_hooks_plan_limits_spec.rb'
|
||||||
- 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb'
|
- 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb'
|
||||||
|
- 'spec/migrations/move_limits_from_plans_spec.rb'
|
||||||
|
- 'spec/migrations/populate_project_statistics_packages_size_spec.rb'
|
||||||
- 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb'
|
- 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb'
|
||||||
|
- 'spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb'
|
||||||
|
- 'spec/migrations/seed_repository_storages_weighted_spec.rb'
|
||||||
- 'spec/models/appearance_spec.rb'
|
- 'spec/models/appearance_spec.rb'
|
||||||
|
- 'spec/models/application_record_spec.rb'
|
||||||
- 'spec/models/application_setting_spec.rb'
|
- 'spec/models/application_setting_spec.rb'
|
||||||
|
- 'spec/models/ci/build_metadata_spec.rb'
|
||||||
- 'spec/models/ci/build_spec.rb'
|
- 'spec/models/ci/build_spec.rb'
|
||||||
|
- 'spec/models/ci/build_trace_chunk_spec.rb'
|
||||||
- 'spec/models/ci/instance_variable_spec.rb'
|
- 'spec/models/ci/instance_variable_spec.rb'
|
||||||
|
- 'spec/models/ci/legacy_stage_spec.rb'
|
||||||
|
- 'spec/models/ci/persistent_ref_spec.rb'
|
||||||
- 'spec/models/ci/pipeline_spec.rb'
|
- 'spec/models/ci/pipeline_spec.rb'
|
||||||
- 'spec/models/ci/runner_spec.rb'
|
- 'spec/models/ci/runner_spec.rb'
|
||||||
- 'spec/models/clusters/applications/helm_spec.rb'
|
- 'spec/models/clusters/applications/helm_spec.rb'
|
||||||
|
- 'spec/models/commit_spec.rb'
|
||||||
|
- 'spec/models/commit_status_spec.rb'
|
||||||
- 'spec/models/concerns/avatarable_spec.rb'
|
- 'spec/models/concerns/avatarable_spec.rb'
|
||||||
- 'spec/models/concerns/bulk_insertable_associations_spec.rb'
|
- 'spec/models/concerns/bulk_insertable_associations_spec.rb'
|
||||||
- 'spec/models/concerns/cache_markdown_field_spec.rb'
|
- 'spec/models/concerns/cache_markdown_field_spec.rb'
|
||||||
|
- 'spec/models/concerns/case_sensitivity_spec.rb'
|
||||||
- 'spec/models/concerns/featurable_spec.rb'
|
- 'spec/models/concerns/featurable_spec.rb'
|
||||||
- 'spec/models/concerns/issuable_spec.rb'
|
- 'spec/models/concerns/issuable_spec.rb'
|
||||||
- 'spec/models/concerns/mentionable_spec.rb'
|
- 'spec/models/concerns/mentionable_spec.rb'
|
||||||
- 'spec/models/concerns/milestoneable_spec.rb'
|
- 'spec/models/concerns/milestoneable_spec.rb'
|
||||||
|
- 'spec/models/concerns/milestoneish_spec.rb'
|
||||||
- 'spec/models/concerns/routable_spec.rb'
|
- 'spec/models/concerns/routable_spec.rb'
|
||||||
- 'spec/models/concerns/subscribable_spec.rb'
|
- 'spec/models/concerns/subscribable_spec.rb'
|
||||||
- 'spec/models/concerns/token_authenticatable_spec.rb'
|
- 'spec/models/concerns/token_authenticatable_spec.rb'
|
||||||
- 'spec/models/container_repository_spec.rb'
|
- 'spec/models/container_repository_spec.rb'
|
||||||
- 'spec/models/cycle_analytics/issue_spec.rb'
|
- 'spec/models/cycle_analytics/issue_spec.rb'
|
||||||
- 'spec/models/cycle_analytics/plan_spec.rb'
|
- 'spec/models/cycle_analytics/plan_spec.rb'
|
||||||
|
- 'spec/models/cycle_analytics/production_spec.rb'
|
||||||
- 'spec/models/deploy_keys_project_spec.rb'
|
- 'spec/models/deploy_keys_project_spec.rb'
|
||||||
- 'spec/models/deploy_token_spec.rb'
|
- 'spec/models/deploy_token_spec.rb'
|
||||||
- 'spec/models/deployment_spec.rb'
|
- 'spec/models/deployment_spec.rb'
|
||||||
- 'spec/models/design_management/version_spec.rb'
|
- 'spec/models/design_management/version_spec.rb'
|
||||||
|
- 'spec/models/diff_discussion_spec.rb'
|
||||||
- 'spec/models/diff_note_spec.rb'
|
- 'spec/models/diff_note_spec.rb'
|
||||||
- 'spec/models/email_spec.rb'
|
- 'spec/models/email_spec.rb'
|
||||||
- 'spec/models/environment_spec.rb'
|
- 'spec/models/environment_spec.rb'
|
||||||
|
@ -1143,7 +1373,9 @@ Rails/SaveBang:
|
||||||
- 'spec/models/hooks/system_hook_spec.rb'
|
- 'spec/models/hooks/system_hook_spec.rb'
|
||||||
- 'spec/models/hooks/web_hook_spec.rb'
|
- 'spec/models/hooks/web_hook_spec.rb'
|
||||||
- 'spec/models/identity_spec.rb'
|
- 'spec/models/identity_spec.rb'
|
||||||
|
- 'spec/models/issue/metrics_spec.rb'
|
||||||
- 'spec/models/issue_spec.rb'
|
- 'spec/models/issue_spec.rb'
|
||||||
|
- 'spec/models/jira_import_state_spec.rb'
|
||||||
- 'spec/models/key_spec.rb'
|
- 'spec/models/key_spec.rb'
|
||||||
- 'spec/models/lfs_objects_project_spec.rb'
|
- 'spec/models/lfs_objects_project_spec.rb'
|
||||||
- 'spec/models/member_spec.rb'
|
- 'spec/models/member_spec.rb'
|
||||||
|
@ -1155,12 +1387,18 @@ Rails/SaveBang:
|
||||||
- 'spec/models/note_spec.rb'
|
- 'spec/models/note_spec.rb'
|
||||||
- 'spec/models/notification_setting_spec.rb'
|
- 'spec/models/notification_setting_spec.rb'
|
||||||
- 'spec/models/pages_domain_spec.rb'
|
- 'spec/models/pages_domain_spec.rb'
|
||||||
|
- 'spec/models/project_auto_devops_spec.rb'
|
||||||
|
- 'spec/models/project_feature_spec.rb'
|
||||||
- 'spec/models/project_services/bamboo_service_spec.rb'
|
- 'spec/models/project_services/bamboo_service_spec.rb'
|
||||||
|
- 'spec/models/project_services/buildkite_service_spec.rb'
|
||||||
- 'spec/models/project_services/jira_service_spec.rb'
|
- 'spec/models/project_services/jira_service_spec.rb'
|
||||||
|
- 'spec/models/project_services/packagist_service_spec.rb'
|
||||||
- 'spec/models/project_services/pipelines_email_service_spec.rb'
|
- 'spec/models/project_services/pipelines_email_service_spec.rb'
|
||||||
- 'spec/models/project_services/teamcity_service_spec.rb'
|
- 'spec/models/project_services/teamcity_service_spec.rb'
|
||||||
- 'spec/models/project_spec.rb'
|
- 'spec/models/project_spec.rb'
|
||||||
- 'spec/models/project_team_spec.rb'
|
- 'spec/models/project_team_spec.rb'
|
||||||
|
- 'spec/models/protectable_dropdown_spec.rb'
|
||||||
|
- 'spec/models/redirect_route_spec.rb'
|
||||||
- 'spec/models/release_spec.rb'
|
- 'spec/models/release_spec.rb'
|
||||||
- 'spec/models/remote_mirror_spec.rb'
|
- 'spec/models/remote_mirror_spec.rb'
|
||||||
- 'spec/models/resource_milestone_event_spec.rb'
|
- 'spec/models/resource_milestone_event_spec.rb'
|
||||||
|
@ -1171,47 +1409,77 @@ Rails/SaveBang:
|
||||||
- 'spec/models/upload_spec.rb'
|
- 'spec/models/upload_spec.rb'
|
||||||
- 'spec/models/user_preference_spec.rb'
|
- 'spec/models/user_preference_spec.rb'
|
||||||
- 'spec/models/user_spec.rb'
|
- 'spec/models/user_spec.rb'
|
||||||
|
- 'spec/models/user_status_spec.rb'
|
||||||
- 'spec/models/wiki_page/meta_spec.rb'
|
- 'spec/models/wiki_page/meta_spec.rb'
|
||||||
- 'spec/models/wiki_page_spec.rb'
|
- 'spec/models/wiki_page_spec.rb'
|
||||||
- 'spec/policies/ci/build_policy_spec.rb'
|
- 'spec/policies/ci/build_policy_spec.rb'
|
||||||
- 'spec/policies/ci/pipeline_policy_spec.rb'
|
- 'spec/policies/ci/pipeline_policy_spec.rb'
|
||||||
- 'spec/policies/ci/pipeline_schedule_policy_spec.rb'
|
- 'spec/policies/ci/pipeline_schedule_policy_spec.rb'
|
||||||
|
- 'spec/policies/group_policy_spec.rb'
|
||||||
|
- 'spec/policies/issue_policy_spec.rb'
|
||||||
- 'spec/policies/merge_request_policy_spec.rb'
|
- 'spec/policies/merge_request_policy_spec.rb'
|
||||||
- 'spec/policies/project_policy_spec.rb'
|
- 'spec/policies/project_policy_spec.rb'
|
||||||
|
- 'spec/presenters/ci/build_runner_presenter_spec.rb'
|
||||||
|
- 'spec/presenters/ci/trigger_presenter_spec.rb'
|
||||||
|
- 'spec/presenters/packages/conan/package_presenter_spec.rb'
|
||||||
|
- 'spec/requests/api/access_requests_spec.rb'
|
||||||
- 'spec/requests/api/boards_spec.rb'
|
- 'spec/requests/api/boards_spec.rb'
|
||||||
|
- 'spec/requests/api/branches_spec.rb'
|
||||||
|
- 'spec/requests/api/ci/runner_spec.rb'
|
||||||
|
- 'spec/requests/api/commit_statuses_spec.rb'
|
||||||
|
- 'spec/requests/api/conan_packages_spec.rb'
|
||||||
- 'spec/requests/api/deployments_spec.rb'
|
- 'spec/requests/api/deployments_spec.rb'
|
||||||
- 'spec/requests/api/environments_spec.rb'
|
- 'spec/requests/api/environments_spec.rb'
|
||||||
|
- 'spec/requests/api/go_proxy_spec.rb'
|
||||||
- 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb'
|
- 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb'
|
||||||
- 'spec/requests/api/graphql/user_query_spec.rb'
|
- 'spec/requests/api/graphql/user_query_spec.rb'
|
||||||
- 'spec/requests/api/graphql_spec.rb'
|
- 'spec/requests/api/graphql_spec.rb'
|
||||||
|
- 'spec/requests/api/group_import_spec.rb'
|
||||||
- 'spec/requests/api/group_milestones_spec.rb'
|
- 'spec/requests/api/group_milestones_spec.rb'
|
||||||
- 'spec/requests/api/internal/base_spec.rb'
|
- 'spec/requests/api/internal/base_spec.rb'
|
||||||
- 'spec/requests/api/issues/get_group_issues_spec.rb'
|
- 'spec/requests/api/issues/get_group_issues_spec.rb'
|
||||||
|
- 'spec/requests/api/issues/post_projects_issues_spec.rb'
|
||||||
- 'spec/requests/api/jobs_spec.rb'
|
- 'spec/requests/api/jobs_spec.rb'
|
||||||
- 'spec/requests/api/labels_spec.rb'
|
- 'spec/requests/api/labels_spec.rb'
|
||||||
|
- 'spec/requests/api/maven_packages_spec.rb'
|
||||||
- 'spec/requests/api/members_spec.rb'
|
- 'spec/requests/api/members_spec.rb'
|
||||||
- 'spec/requests/api/merge_request_diffs_spec.rb'
|
- 'spec/requests/api/merge_request_diffs_spec.rb'
|
||||||
- 'spec/requests/api/merge_requests_spec.rb'
|
- 'spec/requests/api/merge_requests_spec.rb'
|
||||||
|
- 'spec/requests/api/notes_spec.rb'
|
||||||
|
- 'spec/requests/api/pages/internal_access_spec.rb'
|
||||||
|
- 'spec/requests/api/pages/private_access_spec.rb'
|
||||||
|
- 'spec/requests/api/pages/public_access_spec.rb'
|
||||||
- 'spec/requests/api/pipeline_schedules_spec.rb'
|
- 'spec/requests/api/pipeline_schedules_spec.rb'
|
||||||
- 'spec/requests/api/project_import_spec.rb'
|
- 'spec/requests/api/project_import_spec.rb'
|
||||||
|
- 'spec/requests/api/project_milestones_spec.rb'
|
||||||
- 'spec/requests/api/projects_spec.rb'
|
- 'spec/requests/api/projects_spec.rb'
|
||||||
- 'spec/requests/api/runners_spec.rb'
|
|
||||||
- 'spec/requests/api/snippets_spec.rb'
|
- 'spec/requests/api/snippets_spec.rb'
|
||||||
- 'spec/requests/git_http_spec.rb'
|
- 'spec/requests/git_http_spec.rb'
|
||||||
|
- 'spec/requests/lfs_http_spec.rb'
|
||||||
- 'spec/requests/profiles/notifications_controller_spec.rb'
|
- 'spec/requests/profiles/notifications_controller_spec.rb'
|
||||||
- 'spec/requests/projects/cycle_analytics_events_spec.rb'
|
- 'spec/requests/projects/cycle_analytics_events_spec.rb'
|
||||||
- 'spec/serializers/environment_status_entity_spec.rb'
|
- 'spec/serializers/environment_status_entity_spec.rb'
|
||||||
|
- 'spec/serializers/issue_entity_spec.rb'
|
||||||
|
- 'spec/serializers/job_entity_spec.rb'
|
||||||
- 'spec/serializers/merge_request_poll_widget_entity_spec.rb'
|
- 'spec/serializers/merge_request_poll_widget_entity_spec.rb'
|
||||||
- 'spec/serializers/merge_request_widget_entity_spec.rb'
|
- 'spec/serializers/merge_request_widget_entity_spec.rb'
|
||||||
|
- 'spec/services/auth/container_registry_authentication_service_spec.rb'
|
||||||
|
- 'spec/services/auto_merge/base_service_spec.rb'
|
||||||
|
- 'spec/services/auto_merge_service_spec.rb'
|
||||||
|
- 'spec/services/ci/create_cross_project_pipeline_service_spec.rb'
|
||||||
- 'spec/services/ci/create_pipeline_service_spec.rb'
|
- 'spec/services/ci/create_pipeline_service_spec.rb'
|
||||||
- 'spec/services/ci/register_job_service_spec.rb'
|
- 'spec/services/ci/register_job_service_spec.rb'
|
||||||
- 'spec/services/ci/retry_build_service_spec.rb'
|
- 'spec/services/ci/retry_build_service_spec.rb'
|
||||||
|
- 'spec/services/ci/update_runner_service_spec.rb'
|
||||||
|
- 'spec/services/clusters/update_service_spec.rb'
|
||||||
- 'spec/services/deployments/after_create_service_spec.rb'
|
- 'spec/services/deployments/after_create_service_spec.rb'
|
||||||
- 'spec/services/design_management/generate_image_versions_service_spec.rb'
|
- 'spec/services/design_management/generate_image_versions_service_spec.rb'
|
||||||
|
- 'spec/services/discussions/resolve_service_spec.rb'
|
||||||
- 'spec/services/draft_notes/destroy_service_spec.rb'
|
- 'spec/services/draft_notes/destroy_service_spec.rb'
|
||||||
- 'spec/services/emails/confirm_service_spec.rb'
|
- 'spec/services/emails/confirm_service_spec.rb'
|
||||||
- 'spec/services/groups/destroy_service_spec.rb'
|
- 'spec/services/groups/destroy_service_spec.rb'
|
||||||
- 'spec/services/groups/import_export/import_service_spec.rb'
|
- 'spec/services/groups/import_export/import_service_spec.rb'
|
||||||
|
- 'spec/services/issuable/bulk_update_service_spec.rb'
|
||||||
- 'spec/services/issuable/clone/attributes_rewriter_spec.rb'
|
- 'spec/services/issuable/clone/attributes_rewriter_spec.rb'
|
||||||
- 'spec/services/issuable/common_system_notes_service_spec.rb'
|
- 'spec/services/issuable/common_system_notes_service_spec.rb'
|
||||||
- 'spec/services/issues/close_service_spec.rb'
|
- 'spec/services/issues/close_service_spec.rb'
|
||||||
|
@ -1221,6 +1489,7 @@ Rails/SaveBang:
|
||||||
- 'spec/services/issues/update_service_spec.rb'
|
- 'spec/services/issues/update_service_spec.rb'
|
||||||
- 'spec/services/labels/promote_service_spec.rb'
|
- 'spec/services/labels/promote_service_spec.rb'
|
||||||
- 'spec/services/members/destroy_service_spec.rb'
|
- 'spec/services/members/destroy_service_spec.rb'
|
||||||
|
- 'spec/services/merge_requests/build_service_spec.rb'
|
||||||
- 'spec/services/merge_requests/conflicts/list_service_spec.rb'
|
- 'spec/services/merge_requests/conflicts/list_service_spec.rb'
|
||||||
- 'spec/services/merge_requests/create_service_spec.rb'
|
- 'spec/services/merge_requests/create_service_spec.rb'
|
||||||
- 'spec/services/merge_requests/merge_service_spec.rb'
|
- 'spec/services/merge_requests/merge_service_spec.rb'
|
||||||
|
@ -1230,11 +1499,16 @@ Rails/SaveBang:
|
||||||
- 'spec/services/milestones/destroy_service_spec.rb'
|
- 'spec/services/milestones/destroy_service_spec.rb'
|
||||||
- 'spec/services/milestones/promote_service_spec.rb'
|
- 'spec/services/milestones/promote_service_spec.rb'
|
||||||
- 'spec/services/milestones/transfer_service_spec.rb'
|
- 'spec/services/milestones/transfer_service_spec.rb'
|
||||||
|
- 'spec/services/notes/create_service_spec.rb'
|
||||||
- 'spec/services/notification_recipients/build_service_spec.rb'
|
- 'spec/services/notification_recipients/build_service_spec.rb'
|
||||||
- 'spec/services/notification_service_spec.rb'
|
- 'spec/services/notification_service_spec.rb'
|
||||||
|
- 'spec/services/packages/conan/create_package_file_service_spec.rb'
|
||||||
- 'spec/services/projects/after_rename_service_spec.rb'
|
- 'spec/services/projects/after_rename_service_spec.rb'
|
||||||
|
- 'spec/services/projects/autocomplete_service_spec.rb'
|
||||||
- 'spec/services/projects/create_service_spec.rb'
|
- 'spec/services/projects/create_service_spec.rb'
|
||||||
|
- 'spec/services/projects/destroy_service_spec.rb'
|
||||||
- 'spec/services/projects/fork_service_spec.rb'
|
- 'spec/services/projects/fork_service_spec.rb'
|
||||||
|
- 'spec/services/projects/hashed_storage/base_attachment_service_spec.rb'
|
||||||
- 'spec/services/projects/move_access_service_spec.rb'
|
- 'spec/services/projects/move_access_service_spec.rb'
|
||||||
- 'spec/services/projects/move_project_group_links_service_spec.rb'
|
- 'spec/services/projects/move_project_group_links_service_spec.rb'
|
||||||
- 'spec/services/projects/overwrite_project_service_spec.rb'
|
- 'spec/services/projects/overwrite_project_service_spec.rb'
|
||||||
|
@ -1243,6 +1517,8 @@ Rails/SaveBang:
|
||||||
- 'spec/services/projects/update_pages_service_spec.rb'
|
- 'spec/services/projects/update_pages_service_spec.rb'
|
||||||
- 'spec/services/projects/update_service_spec.rb'
|
- 'spec/services/projects/update_service_spec.rb'
|
||||||
- 'spec/services/quick_actions/interpret_service_spec.rb'
|
- 'spec/services/quick_actions/interpret_service_spec.rb'
|
||||||
|
- 'spec/services/reset_project_cache_service_spec.rb'
|
||||||
|
- 'spec/services/resource_events/change_milestone_service_spec.rb'
|
||||||
- 'spec/services/system_hooks_service_spec.rb'
|
- 'spec/services/system_hooks_service_spec.rb'
|
||||||
- 'spec/services/system_note_service_spec.rb'
|
- 'spec/services/system_note_service_spec.rb'
|
||||||
- 'spec/services/system_notes/issuables_service_spec.rb'
|
- 'spec/services/system_notes/issuables_service_spec.rb'
|
||||||
|
@ -1250,42 +1526,71 @@ Rails/SaveBang:
|
||||||
- 'spec/services/todos/destroy/confidential_issue_service_spec.rb'
|
- 'spec/services/todos/destroy/confidential_issue_service_spec.rb'
|
||||||
- 'spec/services/users/destroy_service_spec.rb'
|
- 'spec/services/users/destroy_service_spec.rb'
|
||||||
- 'spec/services/users/repair_ldap_blocked_service_spec.rb'
|
- 'spec/services/users/repair_ldap_blocked_service_spec.rb'
|
||||||
|
- 'spec/services/verify_pages_domain_service_spec.rb'
|
||||||
|
- 'spec/sidekiq/cron/job_gem_dependency_spec.rb'
|
||||||
- 'spec/support/helpers/cycle_analytics_helpers.rb'
|
- 'spec/support/helpers/cycle_analytics_helpers.rb'
|
||||||
|
- 'spec/support/helpers/design_management_test_helpers.rb'
|
||||||
- 'spec/support/helpers/jira_service_helper.rb'
|
- 'spec/support/helpers/jira_service_helper.rb'
|
||||||
- 'spec/support/helpers/login_helpers.rb'
|
- 'spec/support/helpers/login_helpers.rb'
|
||||||
- 'spec/support/helpers/notification_helpers.rb'
|
- 'spec/support/helpers/notification_helpers.rb'
|
||||||
- 'spec/support/helpers/stub_action_cable_connection.rb'
|
|
||||||
- 'spec/support/helpers/stub_object_storage.rb'
|
- 'spec/support/helpers/stub_object_storage.rb'
|
||||||
- 'spec/support/migrations_helpers/cluster_helpers.rb'
|
- 'spec/support/migrations_helpers/cluster_helpers.rb'
|
||||||
|
- 'spec/support/migrations_helpers/namespaces_helper.rb'
|
||||||
- 'spec/support/migrations_helpers/track_untracked_uploads_helpers.rb'
|
- 'spec/support/migrations_helpers/track_untracked_uploads_helpers.rb'
|
||||||
|
- 'spec/support/shared_contexts/email_shared_context.rb'
|
||||||
- 'spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb'
|
- 'spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb'
|
||||||
- 'spec/support/shared_contexts/mailers/notify_shared_context.rb'
|
- 'spec/support/shared_contexts/mailers/notify_shared_context.rb'
|
||||||
|
- 'spec/support/shared_examples/controllers/cache_control_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb'
|
- 'spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/controllers/sessionless_auth_controller_shared_examples.rb'
|
- 'spec/support/shared_examples/controllers/sessionless_auth_controller_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb'
|
- 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
|
- 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/models/chat_slash_commands_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/models/concerns/limitable_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/models/concerns/timebox_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb'
|
- 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/member_shared_examples.rb'
|
- 'spec/support/shared_examples/models/member_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/members_notifications_shared_example.rb'
|
- 'spec/support/shared_examples/models/members_notifications_shared_example.rb'
|
||||||
- 'spec/support/shared_examples/models/mentionable_shared_examples.rb'
|
- 'spec/support/shared_examples/models/mentionable_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/models/project_latest_successful_build_for_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/relative_positioning_shared_examples.rb'
|
- 'spec/support/shared_examples/models/relative_positioning_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb'
|
- 'spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/update_project_statistics_shared_examples.rb'
|
- 'spec/support/shared_examples/models/update_project_statistics_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/models/with_uploads_shared_examples.rb'
|
- 'spec/support/shared_examples/models/with_uploads_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/policies/project_policy_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
|
- 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb'
|
- 'spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/award_emoji_todo_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/requests/api/boards_shared_examples.rb'
|
- 'spec/support/shared_examples/requests/api/boards_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/serializers/note_entity_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/services/common_system_notes_shared_examples.rb'
|
- 'spec/support/shared_examples/services/common_system_notes_shared_examples.rb'
|
||||||
- 'spec/support/shared_examples/services/issuable_shared_examples.rb'
|
- 'spec/support/shared_examples/services/issuable_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb'
|
||||||
- 'spec/tasks/gitlab/web_hook_rake_spec.rb'
|
- 'spec/tasks/gitlab/web_hook_rake_spec.rb'
|
||||||
|
- 'spec/uploaders/file_uploader_spec.rb'
|
||||||
|
- 'spec/uploaders/object_storage_spec.rb'
|
||||||
|
- 'spec/views/notify/changed_milestone_email.html.haml_spec.rb'
|
||||||
- 'spec/views/projects/imports/new.html.haml_spec.rb'
|
- 'spec/views/projects/imports/new.html.haml_spec.rb'
|
||||||
- 'spec/views/projects/merge_requests/show.html.haml_spec.rb'
|
- 'spec/views/projects/merge_requests/show.html.haml_spec.rb'
|
||||||
- 'spec/views/shared/_label_row.html.haml_spec.rb'
|
- 'spec/views/shared/_label_row.html.haml_spec.rb'
|
||||||
|
- 'spec/workers/concerns/project_export_options_spec.rb'
|
||||||
|
- 'spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb'
|
||||||
|
- 'spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb'
|
||||||
- 'spec/workers/migrate_external_diffs_worker_spec.rb'
|
- 'spec/workers/migrate_external_diffs_worker_spec.rb'
|
||||||
- 'spec/workers/namespaceless_project_destroy_worker_spec.rb'
|
- 'spec/workers/namespaceless_project_destroy_worker_spec.rb'
|
||||||
|
- 'spec/workers/namespaces/root_statistics_worker_spec.rb'
|
||||||
- 'spec/workers/pages_domain_verification_worker_spec.rb'
|
- 'spec/workers/pages_domain_verification_worker_spec.rb'
|
||||||
|
- 'spec/workers/process_commit_worker_spec.rb'
|
||||||
|
- 'spec/workers/propagate_integration_worker_spec.rb'
|
||||||
- 'spec/workers/propagate_service_template_worker_spec.rb'
|
- 'spec/workers/propagate_service_template_worker_spec.rb'
|
||||||
- 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb'
|
- 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb'
|
||||||
|
- 'spec/workers/repository_check/single_repository_worker_spec.rb'
|
||||||
- 'spec/workers/repository_cleanup_worker_spec.rb'
|
- 'spec/workers/repository_cleanup_worker_spec.rb'
|
||||||
- 'spec/workers/repository_import_worker_spec.rb'
|
- 'spec/workers/repository_import_worker_spec.rb'
|
||||||
- 'spec/workers/repository_update_remote_mirror_worker_spec.rb'
|
- 'spec/workers/repository_update_remote_mirror_worker_spec.rb'
|
||||||
|
- 'spec/workers/stuck_ci_jobs_worker_spec.rb'
|
||||||
|
- 'spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb'
|
||||||
|
|
742
CHANGELOG.md
742
CHANGELOG.md
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,7 @@ require_relative 'lib/gitlab/danger/request_helper'
|
||||||
danger.import_plugin('danger/plugins/helper.rb')
|
danger.import_plugin('danger/plugins/helper.rb')
|
||||||
danger.import_plugin('danger/plugins/roulette.rb')
|
danger.import_plugin('danger/plugins/roulette.rb')
|
||||||
danger.import_plugin('danger/plugins/changelog.rb')
|
danger.import_plugin('danger/plugins/changelog.rb')
|
||||||
|
danger.import_plugin('danger/plugins/sidekiq_queues.rb')
|
||||||
|
|
||||||
return if helper.release_automation?
|
return if helper.release_automation?
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
13.1.6
|
13.2.1
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.3.0
|
2.4.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.18.0
|
1.21.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
8.35.0
|
8.37.0
|
||||||
|
|
32
Gemfile
32
Gemfile
|
@ -19,7 +19,7 @@ gem 'default_value_for', '~> 3.3.0'
|
||||||
gem 'pg', '~> 1.1'
|
gem 'pg', '~> 1.1'
|
||||||
|
|
||||||
gem 'rugged', '~> 0.28'
|
gem 'rugged', '~> 0.28'
|
||||||
gem 'grape-path-helpers', '~> 1.2'
|
gem 'grape-path-helpers', '~> 1.3'
|
||||||
|
|
||||||
gem 'faraday', '~> 0.12'
|
gem 'faraday', '~> 0.12'
|
||||||
gem 'marginalia', '~> 1.8.0'
|
gem 'marginalia', '~> 1.8.0'
|
||||||
|
@ -66,7 +66,7 @@ gem 'u2f', '~> 0.2.1'
|
||||||
gem 'validates_hostname', '~> 1.0.10'
|
gem 'validates_hostname', '~> 1.0.10'
|
||||||
gem 'rubyzip', '~> 2.0.0', require: 'zip'
|
gem 'rubyzip', '~> 2.0.0', require: 'zip'
|
||||||
# GitLab Pages letsencrypt support
|
# GitLab Pages letsencrypt support
|
||||||
gem 'acme-client', '~> 2.0.5'
|
gem 'acme-client', '~> 2.0', '>= 2.0.6'
|
||||||
|
|
||||||
# Browser detection
|
# Browser detection
|
||||||
gem 'browser', '~> 2.5'
|
gem 'browser', '~> 2.5'
|
||||||
|
@ -81,7 +81,9 @@ gem 'gitlab_omniauth-ldap', '~> 2.1.1', require: 'omniauth-ldap'
|
||||||
gem 'net-ldap'
|
gem 'net-ldap'
|
||||||
|
|
||||||
# API
|
# API
|
||||||
gem 'grape', '~> 1.1.0'
|
# Locked at Grape v1.4.0 until https://github.com/ruby-grape/grape/pull/2088 is merged
|
||||||
|
# Remove config/initializers/grape_patch.rb
|
||||||
|
gem 'grape', '= 1.4.0'
|
||||||
gem 'grape-entity', '~> 0.7.1'
|
gem 'grape-entity', '~> 0.7.1'
|
||||||
gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
|
gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
|
||||||
|
|
||||||
|
@ -140,6 +142,7 @@ gem 'deckar01-task_list', '2.3.1'
|
||||||
gem 'gitlab-markup', '~> 1.7.1'
|
gem 'gitlab-markup', '~> 1.7.1'
|
||||||
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
|
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
|
||||||
gem 'commonmarker', '~> 0.20'
|
gem 'commonmarker', '~> 0.20'
|
||||||
|
gem 'kramdown', '~> 2.2.1'
|
||||||
gem 'RedCloth', '~> 4.3.2'
|
gem 'RedCloth', '~> 4.3.2'
|
||||||
gem 'rdoc', '~> 6.1.2'
|
gem 'rdoc', '~> 6.1.2'
|
||||||
gem 'org-ruby', '~> 0.9.12'
|
gem 'org-ruby', '~> 0.9.12'
|
||||||
|
@ -148,7 +151,7 @@ gem 'wikicloth', '0.8.1'
|
||||||
gem 'asciidoctor', '~> 2.0.10'
|
gem 'asciidoctor', '~> 2.0.10'
|
||||||
gem 'asciidoctor-include-ext', '~> 0.3.1', require: false
|
gem 'asciidoctor-include-ext', '~> 0.3.1', require: false
|
||||||
gem 'asciidoctor-plantuml', '~> 0.0.12'
|
gem 'asciidoctor-plantuml', '~> 0.0.12'
|
||||||
gem 'rouge', '~> 3.19.0'
|
gem 'rouge', '~> 3.21.0'
|
||||||
gem 'truncato', '~> 0.7.11'
|
gem 'truncato', '~> 0.7.11'
|
||||||
gem 'bootstrap_form', '~> 4.2.0'
|
gem 'bootstrap_form', '~> 4.2.0'
|
||||||
gem 'nokogiri', '~> 1.10.9'
|
gem 'nokogiri', '~> 1.10.9'
|
||||||
|
@ -163,6 +166,8 @@ gem 'diff_match_patch', '~> 0.1.0'
|
||||||
|
|
||||||
# Application server
|
# Application server
|
||||||
gem 'rack', '~> 2.0.9'
|
gem 'rack', '~> 2.0.9'
|
||||||
|
# https://github.com/sharpstone/rack-timeout/blob/master/README.md#rails-apps-manually
|
||||||
|
gem 'rack-timeout', '~> 0.5.1', require: 'rack/timeout/base'
|
||||||
|
|
||||||
group :unicorn do
|
group :unicorn do
|
||||||
gem 'unicorn', '~> 5.5'
|
gem 'unicorn', '~> 5.5'
|
||||||
|
@ -172,7 +177,6 @@ end
|
||||||
group :puma do
|
group :puma do
|
||||||
gem 'gitlab-puma', '~> 4.3.3.gitlab.2', require: false
|
gem 'gitlab-puma', '~> 4.3.3.gitlab.2', require: false
|
||||||
gem 'gitlab-puma_worker_killer', '~> 0.1.1.gitlab.1', require: false
|
gem 'gitlab-puma_worker_killer', '~> 0.1.1.gitlab.1', require: false
|
||||||
gem 'rack-timeout', require: false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# State machine
|
# State machine
|
||||||
|
@ -242,7 +246,9 @@ gem 'slack-messenger', '~> 2.3.3'
|
||||||
gem 'hangouts-chat', '~> 0.0.5'
|
gem 'hangouts-chat', '~> 0.0.5'
|
||||||
|
|
||||||
# Asana integration
|
# Asana integration
|
||||||
gem 'asana', '~> 0.9'
|
# asana 0.10.1 needs faraday 1.0
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/issues/224296
|
||||||
|
gem 'asana', '0.10.0'
|
||||||
|
|
||||||
# FogBugz integration
|
# FogBugz integration
|
||||||
gem 'ruby-fogbugz', '~> 0.2.1'
|
gem 'ruby-fogbugz', '~> 0.2.1'
|
||||||
|
@ -300,7 +306,7 @@ gem 'sentry-raven', '~> 2.9'
|
||||||
gem 'premailer-rails', '~> 1.10.3'
|
gem 'premailer-rails', '~> 1.10.3'
|
||||||
|
|
||||||
# LabKit: Tracing and Correlation
|
# LabKit: Tracing and Correlation
|
||||||
gem 'gitlab-labkit', '0.12.0'
|
gem 'gitlab-labkit', '0.12.1'
|
||||||
|
|
||||||
# I18n
|
# I18n
|
||||||
gem 'ruby_parser', '~> 3.8', require: false
|
gem 'ruby_parser', '~> 3.8', require: false
|
||||||
|
@ -331,10 +337,9 @@ group :development do
|
||||||
gem 'danger', '~> 6.0', require: false
|
gem 'danger', '~> 6.0', require: false
|
||||||
|
|
||||||
gem 'letter_opener_web', '~> 1.3.4'
|
gem 'letter_opener_web', '~> 1.3.4'
|
||||||
gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false
|
|
||||||
|
|
||||||
# Better errors handler
|
# Better errors handler
|
||||||
gem 'better_errors', '~> 2.5.0'
|
gem 'better_errors', '~> 2.7.1'
|
||||||
gem 'binding_of_caller', '~> 0.8.0'
|
gem 'binding_of_caller', '~> 0.8.0'
|
||||||
|
|
||||||
# thin instead webrick
|
# thin instead webrick
|
||||||
|
@ -361,7 +366,7 @@ group :development, :test do
|
||||||
gem 'spring', '~> 2.0.0'
|
gem 'spring', '~> 2.0.0'
|
||||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||||
|
|
||||||
gem 'gitlab-styles', '~> 4.2.0', require: false
|
gem 'gitlab-styles', '~> 4.3.0', require: false
|
||||||
# Pin these dependencies, otherwise a new rule could break the CI pipelines
|
# Pin these dependencies, otherwise a new rule could break the CI pipelines
|
||||||
gem 'rubocop', '~> 0.82.0'
|
gem 'rubocop', '~> 0.82.0'
|
||||||
gem 'rubocop-performance', '~> 1.5.2'
|
gem 'rubocop-performance', '~> 1.5.2'
|
||||||
|
@ -370,6 +375,7 @@ group :development, :test do
|
||||||
gem 'scss_lint', '~> 0.56.0', require: false
|
gem 'scss_lint', '~> 0.56.0', require: false
|
||||||
gem 'haml_lint', '~> 0.34.0', require: false
|
gem 'haml_lint', '~> 0.34.0', require: false
|
||||||
gem 'simplecov', '~> 0.18.5', require: false
|
gem 'simplecov', '~> 0.18.5', require: false
|
||||||
|
gem 'simplecov-cobertura', '~> 1.3.1', require: false
|
||||||
gem 'bundler-audit', '~> 0.6.1', require: false
|
gem 'bundler-audit', '~> 0.6.1', require: false
|
||||||
|
|
||||||
gem 'benchmark-ips', '~> 2.3.0', require: false
|
gem 'benchmark-ips', '~> 2.3.0', require: false
|
||||||
|
@ -383,6 +389,8 @@ group :development, :test do
|
||||||
gem 'png_quantizator', '~> 0.2.1', require: false
|
gem 'png_quantizator', '~> 0.2.1', require: false
|
||||||
|
|
||||||
gem 'parallel', '~> 1.19', require: false
|
gem 'parallel', '~> 1.19', require: false
|
||||||
|
|
||||||
|
gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gems required in omnibus-gitlab pipeline
|
# Gems required in omnibus-gitlab pipeline
|
||||||
|
@ -452,7 +460,7 @@ group :ed25519 do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gitaly GRPC protocol definitions
|
# Gitaly GRPC protocol definitions
|
||||||
gem 'gitaly', '~> 13.1.0.pre.rc1'
|
gem 'gitaly', '~> 13.2.0.pre.rc2'
|
||||||
|
|
||||||
gem 'grpc', '~> 1.24.0'
|
gem 'grpc', '~> 1.24.0'
|
||||||
|
|
||||||
|
@ -497,3 +505,5 @@ gem 'valid_email', '~> 0.1'
|
||||||
# JSON
|
# JSON
|
||||||
gem 'json', '~> 2.3.0'
|
gem 'json', '~> 2.3.0'
|
||||||
gem 'json-schema', '~> 2.8.0'
|
gem 'json-schema', '~> 2.8.0'
|
||||||
|
gem 'oj', '~> 3.10.6'
|
||||||
|
gem 'multi_json', '~> 1.14.1'
|
||||||
|
|
107
Gemfile.lock
107
Gemfile.lock
|
@ -4,8 +4,8 @@ GEM
|
||||||
RedCloth (4.3.2)
|
RedCloth (4.3.2)
|
||||||
abstract_type (0.0.7)
|
abstract_type (0.0.7)
|
||||||
ace-rails-ap (4.1.2)
|
ace-rails-ap (4.1.2)
|
||||||
acme-client (2.0.5)
|
acme-client (2.0.6)
|
||||||
faraday (~> 0.9, >= 0.9.1)
|
faraday (>= 0.17, < 2.0.0)
|
||||||
actioncable (6.0.3.1)
|
actioncable (6.0.3.1)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.1)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
|
@ -76,7 +76,7 @@ GEM
|
||||||
apollo_upload_server (2.0.0.beta.3)
|
apollo_upload_server (2.0.0.beta.3)
|
||||||
graphql (>= 1.8)
|
graphql (>= 1.8)
|
||||||
rails (>= 4.2)
|
rails (>= 4.2)
|
||||||
asana (0.9.3)
|
asana (0.10.0)
|
||||||
faraday (~> 0.9)
|
faraday (~> 0.9)
|
||||||
faraday_middleware (~> 0.9)
|
faraday_middleware (~> 0.9)
|
||||||
faraday_middleware-multi_json (~> 0.0)
|
faraday_middleware-multi_json (~> 0.0)
|
||||||
|
@ -103,10 +103,6 @@ GEM
|
||||||
aws-sdk-core (= 2.11.374)
|
aws-sdk-core (= 2.11.374)
|
||||||
aws-sigv4 (1.1.0)
|
aws-sigv4 (1.1.0)
|
||||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||||
axiom-types (0.1.1)
|
|
||||||
descendants_tracker (~> 0.0.4)
|
|
||||||
ice_nine (~> 0.11.0)
|
|
||||||
thread_safe (~> 0.3, >= 0.3.1)
|
|
||||||
babosa (1.0.2)
|
babosa (1.0.2)
|
||||||
base32 (0.3.2)
|
base32 (0.3.2)
|
||||||
batch-loader (1.4.0)
|
batch-loader (1.4.0)
|
||||||
|
@ -115,7 +111,7 @@ GEM
|
||||||
benchmark-ips (2.3.0)
|
benchmark-ips (2.3.0)
|
||||||
benchmark-memory (0.1.2)
|
benchmark-memory (0.1.2)
|
||||||
memory_profiler (~> 0.9)
|
memory_profiler (~> 0.9)
|
||||||
better_errors (2.5.0)
|
better_errors (2.7.1)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubi (>= 1.0.0)
|
erubi (>= 1.0.0)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
|
@ -164,8 +160,6 @@ GEM
|
||||||
nap
|
nap
|
||||||
open4 (~> 1.3)
|
open4 (~> 1.3)
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
coercible (1.0.0)
|
|
||||||
descendants_tracker (~> 0.0.1)
|
|
||||||
colored2 (3.1.2)
|
colored2 (3.1.2)
|
||||||
commonmarker (0.20.1)
|
commonmarker (0.20.1)
|
||||||
ruby-enum (~> 0.5)
|
ruby-enum (~> 0.5)
|
||||||
|
@ -221,8 +215,6 @@ GEM
|
||||||
ruby-statistics (>= 2.1)
|
ruby-statistics (>= 2.1)
|
||||||
thor (>= 0.19, < 2)
|
thor (>= 0.19, < 2)
|
||||||
unicode_plot (>= 0.0.4, < 1.0.0)
|
unicode_plot (>= 0.0.4, < 1.0.0)
|
||||||
descendants_tracker (0.0.4)
|
|
||||||
thread_safe (~> 0.3, >= 0.3.1)
|
|
||||||
device_detector (1.0.0)
|
device_detector (1.0.0)
|
||||||
devise (4.7.1)
|
devise (4.7.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
|
@ -249,6 +241,28 @@ GEM
|
||||||
doorkeeper-openid_connect (1.6.3)
|
doorkeeper-openid_connect (1.6.3)
|
||||||
doorkeeper (>= 5.0, < 5.2)
|
doorkeeper (>= 5.0, < 5.2)
|
||||||
json-jwt (~> 1.6)
|
json-jwt (~> 1.6)
|
||||||
|
dry-configurable (0.11.5)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
dry-core (~> 0.4, >= 0.4.7)
|
||||||
|
dry-equalizer (~> 0.2)
|
||||||
|
dry-container (0.7.2)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
dry-configurable (~> 0.1, >= 0.1.3)
|
||||||
|
dry-core (0.4.9)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
dry-equalizer (0.3.0)
|
||||||
|
dry-inflector (0.2.0)
|
||||||
|
dry-logic (1.0.6)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
dry-core (~> 0.2)
|
||||||
|
dry-equalizer (~> 0.2)
|
||||||
|
dry-types (1.4.0)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
dry-container (~> 0.3)
|
||||||
|
dry-core (~> 0.4, >= 0.4.4)
|
||||||
|
dry-equalizer (~> 0.3)
|
||||||
|
dry-inflector (~> 0.1, >= 0.1.2)
|
||||||
|
dry-logic (~> 1.0, >= 1.0.2)
|
||||||
ed25519 (1.2.4)
|
ed25519 (1.2.4)
|
||||||
elasticsearch (6.8.0)
|
elasticsearch (6.8.0)
|
||||||
elasticsearch-api (= 6.8.0)
|
elasticsearch-api (= 6.8.0)
|
||||||
|
@ -290,7 +304,7 @@ GEM
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
faraday-http-cache (2.0.0)
|
faraday-http-cache (2.0.0)
|
||||||
faraday (~> 0.8)
|
faraday (~> 0.8)
|
||||||
faraday_middleware (0.12.2)
|
faraday_middleware (0.14.0)
|
||||||
faraday (>= 0.7.4, < 1.0)
|
faraday (>= 0.7.4, < 1.0)
|
||||||
faraday_middleware-aws-signers-v4 (0.1.7)
|
faraday_middleware-aws-signers-v4 (0.1.7)
|
||||||
aws-sdk-resources (~> 2)
|
aws-sdk-resources (~> 2)
|
||||||
|
@ -377,12 +391,12 @@ GEM
|
||||||
po_to_json (>= 1.0.0)
|
po_to_json (>= 1.0.0)
|
||||||
rails (>= 3.2.0)
|
rails (>= 3.2.0)
|
||||||
git (1.5.0)
|
git (1.5.0)
|
||||||
gitaly (13.1.0.pre.rc1)
|
gitaly (13.2.0.pre.rc2)
|
||||||
grpc (~> 1.0)
|
grpc (~> 1.0)
|
||||||
github-markup (1.7.0)
|
github-markup (1.7.0)
|
||||||
gitlab-chronic (0.10.5)
|
gitlab-chronic (0.10.5)
|
||||||
numerizer (~> 0.2)
|
numerizer (~> 0.2)
|
||||||
gitlab-labkit (0.12.0)
|
gitlab-labkit (0.12.1)
|
||||||
actionpack (>= 5.0.0, < 6.1.0)
|
actionpack (>= 5.0.0, < 6.1.0)
|
||||||
activesupport (>= 5.0.0, < 6.1.0)
|
activesupport (>= 5.0.0, < 6.1.0)
|
||||||
grpc (~> 1.19)
|
grpc (~> 1.19)
|
||||||
|
@ -400,7 +414,7 @@ GEM
|
||||||
gitlab-puma (>= 2.7, < 5)
|
gitlab-puma (>= 2.7, < 5)
|
||||||
gitlab-sidekiq-fetcher (0.5.2)
|
gitlab-sidekiq-fetcher (0.5.2)
|
||||||
sidekiq (~> 5)
|
sidekiq (~> 5)
|
||||||
gitlab-styles (4.2.0)
|
gitlab-styles (4.3.0)
|
||||||
rubocop (~> 0.82.0)
|
rubocop (~> 0.82.0)
|
||||||
rubocop-gitlab-security (~> 0.1.0)
|
rubocop-gitlab-security (~> 0.1.0)
|
||||||
rubocop-performance (~> 1.5.2)
|
rubocop-performance (~> 1.5.2)
|
||||||
|
@ -439,19 +453,19 @@ GEM
|
||||||
signet (~> 0.14)
|
signet (~> 0.14)
|
||||||
gpgme (2.0.20)
|
gpgme (2.0.20)
|
||||||
mini_portile2 (~> 2.3)
|
mini_portile2 (~> 2.3)
|
||||||
grape (1.1.0)
|
grape (1.4.0)
|
||||||
activesupport
|
activesupport
|
||||||
builder
|
builder
|
||||||
|
dry-types (>= 1.1)
|
||||||
mustermann-grape (~> 1.0.0)
|
mustermann-grape (~> 1.0.0)
|
||||||
rack (>= 1.3.0)
|
rack (>= 1.3.0)
|
||||||
rack-accept
|
rack-accept
|
||||||
virtus (>= 1.0.0)
|
|
||||||
grape-entity (0.7.1)
|
grape-entity (0.7.1)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
multi_json (>= 1.3.2)
|
multi_json (>= 1.3.2)
|
||||||
grape-path-helpers (1.2.0)
|
grape-path-helpers (1.3.0)
|
||||||
activesupport
|
activesupport
|
||||||
grape (~> 1.0)
|
grape (~> 1.3)
|
||||||
rake (~> 12)
|
rake (~> 12)
|
||||||
grape_logging (1.8.3)
|
grape_logging (1.8.3)
|
||||||
grape
|
grape
|
||||||
|
@ -575,7 +589,8 @@ GEM
|
||||||
kgio (2.11.3)
|
kgio (2.11.3)
|
||||||
knapsack (1.17.0)
|
knapsack (1.17.0)
|
||||||
rake
|
rake
|
||||||
kramdown (2.1.0)
|
kramdown (2.2.1)
|
||||||
|
rexml
|
||||||
kramdown-parser-gfm (1.1.0)
|
kramdown-parser-gfm (1.1.0)
|
||||||
kramdown (~> 2.0)
|
kramdown (~> 2.0)
|
||||||
kubeclient (4.6.0)
|
kubeclient (4.6.0)
|
||||||
|
@ -641,9 +656,10 @@ GEM
|
||||||
multi_xml (0.6.0)
|
multi_xml (0.6.0)
|
||||||
multipart-post (2.1.1)
|
multipart-post (2.1.1)
|
||||||
murmurhash3 (0.1.6)
|
murmurhash3 (0.1.6)
|
||||||
mustermann (1.0.3)
|
mustermann (1.1.1)
|
||||||
mustermann-grape (1.0.0)
|
ruby2_keywords (~> 0.0.1)
|
||||||
mustermann (~> 1.0.0)
|
mustermann-grape (1.0.1)
|
||||||
|
mustermann (>= 1.0.0)
|
||||||
nakayoshi_fork (0.0.4)
|
nakayoshi_fork (0.0.4)
|
||||||
nap (1.1.0)
|
nap (1.1.0)
|
||||||
nenv (0.3.0)
|
nenv (0.3.0)
|
||||||
|
@ -671,6 +687,7 @@ GEM
|
||||||
octokit (4.15.0)
|
octokit (4.15.0)
|
||||||
faraday (>= 0.9)
|
faraday (>= 0.9)
|
||||||
sawyer (~> 0.8.0, >= 0.5.3)
|
sawyer (~> 0.8.0, >= 0.5.3)
|
||||||
|
oj (3.10.6)
|
||||||
omniauth (1.9.0)
|
omniauth (1.9.0)
|
||||||
hashie (>= 3.4.6, < 3.7.0)
|
hashie (>= 3.4.6, < 3.7.0)
|
||||||
rack (>= 1.6.2, < 3)
|
rack (>= 1.6.2, < 3)
|
||||||
|
@ -801,7 +818,7 @@ GEM
|
||||||
rack
|
rack
|
||||||
rack-test (1.1.0)
|
rack-test (1.1.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rack-timeout (0.5.1)
|
rack-timeout (0.5.2)
|
||||||
rails (6.0.3.1)
|
rails (6.0.3.1)
|
||||||
actioncable (= 6.0.3.1)
|
actioncable (= 6.0.3.1)
|
||||||
actionmailbox (= 6.0.3.1)
|
actionmailbox (= 6.0.3.1)
|
||||||
|
@ -890,7 +907,7 @@ GEM
|
||||||
rexml (3.2.4)
|
rexml (3.2.4)
|
||||||
rinku (2.0.0)
|
rinku (2.0.0)
|
||||||
rotp (2.1.2)
|
rotp (2.1.2)
|
||||||
rouge (3.19.0)
|
rouge (3.21.0)
|
||||||
rqrcode (0.7.0)
|
rqrcode (0.7.0)
|
||||||
chunky_png
|
chunky_png
|
||||||
rqrcode-rails3 (0.1.7)
|
rqrcode-rails3 (0.1.7)
|
||||||
|
@ -958,6 +975,7 @@ GEM
|
||||||
ruby-saml (1.7.2)
|
ruby-saml (1.7.2)
|
||||||
nokogiri (>= 1.5.10)
|
nokogiri (>= 1.5.10)
|
||||||
ruby-statistics (2.1.2)
|
ruby-statistics (2.1.2)
|
||||||
|
ruby2_keywords (0.0.2)
|
||||||
ruby_dep (1.5.0)
|
ruby_dep (1.5.0)
|
||||||
ruby_parser (3.13.1)
|
ruby_parser (3.13.1)
|
||||||
sexp_processor (~> 4.9)
|
sexp_processor (~> 4.9)
|
||||||
|
@ -1003,11 +1021,11 @@ GEM
|
||||||
shellany (0.0.1)
|
shellany (0.0.1)
|
||||||
shoulda-matchers (4.0.1)
|
shoulda-matchers (4.0.1)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
sidekiq (5.2.7)
|
sidekiq (5.2.9)
|
||||||
connection_pool (~> 2.2, >= 2.2.2)
|
connection_pool (~> 2.2, >= 2.2.2)
|
||||||
rack (>= 1.5.0)
|
rack (~> 2.0)
|
||||||
rack-protection (>= 1.5.0)
|
rack-protection (>= 1.5.0)
|
||||||
redis (>= 3.3.5, < 5)
|
redis (>= 3.3.5, < 4.2)
|
||||||
sidekiq-cron (1.0.4)
|
sidekiq-cron (1.0.4)
|
||||||
fugit (~> 1.1)
|
fugit (~> 1.1)
|
||||||
sidekiq (>= 4.2.1)
|
sidekiq (>= 4.2.1)
|
||||||
|
@ -1020,6 +1038,8 @@ GEM
|
||||||
simplecov (0.18.5)
|
simplecov (0.18.5)
|
||||||
docile (~> 1.1)
|
docile (~> 1.1)
|
||||||
simplecov-html (~> 0.11)
|
simplecov-html (~> 0.11)
|
||||||
|
simplecov-cobertura (1.3.1)
|
||||||
|
simplecov (~> 0.8)
|
||||||
simplecov-html (0.12.2)
|
simplecov-html (0.12.2)
|
||||||
sixarm_ruby_unaccent (1.2.0)
|
sixarm_ruby_unaccent (1.2.0)
|
||||||
slack-messenger (2.3.3)
|
slack-messenger (2.3.3)
|
||||||
|
@ -1119,11 +1139,6 @@ GEM
|
||||||
activerecord (>= 3.0)
|
activerecord (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
version_sorter (2.2.4)
|
version_sorter (2.2.4)
|
||||||
virtus (1.0.5)
|
|
||||||
axiom-types (~> 0.1)
|
|
||||||
coercible (~> 1.0)
|
|
||||||
descendants_tracker (~> 0.0, >= 0.0.3)
|
|
||||||
equalizer (~> 0.0, >= 0.0.9)
|
|
||||||
vmstat (2.3.0)
|
vmstat (2.3.0)
|
||||||
warden (1.2.8)
|
warden (1.2.8)
|
||||||
rack (>= 2.0.6)
|
rack (>= 2.0.6)
|
||||||
|
@ -1155,13 +1170,13 @@ PLATFORMS
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
RedCloth (~> 4.3.2)
|
RedCloth (~> 4.3.2)
|
||||||
ace-rails-ap (~> 4.1.0)
|
ace-rails-ap (~> 4.1.0)
|
||||||
acme-client (~> 2.0.5)
|
acme-client (~> 2.0, >= 2.0.6)
|
||||||
activerecord-explain-analyze (~> 0.1)
|
activerecord-explain-analyze (~> 0.1)
|
||||||
acts-as-taggable-on (~> 6.0)
|
acts-as-taggable-on (~> 6.0)
|
||||||
addressable (~> 2.7)
|
addressable (~> 2.7)
|
||||||
akismet (~> 3.0)
|
akismet (~> 3.0)
|
||||||
apollo_upload_server (~> 2.0.0.beta3)
|
apollo_upload_server (~> 2.0.0.beta3)
|
||||||
asana (~> 0.9)
|
asana (= 0.10.0)
|
||||||
asciidoctor (~> 2.0.10)
|
asciidoctor (~> 2.0.10)
|
||||||
asciidoctor-include-ext (~> 0.3.1)
|
asciidoctor-include-ext (~> 0.3.1)
|
||||||
asciidoctor-plantuml (~> 0.0.12)
|
asciidoctor-plantuml (~> 0.0.12)
|
||||||
|
@ -1175,7 +1190,7 @@ DEPENDENCIES
|
||||||
bcrypt_pbkdf (~> 1.0)
|
bcrypt_pbkdf (~> 1.0)
|
||||||
benchmark-ips (~> 2.3.0)
|
benchmark-ips (~> 2.3.0)
|
||||||
benchmark-memory (~> 0.1)
|
benchmark-memory (~> 0.1)
|
||||||
better_errors (~> 2.5.0)
|
better_errors (~> 2.7.1)
|
||||||
binding_of_caller (~> 0.8.0)
|
binding_of_caller (~> 0.8.0)
|
||||||
bootsnap (~> 1.4.6)
|
bootsnap (~> 1.4.6)
|
||||||
bootstrap_form (~> 4.2.0)
|
bootstrap_form (~> 4.2.0)
|
||||||
|
@ -1236,10 +1251,10 @@ DEPENDENCIES
|
||||||
gettext (~> 3.2.2)
|
gettext (~> 3.2.2)
|
||||||
gettext_i18n_rails (~> 1.8.0)
|
gettext_i18n_rails (~> 1.8.0)
|
||||||
gettext_i18n_rails_js (~> 1.3)
|
gettext_i18n_rails_js (~> 1.3)
|
||||||
gitaly (~> 13.1.0.pre.rc1)
|
gitaly (~> 13.2.0.pre.rc2)
|
||||||
github-markup (~> 1.7.0)
|
github-markup (~> 1.7.0)
|
||||||
gitlab-chronic (~> 0.10.5)
|
gitlab-chronic (~> 0.10.5)
|
||||||
gitlab-labkit (= 0.12.0)
|
gitlab-labkit (= 0.12.1)
|
||||||
gitlab-license (~> 1.0)
|
gitlab-license (~> 1.0)
|
||||||
gitlab-mail_room (~> 0.0.6)
|
gitlab-mail_room (~> 0.0.6)
|
||||||
gitlab-markup (~> 1.7.1)
|
gitlab-markup (~> 1.7.1)
|
||||||
|
@ -1247,16 +1262,16 @@ DEPENDENCIES
|
||||||
gitlab-puma (~> 4.3.3.gitlab.2)
|
gitlab-puma (~> 4.3.3.gitlab.2)
|
||||||
gitlab-puma_worker_killer (~> 0.1.1.gitlab.1)
|
gitlab-puma_worker_killer (~> 0.1.1.gitlab.1)
|
||||||
gitlab-sidekiq-fetcher (= 0.5.2)
|
gitlab-sidekiq-fetcher (= 0.5.2)
|
||||||
gitlab-styles (~> 4.2.0)
|
gitlab-styles (~> 4.3.0)
|
||||||
gitlab_chronic_duration (~> 0.10.6.2)
|
gitlab_chronic_duration (~> 0.10.6.2)
|
||||||
gitlab_omniauth-ldap (~> 2.1.1)
|
gitlab_omniauth-ldap (~> 2.1.1)
|
||||||
gon (~> 6.2)
|
gon (~> 6.2)
|
||||||
google-api-client (~> 0.33)
|
google-api-client (~> 0.33)
|
||||||
google-protobuf (~> 3.8.0)
|
google-protobuf (~> 3.8.0)
|
||||||
gpgme (~> 2.0.19)
|
gpgme (~> 2.0.19)
|
||||||
grape (~> 1.1.0)
|
grape (= 1.4.0)
|
||||||
grape-entity (~> 0.7.1)
|
grape-entity (~> 0.7.1)
|
||||||
grape-path-helpers (~> 1.2)
|
grape-path-helpers (~> 1.3)
|
||||||
grape_logging (~> 1.7)
|
grape_logging (~> 1.7)
|
||||||
graphiql-rails (~> 1.4.10)
|
graphiql-rails (~> 1.4.10)
|
||||||
graphql (~> 1.10.5)
|
graphql (~> 1.10.5)
|
||||||
|
@ -1282,6 +1297,7 @@ DEPENDENCIES
|
||||||
jwt (~> 2.1.0)
|
jwt (~> 2.1.0)
|
||||||
kaminari (~> 1.0)
|
kaminari (~> 1.0)
|
||||||
knapsack (~> 1.17)
|
knapsack (~> 1.17)
|
||||||
|
kramdown (~> 2.2.1)
|
||||||
kubeclient (~> 4.6.0)
|
kubeclient (~> 4.6.0)
|
||||||
letter_opener_web (~> 1.3.4)
|
letter_opener_web (~> 1.3.4)
|
||||||
license_finder (~> 5.4)
|
license_finder (~> 5.4)
|
||||||
|
@ -1297,6 +1313,7 @@ DEPENDENCIES
|
||||||
mimemagic (~> 0.3.2)
|
mimemagic (~> 0.3.2)
|
||||||
mini_magick
|
mini_magick
|
||||||
minitest (~> 5.11.0)
|
minitest (~> 5.11.0)
|
||||||
|
multi_json (~> 1.14.1)
|
||||||
nakayoshi_fork (~> 0.0.4)
|
nakayoshi_fork (~> 0.0.4)
|
||||||
net-ldap
|
net-ldap
|
||||||
net-ntp
|
net-ntp
|
||||||
|
@ -1304,6 +1321,7 @@ DEPENDENCIES
|
||||||
nokogiri (~> 1.10.9)
|
nokogiri (~> 1.10.9)
|
||||||
oauth2 (~> 1.4)
|
oauth2 (~> 1.4)
|
||||||
octokit (~> 4.15)
|
octokit (~> 4.15)
|
||||||
|
oj (~> 3.10.6)
|
||||||
omniauth (~> 1.8)
|
omniauth (~> 1.8)
|
||||||
omniauth-auth0 (~> 2.0.0)
|
omniauth-auth0 (~> 2.0.0)
|
||||||
omniauth-authentiq (~> 0.3.3)
|
omniauth-authentiq (~> 0.3.3)
|
||||||
|
@ -1335,7 +1353,7 @@ DEPENDENCIES
|
||||||
rack-cors (~> 1.0.6)
|
rack-cors (~> 1.0.6)
|
||||||
rack-oauth2 (~> 1.9.3)
|
rack-oauth2 (~> 1.9.3)
|
||||||
rack-proxy (~> 0.6.0)
|
rack-proxy (~> 0.6.0)
|
||||||
rack-timeout
|
rack-timeout (~> 0.5.1)
|
||||||
rails (~> 6.0.3.1)
|
rails (~> 6.0.3.1)
|
||||||
rails-controller-testing
|
rails-controller-testing
|
||||||
rails-i18n (~> 6.0)
|
rails-i18n (~> 6.0)
|
||||||
|
@ -1352,7 +1370,7 @@ DEPENDENCIES
|
||||||
request_store (~> 1.5)
|
request_store (~> 1.5)
|
||||||
responders (~> 3.0)
|
responders (~> 3.0)
|
||||||
retriable (~> 3.1.2)
|
retriable (~> 3.1.2)
|
||||||
rouge (~> 3.19.0)
|
rouge (~> 3.21.0)
|
||||||
rqrcode-rails3 (~> 0.1.7)
|
rqrcode-rails3 (~> 0.1.7)
|
||||||
rspec-parameterized
|
rspec-parameterized
|
||||||
rspec-rails (~> 4.0.0)
|
rspec-rails (~> 4.0.0)
|
||||||
|
@ -1380,6 +1398,7 @@ DEPENDENCIES
|
||||||
sidekiq-cron (~> 1.0)
|
sidekiq-cron (~> 1.0)
|
||||||
simple_po_parser (~> 1.1.2)
|
simple_po_parser (~> 1.1.2)
|
||||||
simplecov (~> 0.18.5)
|
simplecov (~> 0.18.5)
|
||||||
|
simplecov-cobertura (~> 1.3.1)
|
||||||
slack-messenger (~> 2.3.3)
|
slack-messenger (~> 2.3.3)
|
||||||
snowplow-tracker (~> 0.6.1)
|
snowplow-tracker (~> 0.6.1)
|
||||||
spring (~> 2.0.0)
|
spring (~> 2.0.0)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
13.1.6
|
13.2.1
|
||||||
|
|
1
app/assets/images/confluence.svg
Normal file
1
app/assets/images/confluence.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#344563"/><stop offset=".68" stop-color="#637088"/><stop offset="1" stop-color="#7a869a"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="14.873" x2="5.739" xlink:href="#a" y1="15.883" y2="10.625"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="-168376" x2="-168177" xlink:href="#a" y1="-6722.4" y2="-6493.53"/><path d="m1.517 11.68c-.15.243-.32.53-.453.757a.462.462 0 0 0 .155.63l3.013 1.863a.466.466 0 0 0 .645-.158l.445-.735c1.197-1.97 2.402-1.732 4.571-.703l2.995 1.424a.468.468 0 0 0 .626-.232l1.448-3.24a.466.466 0 0 0 -.229-.606c-.633-.298-1.89-.89-3.016-1.434-4.089-2.004-7.551-1.86-10.2 2.434z" fill="url(#b)"/><path d="m14.479 4.315c.15-.243.324-.53.456-.758a.46.46 0 0 0 -.158-.63l-3.025-1.857a.464.464 0 0 0 -.644.158 22.81 22.81 0 0 1 -.446.736c-1.196 1.972-2.4 1.733-4.567.703l-2.993-1.424a.468.468 0 0 0 -.625.231l-1.437 3.246a.46.46 0 0 0 .225.607c.633.298 1.892.89 3.014 1.435 4.097 1.99 7.556 1.858 10.199-2.446z" fill="url(#c)"/></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
app/assets/images/logos/jira-gray.svg
Normal file
1
app/assets/images/logos/jira-gray.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg id="Logos" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="80" height="80" viewBox="0 0 80 80"><defs><style>.cls-1{fill:#7a869a;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:url(#linear-gradient-2);}</style><linearGradient id="linear-gradient" x1="38.11" y1="18.54" x2="23.17" y2="33.48" gradientUnits="userSpaceOnUse"><stop offset="0.18" stop-color="#344563"/><stop offset="1" stop-color="#7a869a"/></linearGradient><linearGradient id="linear-gradient-2" x1="42.07" y1="61.47" x2="56.98" y2="46.55" xlink:href="#linear-gradient"/></defs><title>jira software-icon-gradient-neutral</title><path class="cls-1" d="M74.18,38,43,6.9l-3-3h0L16.58,27.32h0L5.86,38a2.86,2.86,0,0,0,0,4.05L27.28,63.51,40,76.25,63.47,52.81l.36-.36L74.18,42.09A2.86,2.86,0,0,0,74.18,38ZM40,50.77l-10.7-10.7L40,29.37l10.7,10.7Z"/><path class="cls-2" d="M40,29.37A18,18,0,0,1,40,4L16.54,27.37,29.28,40.11,40,29.37Z"/><path class="cls-3" d="M50.75,40,40,50.77a18,18,0,0,1,0,25.48h0L63.5,52.78Z"/></svg>
|
After Width: | Height: | Size: 1,016 B |
|
@ -12,18 +12,21 @@ import {
|
||||||
GlTable,
|
GlTable,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import query from '../graphql/queries/details.query.graphql';
|
import alertQuery from '../graphql/queries/details.query.graphql';
|
||||||
|
import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql';
|
||||||
import { fetchPolicies } from '~/lib/graphql';
|
import { fetchPolicies } from '~/lib/graphql';
|
||||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||||
import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user';
|
import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user';
|
||||||
import initUserPopovers from '~/user_popovers';
|
import initUserPopovers from '~/user_popovers';
|
||||||
import { ALERTS_SEVERITY_LABELS, trackAlertsDetailsViewsOptions } from '../constants';
|
import { ALERTS_SEVERITY_LABELS, trackAlertsDetailsViewsOptions } from '../constants';
|
||||||
import createIssueQuery from '../graphql/mutations/create_issue_from_alert.graphql';
|
import createIssueMutation from '../graphql/mutations/create_issue_from_alert.mutation.graphql';
|
||||||
|
import toggleSidebarStatusMutation from '../graphql/mutations/toggle_sidebar_status.mutation.graphql';
|
||||||
import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
|
import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
import { toggleContainerClasses } from '~/lib/utils/dom_utils';
|
import { toggleContainerClasses } from '~/lib/utils/dom_utils';
|
||||||
import SystemNote from './system_notes/system_note.vue';
|
import SystemNote from './system_notes/system_note.vue';
|
||||||
import AlertSidebar from './alert_sidebar.vue';
|
import AlertSidebar from './alert_sidebar.vue';
|
||||||
|
import AlertMetrics from './alert_metrics.vue';
|
||||||
|
|
||||||
const containerEl = document.querySelector('.page-with-contextual-sidebar');
|
const containerEl = document.querySelector('.page-with-contextual-sidebar');
|
||||||
|
|
||||||
|
@ -34,6 +37,7 @@ export default {
|
||||||
),
|
),
|
||||||
fullAlertDetailsTitle: s__('AlertManagement|Alert details'),
|
fullAlertDetailsTitle: s__('AlertManagement|Alert details'),
|
||||||
overviewTitle: s__('AlertManagement|Overview'),
|
overviewTitle: s__('AlertManagement|Overview'),
|
||||||
|
metricsTitle: s__('AlertManagement|Metrics'),
|
||||||
reportedAt: s__('AlertManagement|Reported %{when}'),
|
reportedAt: s__('AlertManagement|Reported %{when}'),
|
||||||
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
|
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
|
||||||
},
|
},
|
||||||
|
@ -51,25 +55,29 @@ export default {
|
||||||
TimeAgoTooltip,
|
TimeAgoTooltip,
|
||||||
AlertSidebar,
|
AlertSidebar,
|
||||||
SystemNote,
|
SystemNote,
|
||||||
|
AlertMetrics,
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
projectPath: {
|
||||||
|
default: '',
|
||||||
},
|
},
|
||||||
props: {
|
|
||||||
alertId: {
|
alertId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
default: '',
|
||||||
},
|
},
|
||||||
projectPath: {
|
projectId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
default: '',
|
||||||
},
|
},
|
||||||
projectIssuesPath: {
|
projectIssuesPath: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
alert: {
|
alert: {
|
||||||
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
||||||
query,
|
query: alertQuery,
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
fullPath: this.projectPath,
|
fullPath: this.projectPath,
|
||||||
|
@ -84,15 +92,18 @@ export default {
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
sidebarStatus: {
|
||||||
|
query: sidebarStatusQuery,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
alert: null,
|
alert: null,
|
||||||
errored: false,
|
errored: false,
|
||||||
|
sidebarStatus: false,
|
||||||
isErrorDismissed: false,
|
isErrorDismissed: false,
|
||||||
createIssueError: '',
|
createIssueError: '',
|
||||||
issueCreationInProgress: false,
|
issueCreationInProgress: false,
|
||||||
sidebarCollapsed: false,
|
|
||||||
sidebarErrorMessage: '',
|
sidebarErrorMessage: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -128,10 +139,10 @@ export default {
|
||||||
this.sidebarErrorMessage = '';
|
this.sidebarErrorMessage = '';
|
||||||
},
|
},
|
||||||
toggleSidebar() {
|
toggleSidebar() {
|
||||||
this.sidebarCollapsed = !this.sidebarCollapsed;
|
this.$apollo.mutate({ mutation: toggleSidebarStatusMutation });
|
||||||
toggleContainerClasses(containerEl, {
|
toggleContainerClasses(containerEl, {
|
||||||
'right-sidebar-collapsed': this.sidebarCollapsed,
|
'right-sidebar-collapsed': !this.sidebarStatus,
|
||||||
'right-sidebar-expanded': !this.sidebarCollapsed,
|
'right-sidebar-expanded': this.sidebarStatus,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleAlertSidebarError(errorMessage) {
|
handleAlertSidebarError(errorMessage) {
|
||||||
|
@ -143,7 +154,7 @@ export default {
|
||||||
|
|
||||||
this.$apollo
|
this.$apollo
|
||||||
.mutate({
|
.mutate({
|
||||||
mutation: createIssueQuery,
|
mutation: createIssueMutation,
|
||||||
variables: {
|
variables: {
|
||||||
iid: this.alert.iid,
|
iid: this.alert.iid,
|
||||||
projectPath: this.projectPath,
|
projectPath: this.projectPath,
|
||||||
|
@ -169,9 +180,6 @@ export default {
|
||||||
const { category, action } = trackAlertsDetailsViewsOptions;
|
const { category, action } = trackAlertsDetailsViewsOptions;
|
||||||
Tracking.event(category, action);
|
Tracking.event(category, action);
|
||||||
},
|
},
|
||||||
alertRefresh() {
|
|
||||||
this.$apollo.queries.alert.refetch();
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -179,7 +187,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<gl-alert v-if="showErrorMsg" variant="danger" @dismiss="dismissError">
|
<gl-alert v-if="showErrorMsg" variant="danger" @dismiss="dismissError">
|
||||||
{{ sidebarErrorMessage || $options.i18n.errorMsg }}
|
<p v-html="sidebarErrorMessage || $options.i18n.errorMsg"></p>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
<gl-alert
|
<gl-alert
|
||||||
v-if="createIssueError"
|
v-if="createIssueError"
|
||||||
|
@ -193,10 +201,10 @@ export default {
|
||||||
<div
|
<div
|
||||||
v-if="alert"
|
v-if="alert"
|
||||||
class="alert-management-details gl-relative"
|
class="alert-management-details gl-relative"
|
||||||
:class="{ 'pr-sm-8': sidebarCollapsed }"
|
:class="{ 'pr-sm-8': sidebarStatus }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-200 gl-border-b-solid flex-column flex-sm-row"
|
class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid flex-column flex-sm-row"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
data-testid="alert-header"
|
data-testid="alert-header"
|
||||||
|
@ -324,14 +332,14 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
</gl-table>
|
</gl-table>
|
||||||
</gl-tab>
|
</gl-tab>
|
||||||
|
<gl-tab data-testId="metricsTab" :title="$options.i18n.metricsTitle">
|
||||||
|
<alert-metrics :dashboard-url="alert.metricsDashboardUrl" />
|
||||||
|
</gl-tab>
|
||||||
</gl-tabs>
|
</gl-tabs>
|
||||||
<alert-sidebar
|
<alert-sidebar
|
||||||
:project-path="projectPath"
|
|
||||||
:alert="alert"
|
:alert="alert"
|
||||||
:sidebar-collapsed="sidebarCollapsed"
|
|
||||||
@alert-refresh="alertRefresh"
|
|
||||||
@toggle-sidebar="toggleSidebar"
|
@toggle-sidebar="toggleSidebar"
|
||||||
@alert-sidebar-error="handleAlertSidebarError"
|
@alert-error="handleAlertSidebarError"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<script>
|
||||||
|
import { GlEmptyState, GlButton } from '@gitlab/ui';
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
i18n: {
|
||||||
|
emptyState: {
|
||||||
|
opsgenie: {
|
||||||
|
title: s__('AlertManagement|Opsgenie is enabled'),
|
||||||
|
info: s__(
|
||||||
|
'AlertManagement|You have enabled the Opsgenie integration. Your alerts will be visible directly in Opsgenie.',
|
||||||
|
),
|
||||||
|
buttonText: s__('AlertManagement|View alerts in Opsgenie'),
|
||||||
|
},
|
||||||
|
gitlab: {
|
||||||
|
title: s__('AlertManagement|Surface alerts in GitLab'),
|
||||||
|
info: s__(
|
||||||
|
'AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents.',
|
||||||
|
),
|
||||||
|
buttonText: s__('AlertManagement|Authorize external service'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
moreInformation: s__('AlertManagement|More information'),
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
GlEmptyState,
|
||||||
|
GlButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
enableAlertManagementPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
userCanEnableAlertManagement: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
emptyAlertSvgPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
opsgenieMvcEnabled: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
opsgenieMvcTargetUrl: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
emptyState() {
|
||||||
|
return {
|
||||||
|
...(this.opsgenieMvcEnabled
|
||||||
|
? this.$options.i18n.emptyState.opsgenie
|
||||||
|
: this.$options.i18n.emptyState.gitlab),
|
||||||
|
link: this.opsgenieMvcEnabled ? this.opsgenieMvcTargetUrl : this.enableAlertManagementPath,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
alertsCanBeEnabled() {
|
||||||
|
return this.userCanEnableAlertManagement || this.opsgenieMvcEnabled;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<gl-empty-state :title="emptyState.title" :svg-path="emptyAlertSvgPath">
|
||||||
|
<template #description>
|
||||||
|
<div class="gl-display-block">
|
||||||
|
<span>{{ emptyState.info }}</span>
|
||||||
|
<a
|
||||||
|
v-if="!opsgenieMvcEnabled"
|
||||||
|
href="/help/user/project/operations/alert_management.html"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{{ $options.i18n.moreInformation }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div v-if="alertsCanBeEnabled" class="gl-display-block center gl-pt-4">
|
||||||
|
<gl-button category="primary" variant="success" :href="emptyState.link">
|
||||||
|
{{ emptyState.buttonText }}
|
||||||
|
</gl-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</gl-empty-state>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,75 @@
|
||||||
|
<script>
|
||||||
|
import Tracking from '~/tracking';
|
||||||
|
import { trackAlertListViewsOptions } from '../constants';
|
||||||
|
import AlertManagementEmptyState from './alert_management_empty_state.vue';
|
||||||
|
import AlertManagementTable from './alert_management_table.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AlertManagementEmptyState,
|
||||||
|
AlertManagementTable,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
projectPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
alertManagementEnabled: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
enableAlertManagementPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
populatingAlertsHelpUrl: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
userCanEnableAlertManagement: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
emptyAlertSvgPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
opsgenieMvcEnabled: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
opsgenieMvcTargetUrl: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.trackPageViews();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
trackPageViews() {
|
||||||
|
const { category, action } = trackAlertListViewsOptions;
|
||||||
|
Tracking.event(category, action);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<alert-management-table
|
||||||
|
v-if="alertManagementEnabled"
|
||||||
|
:populating-alerts-help-url="populatingAlertsHelpUrl"
|
||||||
|
:project-path="projectPath"
|
||||||
|
/>
|
||||||
|
<alert-management-empty-state
|
||||||
|
v-else
|
||||||
|
:empty-alert-svg-path="emptyAlertSvgPath"
|
||||||
|
:enable-alert-management-path="enableAlertManagementPath"
|
||||||
|
:user-can-enable-alert-management="userCanEnableAlertManagement"
|
||||||
|
:opsgenie-mvc-enabled="opsgenieMvcEnabled"
|
||||||
|
:opsgenie-mvc-target-url="opsgenieMvcTargetUrl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,23 +1,24 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
GlEmptyState,
|
|
||||||
GlDeprecatedButton,
|
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTable,
|
GlTable,
|
||||||
GlAlert,
|
GlAlert,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlDropdown,
|
GlLink,
|
||||||
GlDropdownItem,
|
|
||||||
GlTabs,
|
GlTabs,
|
||||||
GlTab,
|
GlTab,
|
||||||
GlBadge,
|
GlBadge,
|
||||||
GlPagination,
|
GlPagination,
|
||||||
|
GlSearchBoxByType,
|
||||||
|
GlSprintf,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import createFlash from '~/flash';
|
import { __, s__ } from '~/locale';
|
||||||
import { s__ } from '~/locale';
|
import { debounce, trim } from 'lodash';
|
||||||
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
|
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
|
||||||
import { fetchPolicies } from '~/lib/graphql';
|
import { fetchPolicies } from '~/lib/graphql';
|
||||||
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
|
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||||
|
import { convertToSnakeCase } from '~/lib/utils/text_utility';
|
||||||
|
import Tracking from '~/tracking';
|
||||||
import getAlerts from '../graphql/queries/get_alerts.query.graphql';
|
import getAlerts from '../graphql/queries/get_alerts.query.graphql';
|
||||||
import getAlertsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql';
|
import getAlertsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql';
|
||||||
import {
|
import {
|
||||||
|
@ -27,11 +28,10 @@ import {
|
||||||
trackAlertListViewsOptions,
|
trackAlertListViewsOptions,
|
||||||
trackAlertStatusUpdateOptions,
|
trackAlertStatusUpdateOptions,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import updateAlertStatus from '../graphql/mutations/update_alert_status.graphql';
|
import AlertStatus from './alert_status.vue';
|
||||||
import { convertToSnakeCase } from '~/lib/utils/text_utility';
|
|
||||||
import Tracking from '~/tracking';
|
|
||||||
|
|
||||||
const tdClass = 'table-col gl-display-flex d-md-table-cell gl-align-items-center';
|
const tdClass =
|
||||||
|
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
|
||||||
const thClass = 'gl-hover-bg-blue-50';
|
const thClass = 'gl-hover-bg-blue-50';
|
||||||
const bodyTrClass =
|
const bodyTrClass =
|
||||||
'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-bg-blue-50 gl-hover-cursor-pointer gl-hover-border-b-solid gl-hover-border-blue-200';
|
'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-bg-blue-50 gl-hover-cursor-pointer gl-hover-border-b-solid gl-hover-border-blue-200';
|
||||||
|
@ -44,54 +44,57 @@ const initialPaginationState = {
|
||||||
lastPageSize: null,
|
lastPageSize: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TWELVE_HOURS_IN_MS = 12 * 60 * 60 * 1000;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
i18n: {
|
i18n: {
|
||||||
noAlertsMsg: s__(
|
noAlertsMsg: s__(
|
||||||
"AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page.",
|
'AlertManagement|No alerts available to display. See %{linkStart}enabling alert management%{linkEnd} for more information on adding alerts to the list.',
|
||||||
),
|
),
|
||||||
errorMsg: s__(
|
errorMsg: s__(
|
||||||
"AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear.",
|
"AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear.",
|
||||||
),
|
),
|
||||||
|
searchPlaceholder: __('Search or filter results...'),
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
key: 'severity',
|
key: 'severity',
|
||||||
label: s__('AlertManagement|Severity'),
|
label: s__('AlertManagement|Severity'),
|
||||||
tdClass: `${tdClass} rounded-top text-capitalize`,
|
tdClass: `${tdClass} rounded-top text-capitalize`,
|
||||||
thClass,
|
thClass: `${thClass} gl-w-eighth`,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'startedAt',
|
key: 'startedAt',
|
||||||
label: s__('AlertManagement|Start time'),
|
label: s__('AlertManagement|Start time'),
|
||||||
thClass: `${thClass} js-started-at`,
|
thClass: `${thClass} js-started-at w-15p`,
|
||||||
tdClass,
|
|
||||||
sortable: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'endedAt',
|
|
||||||
label: s__('AlertManagement|End time'),
|
|
||||||
thClass,
|
|
||||||
tdClass,
|
tdClass,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'title',
|
key: 'title',
|
||||||
label: s__('AlertManagement|Alert'),
|
label: s__('AlertManagement|Alert'),
|
||||||
thClass: `${thClass} w-30p gl-pointer-events-none`,
|
thClass: `gl-pointer-events-none`,
|
||||||
tdClass,
|
tdClass,
|
||||||
sortable: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'eventCount',
|
key: 'eventCount',
|
||||||
label: s__('AlertManagement|Events'),
|
label: s__('AlertManagement|Events'),
|
||||||
thClass: `${thClass} text-right gl-pr-9 w-3rem`,
|
thClass: `${thClass} text-right gl-w-12`,
|
||||||
tdClass: `${tdClass} text-md-right`,
|
tdClass: `${tdClass} text-md-right`,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'issue',
|
||||||
|
label: s__('AlertManagement|Issue'),
|
||||||
|
thClass: 'gl-w-12 gl-pointer-events-none',
|
||||||
|
tdClass,
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'assignees',
|
key: 'assignees',
|
||||||
label: s__('AlertManagement|Assignees'),
|
label: s__('AlertManagement|Assignees'),
|
||||||
|
thClass: 'gl-w-eighth gl-pointer-events-none',
|
||||||
tdClass,
|
tdClass,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -102,46 +105,29 @@ export default {
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
statuses: {
|
|
||||||
TRIGGERED: s__('AlertManagement|Triggered'),
|
|
||||||
ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
|
|
||||||
RESOLVED: s__('AlertManagement|Resolved'),
|
|
||||||
},
|
|
||||||
severityLabels: ALERTS_SEVERITY_LABELS,
|
severityLabels: ALERTS_SEVERITY_LABELS,
|
||||||
statusTabs: ALERTS_STATUS_TABS,
|
statusTabs: ALERTS_STATUS_TABS,
|
||||||
components: {
|
components: {
|
||||||
GlEmptyState,
|
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTable,
|
GlTable,
|
||||||
GlAlert,
|
GlAlert,
|
||||||
GlDeprecatedButton,
|
|
||||||
TimeAgo,
|
TimeAgo,
|
||||||
GlDropdown,
|
|
||||||
GlDropdownItem,
|
|
||||||
GlIcon,
|
GlIcon,
|
||||||
|
GlLink,
|
||||||
GlTabs,
|
GlTabs,
|
||||||
GlTab,
|
GlTab,
|
||||||
GlBadge,
|
GlBadge,
|
||||||
GlPagination,
|
GlPagination,
|
||||||
|
GlSearchBoxByType,
|
||||||
|
GlSprintf,
|
||||||
|
AlertStatus,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
projectPath: {
|
projectPath: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
alertManagementEnabled: {
|
populatingAlertsHelpUrl: {
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
enableAlertManagementPath: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
userCanEnableAlertManagement: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
emptyAlertSvgPath: {
|
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
@ -152,6 +138,7 @@ export default {
|
||||||
query: getAlerts,
|
query: getAlerts,
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
|
searchTerm: this.searchTerm,
|
||||||
projectPath: this.projectPath,
|
projectPath: this.projectPath,
|
||||||
statuses: this.statusFilter,
|
statuses: this.statusFilter,
|
||||||
sort: this.sort,
|
sort: this.sort,
|
||||||
|
@ -164,9 +151,20 @@ export default {
|
||||||
update(data) {
|
update(data) {
|
||||||
const { alertManagementAlerts: { nodes: list = [], pageInfo = {} } = {} } =
|
const { alertManagementAlerts: { nodes: list = [], pageInfo = {} } = {} } =
|
||||||
data.project || {};
|
data.project || {};
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
const listWithData = list.map(alert => {
|
||||||
|
const then = new Date(alert.startedAt);
|
||||||
|
const diff = now - then;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
list,
|
...alert,
|
||||||
|
isNew: diff < TWELVE_HOURS_IN_MS,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
list: listWithData,
|
||||||
pageInfo,
|
pageInfo,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -178,6 +176,7 @@ export default {
|
||||||
query: getAlertsCountByStatus,
|
query: getAlertsCountByStatus,
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
|
searchTerm: this.searchTerm,
|
||||||
projectPath: this.projectPath,
|
projectPath: this.projectPath,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -188,7 +187,9 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
searchTerm: '',
|
||||||
errored: false,
|
errored: false,
|
||||||
|
errorMessage: '',
|
||||||
isAlertDismissed: false,
|
isAlertDismissed: false,
|
||||||
isErrorAlertDismissed: false,
|
isErrorAlertDismissed: false,
|
||||||
sort: 'STARTED_AT_DESC',
|
sort: 'STARTED_AT_DESC',
|
||||||
|
@ -203,7 +204,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
showNoAlertsMsg() {
|
showNoAlertsMsg() {
|
||||||
return (
|
return (
|
||||||
!this.errored && !this.loading && this.alertsCount?.all === 0 && !this.isAlertDismissed
|
!this.errored &&
|
||||||
|
!this.loading &&
|
||||||
|
this.alertsCount?.all === 0 &&
|
||||||
|
!this.searchTerm &&
|
||||||
|
!this.isAlertDismissed
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
showErrorMsg() {
|
showErrorMsg() {
|
||||||
|
@ -215,9 +220,6 @@ export default {
|
||||||
hasAlerts() {
|
hasAlerts() {
|
||||||
return this.alerts?.list?.length;
|
return this.alerts?.list?.length;
|
||||||
},
|
},
|
||||||
tbodyTrClass() {
|
|
||||||
return !this.loading && this.hasAlerts ? bodyTrClass : '';
|
|
||||||
},
|
|
||||||
showPaginationControls() {
|
showPaginationControls() {
|
||||||
return Boolean(this.prevPage || this.nextPage);
|
return Boolean(this.prevPage || this.nextPage);
|
||||||
},
|
},
|
||||||
|
@ -249,30 +251,13 @@ export default {
|
||||||
this.resetPagination();
|
this.resetPagination();
|
||||||
this.sort = `${sortingColumn}_${sortingDirection}`;
|
this.sort = `${sortingColumn}_${sortingDirection}`;
|
||||||
},
|
},
|
||||||
updateAlertStatus(status, iid) {
|
onInputChange: debounce(function debounceSearch(input) {
|
||||||
this.$apollo
|
const trimmedInput = trim(input);
|
||||||
.mutate({
|
if (trimmedInput !== this.searchTerm) {
|
||||||
mutation: updateAlertStatus,
|
|
||||||
variables: {
|
|
||||||
iid,
|
|
||||||
status: status.toUpperCase(),
|
|
||||||
projectPath: this.projectPath,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.trackStatusUpdate(status);
|
|
||||||
this.$apollo.queries.alerts.refetch();
|
|
||||||
this.$apollo.queries.alertsCount.refetch();
|
|
||||||
this.resetPagination();
|
this.resetPagination();
|
||||||
})
|
this.searchTerm = trimmedInput;
|
||||||
.catch(() => {
|
}
|
||||||
createFlash(
|
}, 500),
|
||||||
s__(
|
|
||||||
'AlertManagement|There was an error while updating the status of the alert. Please try again.',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
navigateToAlertDetails({ iid }) {
|
navigateToAlertDetails({ iid }) {
|
||||||
return visitUrl(joinPaths(window.location.pathname, iid, 'details'));
|
return visitUrl(joinPaths(window.location.pathname, iid, 'details'));
|
||||||
},
|
},
|
||||||
|
@ -290,6 +275,9 @@ export default {
|
||||||
? assignees.nodes[0]?.username
|
? assignees.nodes[0]?.username
|
||||||
: s__('AlertManagement|Unassigned');
|
: s__('AlertManagement|Unassigned');
|
||||||
},
|
},
|
||||||
|
getIssueLink(item) {
|
||||||
|
return joinPaths('/', this.projectPath, '-', 'issues', item.issueIid);
|
||||||
|
},
|
||||||
handlePageChange(page) {
|
handlePageChange(page) {
|
||||||
const { startCursor, endCursor } = this.alerts.pageInfo;
|
const { startCursor, endCursor } = this.alerts.pageInfo;
|
||||||
|
|
||||||
|
@ -312,20 +300,49 @@ export default {
|
||||||
resetPagination() {
|
resetPagination() {
|
||||||
this.pagination = initialPaginationState;
|
this.pagination = initialPaginationState;
|
||||||
},
|
},
|
||||||
|
tbodyTrClass(item) {
|
||||||
|
return {
|
||||||
|
[bodyTrClass]: !this.loading && this.hasAlerts,
|
||||||
|
'new-alert': item?.isNew,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleAlertError(errorMessage) {
|
||||||
|
this.errored = true;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
},
|
||||||
|
dismissError() {
|
||||||
|
this.isErrorAlertDismissed = true;
|
||||||
|
this.errorMessage = '';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="alertManagementEnabled" class="alert-management-list">
|
<div class="alert-management-list">
|
||||||
<gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true">
|
<gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true">
|
||||||
{{ $options.i18n.noAlertsMsg }}
|
<gl-sprintf :message="$options.i18n.noAlertsMsg">
|
||||||
|
<template #link="{ content }">
|
||||||
|
<gl-link
|
||||||
|
class="gl-display-inline-block"
|
||||||
|
:href="populatingAlertsHelpUrl"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{{ content }}
|
||||||
|
</gl-link>
|
||||||
|
</template>
|
||||||
|
</gl-sprintf>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
<gl-alert v-if="showErrorMsg" variant="danger" @dismiss="isErrorAlertDismissed = true">
|
<gl-alert
|
||||||
{{ $options.i18n.errorMsg }}
|
v-if="showErrorMsg"
|
||||||
|
variant="danger"
|
||||||
|
data-testid="alert-error"
|
||||||
|
@dismiss="dismissError"
|
||||||
|
>
|
||||||
|
<p v-html="errorMessage || $options.i18n.errorMsg"></p>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
|
|
||||||
<gl-tabs @input="filterAlertsByStatus">
|
<gl-tabs content-class="gl-p-0" @input="filterAlertsByStatus">
|
||||||
<gl-tab v-for="tab in $options.statusTabs" :key="tab.status">
|
<gl-tab v-for="tab in $options.statusTabs" :key="tab.status">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ tab.title }}</span>
|
<span>{{ tab.title }}</span>
|
||||||
|
@ -336,11 +353,19 @@ export default {
|
||||||
</gl-tab>
|
</gl-tab>
|
||||||
</gl-tabs>
|
</gl-tabs>
|
||||||
|
|
||||||
|
<div class="gl-bg-gray-10 gl-p-5 gl-border-b-solid gl-border-b-1 gl-border-gray-100">
|
||||||
|
<gl-search-box-by-type
|
||||||
|
class="gl-bg-white"
|
||||||
|
:placeholder="$options.i18n.searchPlaceholder"
|
||||||
|
@input="onInputChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h4 class="d-block d-md-none my-3">
|
<h4 class="d-block d-md-none my-3">
|
||||||
{{ s__('AlertManagement|Alerts') }}
|
{{ s__('AlertManagement|Alerts') }}
|
||||||
</h4>
|
</h4>
|
||||||
<gl-table
|
<gl-table
|
||||||
class="alert-management-table mt-3"
|
class="alert-management-table"
|
||||||
:items="alerts ? alerts.list : []"
|
:items="alerts ? alerts.list : []"
|
||||||
:fields="$options.fields"
|
:fields="$options.fields"
|
||||||
:show-empty="true"
|
:show-empty="true"
|
||||||
|
@ -352,6 +377,7 @@ export default {
|
||||||
:sort-desc.sync="sortDesc"
|
:sort-desc.sync="sortDesc"
|
||||||
:sort-by.sync="sortBy"
|
:sort-by.sync="sortBy"
|
||||||
sort-icon-left
|
sort-icon-left
|
||||||
|
fixed
|
||||||
@row-clicked="navigateToAlertDetails"
|
@row-clicked="navigateToAlertDetails"
|
||||||
@sort-changed="fetchSortedData"
|
@sort-changed="fetchSortedData"
|
||||||
>
|
>
|
||||||
|
@ -374,16 +400,19 @@ export default {
|
||||||
<time-ago v-if="item.startedAt" :time="item.startedAt" />
|
<time-ago v-if="item.startedAt" :time="item.startedAt" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell(endedAt)="{ item }">
|
|
||||||
<time-ago v-if="item.endedAt" :time="item.endedAt" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #cell(eventCount)="{ item }">
|
<template #cell(eventCount)="{ item }">
|
||||||
{{ item.eventCount }}
|
{{ item.eventCount }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell(title)="{ item }">
|
<template #cell(title)="{ item }">
|
||||||
<div class="gl-max-w-full text-truncate">{{ item.title }}</div>
|
<div class="gl-max-w-full text-truncate" :title="item.title">{{ item.title }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cell(issue)="{ item }">
|
||||||
|
<gl-link v-if="item.issueIid" data-testid="issueField" :href="getIssueLink(item)">
|
||||||
|
#{{ item.issueIid }}
|
||||||
|
</gl-link>
|
||||||
|
<div v-else data-testid="issueField">{{ s__('AlertManagement|None') }}</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell(assignees)="{ item }">
|
<template #cell(assignees)="{ item }">
|
||||||
|
@ -393,22 +422,12 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell(status)="{ item }">
|
<template #cell(status)="{ item }">
|
||||||
<gl-dropdown :text="$options.statuses[item.status]" class="w-100" right>
|
<alert-status
|
||||||
<gl-dropdown-item
|
:alert="item"
|
||||||
v-for="(label, field) in $options.statuses"
|
:project-path="projectPath"
|
||||||
:key="field"
|
:is-sidebar="false"
|
||||||
@click="updateAlertStatus(label, item.iid)"
|
@alert-error="handleAlertError"
|
||||||
>
|
|
||||||
<span class="d-flex">
|
|
||||||
<gl-icon
|
|
||||||
class="flex-shrink-0 append-right-4"
|
|
||||||
:class="{ invisible: label.toUpperCase() !== item.status }"
|
|
||||||
name="mobile-issue-close"
|
|
||||||
/>
|
/>
|
||||||
{{ label }}
|
|
||||||
</span>
|
|
||||||
</gl-dropdown-item>
|
|
||||||
</gl-dropdown>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #empty>
|
<template #empty>
|
||||||
|
@ -426,36 +445,9 @@ export default {
|
||||||
:prev-page="prevPage"
|
:prev-page="prevPage"
|
||||||
:next-page="nextPage"
|
:next-page="nextPage"
|
||||||
align="center"
|
align="center"
|
||||||
class="gl-pagination prepend-top-default"
|
class="gl-pagination gl-mt-3"
|
||||||
@input="handlePageChange"
|
@input="handlePageChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<gl-empty-state
|
|
||||||
v-else
|
|
||||||
:title="s__('AlertManagement|Surface alerts in GitLab')"
|
|
||||||
:svg-path="emptyAlertSvgPath"
|
|
||||||
>
|
|
||||||
<template #description>
|
|
||||||
<div class="d-block">
|
|
||||||
<span>{{
|
|
||||||
s__(
|
|
||||||
'AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents.',
|
|
||||||
)
|
|
||||||
}}</span>
|
|
||||||
<a href="/help/user/project/operations/alert_management.html" target="_blank">
|
|
||||||
{{ s__('AlertManagement|More information') }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div v-if="userCanEnableAlertManagement" class="d-block center pt-4">
|
|
||||||
<gl-deprecated-button
|
|
||||||
category="primary"
|
|
||||||
variant="success"
|
|
||||||
:href="enableAlertManagementPath"
|
|
||||||
>
|
|
||||||
{{ s__('AlertManagement|Authorize external service') }}
|
|
||||||
</gl-deprecated-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</gl-empty-state>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
import * as Sentry from '@sentry/browser';
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
dashboardUrl: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
metricEmbedComponent: null,
|
||||||
|
namespace: 'alertMetrics',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.dashboardUrl) {
|
||||||
|
Promise.all([
|
||||||
|
import('~/monitoring/components/embeds/metric_embed.vue'),
|
||||||
|
import('~/monitoring/stores'),
|
||||||
|
])
|
||||||
|
.then(([{ default: MetricEmbed }, { monitoringDashboard }]) => {
|
||||||
|
this.$store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
[this.namespace]: monitoringDashboard,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.metricEmbedComponent = MetricEmbed;
|
||||||
|
})
|
||||||
|
.catch(e => Sentry.captureException(e));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="gl-py-3">
|
||||||
|
<div v-if="dashboardUrl" ref="metricsChart">
|
||||||
|
<component
|
||||||
|
:is="metricEmbedComponent"
|
||||||
|
v-if="metricEmbedComponent"
|
||||||
|
:dashboard-url="dashboardUrl"
|
||||||
|
:namespace="namespace"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else ref="emptyState">
|
||||||
|
{{ s__("AlertManagement|Metrics weren't available in the alerts payload.") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -4,6 +4,8 @@ import SidebarTodo from './sidebar/sidebar_todo.vue';
|
||||||
import SidebarStatus from './sidebar/sidebar_status.vue';
|
import SidebarStatus from './sidebar/sidebar_status.vue';
|
||||||
import SidebarAssignees from './sidebar/sidebar_assignees.vue';
|
import SidebarAssignees from './sidebar/sidebar_assignees.vue';
|
||||||
|
|
||||||
|
import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SidebarAssignees,
|
SidebarAssignees,
|
||||||
|
@ -11,23 +13,34 @@ export default {
|
||||||
SidebarTodo,
|
SidebarTodo,
|
||||||
SidebarStatus,
|
SidebarStatus,
|
||||||
},
|
},
|
||||||
props: {
|
inject: {
|
||||||
sidebarCollapsed: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
projectPath: {
|
projectPath: {
|
||||||
type: String,
|
default: '',
|
||||||
required: true,
|
|
||||||
},
|
},
|
||||||
|
projectId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
alert: {
|
alert: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
apollo: {
|
||||||
|
sidebarStatus: {
|
||||||
|
query: sidebarStatusQuery,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sidebarStatus: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
sidebarCollapsedClass() {
|
sidebarCollapsedClass() {
|
||||||
return this.sidebarCollapsed ? 'right-sidebar-collapsed' : 'right-sidebar-expanded';
|
return this.sidebarStatus ? 'right-sidebar-collapsed' : 'right-sidebar-expanded';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -37,23 +50,32 @@ export default {
|
||||||
<aside :class="sidebarCollapsedClass" class="right-sidebar alert-sidebar">
|
<aside :class="sidebarCollapsedClass" class="right-sidebar alert-sidebar">
|
||||||
<div class="issuable-sidebar js-issuable-update">
|
<div class="issuable-sidebar js-issuable-update">
|
||||||
<sidebar-header
|
<sidebar-header
|
||||||
:sidebar-collapsed="sidebarCollapsed"
|
:sidebar-collapsed="sidebarStatus"
|
||||||
|
:project-path="projectPath"
|
||||||
|
:alert="alert"
|
||||||
@toggle-sidebar="$emit('toggle-sidebar')"
|
@toggle-sidebar="$emit('toggle-sidebar')"
|
||||||
|
@alert-error="$emit('alert-error', $event)"
|
||||||
|
/>
|
||||||
|
<sidebar-todo
|
||||||
|
v-if="sidebarStatus"
|
||||||
|
:project-path="projectPath"
|
||||||
|
:alert="alert"
|
||||||
|
:sidebar-collapsed="sidebarStatus"
|
||||||
|
@alert-error="$emit('alert-error', $event)"
|
||||||
/>
|
/>
|
||||||
<sidebar-todo v-if="sidebarCollapsed" :sidebar-collapsed="sidebarCollapsed" />
|
|
||||||
<sidebar-status
|
<sidebar-status
|
||||||
:project-path="projectPath"
|
:project-path="projectPath"
|
||||||
:alert="alert"
|
:alert="alert"
|
||||||
@toggle-sidebar="$emit('toggle-sidebar')"
|
@toggle-sidebar="$emit('toggle-sidebar')"
|
||||||
@alert-sidebar-error="$emit('alert-sidebar-error', $event)"
|
@alert-error="$emit('alert-error', $event)"
|
||||||
/>
|
/>
|
||||||
<sidebar-assignees
|
<sidebar-assignees
|
||||||
:project-path="projectPath"
|
:project-path="projectPath"
|
||||||
|
:project-id="projectId"
|
||||||
:alert="alert"
|
:alert="alert"
|
||||||
:sidebar-collapsed="sidebarCollapsed"
|
:sidebar-collapsed="sidebarStatus"
|
||||||
@alert-refresh="$emit('alert-refresh')"
|
|
||||||
@toggle-sidebar="$emit('toggle-sidebar')"
|
@toggle-sidebar="$emit('toggle-sidebar')"
|
||||||
@alert-sidebar-error="$emit('alert-sidebar-error', $event)"
|
@alert-error="$emit('alert-error', $event)"
|
||||||
/>
|
/>
|
||||||
<div class="block"></div>
|
<div class="block"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
<script>
|
||||||
|
import { GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui';
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
import Tracking from '~/tracking';
|
||||||
|
import { trackAlertStatusUpdateOptions } from '../constants';
|
||||||
|
import updateAlertStatus from '../graphql/mutations/update_alert_status.mutation.graphql';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
i18n: {
|
||||||
|
UPDATE_ALERT_STATUS_ERROR: s__(
|
||||||
|
'AlertManagement|There was an error while updating the status of the alert.',
|
||||||
|
),
|
||||||
|
UPDATE_ALERT_STATUS_INSTRUCTION: s__('AlertManagement|Please try again.'),
|
||||||
|
},
|
||||||
|
statuses: {
|
||||||
|
TRIGGERED: s__('AlertManagement|Triggered'),
|
||||||
|
ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
|
||||||
|
RESOLVED: s__('AlertManagement|Resolved'),
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
GlDropdown,
|
||||||
|
GlDropdownItem,
|
||||||
|
GlButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
projectPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
alert: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
isDropdownShowing: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
isSidebar: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
dropdownClass() {
|
||||||
|
// eslint-disable-next-line no-nested-ternary
|
||||||
|
return this.isSidebar ? (this.isDropdownShowing ? 'show' : 'gl-display-none') : '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateAlertStatus(status) {
|
||||||
|
this.$emit('handle-updating', true);
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: updateAlertStatus,
|
||||||
|
variables: {
|
||||||
|
iid: this.alert.iid,
|
||||||
|
status: status.toUpperCase(),
|
||||||
|
projectPath: this.projectPath,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
this.trackStatusUpdate(status);
|
||||||
|
this.$emit('hide-dropdown');
|
||||||
|
|
||||||
|
const errors = resp.data?.updateAlertStatus?.errors || [];
|
||||||
|
|
||||||
|
if (errors[0]) {
|
||||||
|
this.$emit(
|
||||||
|
'alert-error',
|
||||||
|
`${this.$options.i18n.UPDATE_ALERT_STATUS_ERROR} ${errors[0]}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$emit(
|
||||||
|
'alert-error',
|
||||||
|
`${this.$options.i18n.UPDATE_ALERT_STATUS_ERROR} ${this.$options.i18n.UPDATE_ALERT_STATUS_INSTRUCTION}`,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.$emit('handle-updating', false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
trackStatusUpdate(status) {
|
||||||
|
const { category, action, label } = trackAlertStatusUpdateOptions;
|
||||||
|
Tracking.event(category, action, { label, property: status });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
|
||||||
|
<gl-dropdown
|
||||||
|
ref="dropdown"
|
||||||
|
right
|
||||||
|
:text="$options.statuses[alert.status]"
|
||||||
|
class="w-100"
|
||||||
|
toggle-class="dropdown-menu-toggle"
|
||||||
|
variant="outline-default"
|
||||||
|
@keydown.esc.native="$emit('hide-dropdown')"
|
||||||
|
@hide="$emit('hide-dropdown')"
|
||||||
|
>
|
||||||
|
<div v-if="isSidebar" class="dropdown-title text-center">
|
||||||
|
<span class="alert-title">{{ s__('AlertManagement|Assign status') }}</span>
|
||||||
|
<gl-button
|
||||||
|
:aria-label="__('Close')"
|
||||||
|
variant="link"
|
||||||
|
class="dropdown-title-button dropdown-menu-close"
|
||||||
|
icon="close"
|
||||||
|
@click="$emit('hide-dropdown')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-content dropdown-body">
|
||||||
|
<gl-dropdown-item
|
||||||
|
v-for="(label, field) in $options.statuses"
|
||||||
|
:key="field"
|
||||||
|
data-testid="statusDropdownItem"
|
||||||
|
class="gl-vertical-align-middle"
|
||||||
|
:active="label.toUpperCase() === alert.status"
|
||||||
|
:active-class="'is-active'"
|
||||||
|
@click="updateAlertStatus(label)"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</gl-dropdown-item>
|
||||||
|
</div>
|
||||||
|
</gl-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -11,20 +11,26 @@ import {
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import { s__ } from '~/locale';
|
import { s__, __ } from '~/locale';
|
||||||
import alertSetAssignees from '../../graphql/mutations/alert_set_assignees.graphql';
|
import alertSetAssignees from '../../graphql/mutations/alert_set_assignees.mutation.graphql';
|
||||||
import SidebarAssignee from './sidebar_assignee.vue';
|
import SidebarAssignee from './sidebar_assignee.vue';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
const DATA_REFETCH_DELAY = 250;
|
const DATA_REFETCH_DELAY = 250;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
i18n: {
|
||||||
FETCH_USERS_ERROR: s__(
|
FETCH_USERS_ERROR: s__(
|
||||||
'AlertManagement|There was an error while updating the assignee(s) list. Please try again.',
|
'AlertManagement|There was an error while updating the assignee(s) list. Please try again.',
|
||||||
),
|
),
|
||||||
UPDATE_ALERT_ASSIGNEES_ERROR: s__(
|
UPDATE_ALERT_ASSIGNEES_ERROR: s__(
|
||||||
'AlertManagement|There was an error while updating the assignee(s) of the alert. Please try again.',
|
'AlertManagement|There was an error while updating the assignee(s) of the alert. Please try again.',
|
||||||
),
|
),
|
||||||
|
UPDATE_ALERT_ASSIGNEES_GRAPHQL_ERROR: s__(
|
||||||
|
'AlertManagement|This assignee cannot be assigned to this alert.',
|
||||||
|
),
|
||||||
|
ASSIGNEES_BLOCK: s__('AlertManagement|Alert assignee(s): %{assignees}'),
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlDropdown,
|
GlDropdown,
|
||||||
|
@ -38,6 +44,10 @@ export default {
|
||||||
SidebarAssignee,
|
SidebarAssignee,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
projectPath: {
|
projectPath: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -73,7 +83,7 @@ export default {
|
||||||
return this.alert?.assignees?.nodes[0]?.username;
|
return this.alert?.assignees?.nodes[0]?.username;
|
||||||
},
|
},
|
||||||
assignedUser() {
|
assignedUser() {
|
||||||
return this.userName || s__('AlertManagement|None');
|
return this.userName || __('None');
|
||||||
},
|
},
|
||||||
sortedUsers() {
|
sortedUsers() {
|
||||||
return this.users
|
return this.users
|
||||||
|
@ -122,20 +132,20 @@ export default {
|
||||||
updateAssigneesDropdown() {
|
updateAssigneesDropdown() {
|
||||||
this.isDropdownSearching = true;
|
this.isDropdownSearching = true;
|
||||||
return axios
|
return axios
|
||||||
.get(this.buildUrl(gon.relative_url_root, '/autocomplete/users.json'), {
|
.get(this.buildUrl(gon.relative_url_root, '/-/autocomplete/users.json'), {
|
||||||
params: {
|
params: {
|
||||||
search: this.search,
|
search: this.search,
|
||||||
per_page: 20,
|
per_page: 20,
|
||||||
active: true,
|
active: true,
|
||||||
current_user: true,
|
current_user: true,
|
||||||
project_id: gon?.current_project_id,
|
project_id: this.projectId,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
this.users = data;
|
this.users = data;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.$emit('alert-sidebar-error', this.$options.FETCH_USERS_ERROR);
|
this.$emit('alert-error', this.$options.i18n.FETCH_USERS_ERROR);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.isDropdownSearching = false;
|
this.isDropdownSearching = false;
|
||||||
|
@ -152,12 +162,18 @@ export default {
|
||||||
projectPath: this.projectPath,
|
projectPath: this.projectPath,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(({ data: { alertSetAssignees: { errors } = [] } = {} } = {}) => {
|
||||||
this.hideDropdown();
|
this.hideDropdown();
|
||||||
this.$emit('alert-refresh');
|
|
||||||
|
if (errors[0]) {
|
||||||
|
this.$emit(
|
||||||
|
'alert-error',
|
||||||
|
`${this.$options.i18n.UPDATE_ALERT_ASSIGNEES_GRAPHQL_ERROR} ${errors[0]}.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.$emit('alert-sidebar-error', this.$options.UPDATE_ALERT_ASSIGNEES_ERROR);
|
this.$emit('alert-error', this.$options.i18n.UPDATE_ALERT_ASSIGNEES_ERROR);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
|
@ -174,7 +190,7 @@ export default {
|
||||||
<gl-loading-icon v-if="isUpdating" />
|
<gl-loading-icon v-if="isUpdating" />
|
||||||
</div>
|
</div>
|
||||||
<gl-tooltip :target="() => $refs.status" boundary="viewport" placement="left">
|
<gl-tooltip :target="() => $refs.status" boundary="viewport" placement="left">
|
||||||
<gl-sprintf :message="s__('AlertManagement|Alert assignee(s): %{assignees}')">
|
<gl-sprintf :message="$options.i18n.ASSIGNEES_BLOCK">
|
||||||
<template #assignees>
|
<template #assignees>
|
||||||
{{ assignedUser }}
|
{{ assignedUser }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -183,7 +199,7 @@ export default {
|
||||||
|
|
||||||
<div class="hide-collapsed">
|
<div class="hide-collapsed">
|
||||||
<p class="title gl-display-flex gl-justify-content-space-between">
|
<p class="title gl-display-flex gl-justify-content-space-between">
|
||||||
{{ s__('AlertManagement|Assignee') }}
|
{{ __('Assignee') }}
|
||||||
<a
|
<a
|
||||||
v-if="isEditable"
|
v-if="isEditable"
|
||||||
ref="editButton"
|
ref="editButton"
|
||||||
|
@ -192,7 +208,7 @@ export default {
|
||||||
@click="toggleFormDropdown"
|
@click="toggleFormDropdown"
|
||||||
@keydown.esc="hideDropdown"
|
@keydown.esc="hideDropdown"
|
||||||
>
|
>
|
||||||
{{ s__('AlertManagement|Edit') }}
|
{{ __('Edit') }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -207,7 +223,7 @@ export default {
|
||||||
@hide="hideDropdown"
|
@hide="hideDropdown"
|
||||||
>
|
>
|
||||||
<div class="dropdown-title">
|
<div class="dropdown-title">
|
||||||
<span class="alert-title">{{ s__('AlertManagement|Assign To') }}</span>
|
<span class="alert-title">{{ __('Assign To') }}</span>
|
||||||
<gl-button
|
<gl-button
|
||||||
:aria-label="__('Close')"
|
:aria-label="__('Close')"
|
||||||
variant="link"
|
variant="link"
|
||||||
|
@ -232,12 +248,12 @@ export default {
|
||||||
active-class="is-active"
|
active-class="is-active"
|
||||||
@click="updateAlertAssignees('')"
|
@click="updateAlertAssignees('')"
|
||||||
>
|
>
|
||||||
{{ s__('AlertManagement|Unassigned') }}
|
{{ __('Unassigned') }}
|
||||||
</gl-dropdown-item>
|
</gl-dropdown-item>
|
||||||
<gl-dropdown-divider />
|
<gl-dropdown-divider />
|
||||||
|
|
||||||
<gl-dropdown-header class="mt-0">
|
<gl-dropdown-header class="mt-0">
|
||||||
{{ s__('AlertManagement|Assignee') }}
|
{{ __('Assignee') }}
|
||||||
</gl-dropdown-header>
|
</gl-dropdown-header>
|
||||||
<sidebar-assignee
|
<sidebar-assignee
|
||||||
v-for="user in sortedUsers"
|
v-for="user in sortedUsers"
|
||||||
|
@ -248,7 +264,7 @@ export default {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<gl-dropdown-item v-else-if="userListEmpty">
|
<gl-dropdown-item v-else-if="userListEmpty">
|
||||||
{{ s__('AlertManagement|No Matching Results') }}
|
{{ __('No Matching Results') }}
|
||||||
</gl-dropdown-item>
|
</gl-dropdown-item>
|
||||||
<gl-loading-icon v-else />
|
<gl-loading-icon v-else />
|
||||||
</div>
|
</div>
|
||||||
|
@ -261,7 +277,7 @@ export default {
|
||||||
assignedUser
|
assignedUser
|
||||||
}}</span>
|
}}</span>
|
||||||
<span v-else class="gl-display-flex gl-align-items-center">
|
<span v-else class="gl-display-flex gl-align-items-center">
|
||||||
{{ s__('AlertManagement|None -') }}
|
{{ __('None') }} -
|
||||||
<gl-button
|
<gl-button
|
||||||
class="gl-pl-2"
|
class="gl-pl-2"
|
||||||
href="#"
|
href="#"
|
||||||
|
@ -269,7 +285,7 @@ export default {
|
||||||
data-testid="unassigned-users"
|
data-testid="unassigned-users"
|
||||||
@click="updateAlertAssignees(currentUser)"
|
@click="updateAlertAssignees(currentUser)"
|
||||||
>
|
>
|
||||||
{{ s__('AlertManagement| assign yourself') }}
|
{{ __('assign yourself') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -8,6 +8,14 @@ export default {
|
||||||
SidebarTodo,
|
SidebarTodo,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
alert: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
projectPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
sidebarCollapsed: {
|
sidebarCollapsed: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -17,18 +25,17 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="block d-flex justify-content-between">
|
<div class="block gl-display-flex gl-justify-content-space-between">
|
||||||
<span class="issuable-header-text hide-collapsed">
|
<span class="issuable-header-text hide-collapsed">
|
||||||
{{ __('Quick actions') }}
|
{{ __('To Do') }}
|
||||||
</span>
|
</span>
|
||||||
<toggle-sidebar
|
<sidebar-todo
|
||||||
:collapsed="sidebarCollapsed"
|
v-if="!sidebarCollapsed"
|
||||||
css-classes="ml-auto"
|
:project-path="projectPath"
|
||||||
@toggle="$emit('toggle-sidebar')"
|
:alert="alert"
|
||||||
|
:sidebar-collapsed="sidebarCollapsed"
|
||||||
|
@alert-error="$emit('alert-error', $event)"
|
||||||
/>
|
/>
|
||||||
<!-- TODO: Implement after or as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/215946 -->
|
<toggle-sidebar :collapsed="sidebarCollapsed" @toggle="$emit('toggle-sidebar')" />
|
||||||
<template v-if="false">
|
|
||||||
<sidebar-todo v-if="!sidebarCollapsed" :sidebar-collapsed="sidebarCollapsed" />
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { GlIcon, GlLoadingIcon, GlTooltip, GlSprintf } from '@gitlab/ui';
|
||||||
GlIcon,
|
|
||||||
GlDropdown,
|
|
||||||
GlDropdownItem,
|
|
||||||
GlLoadingIcon,
|
|
||||||
GlTooltip,
|
|
||||||
GlButton,
|
|
||||||
GlSprintf,
|
|
||||||
} from '@gitlab/ui';
|
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import Tracking from '~/tracking';
|
import AlertStatus from '../alert_status.vue';
|
||||||
import { trackAlertStatusUpdateOptions } from '../../constants';
|
|
||||||
import updateAlertStatus from '../../graphql/mutations/update_alert_status.graphql';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
statuses: {
|
statuses: {
|
||||||
|
@ -21,12 +11,10 @@ export default {
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlDropdown,
|
|
||||||
GlDropdownItem,
|
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTooltip,
|
GlTooltip,
|
||||||
GlButton,
|
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
|
AlertStatus,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
projectPath: {
|
projectPath: {
|
||||||
|
@ -60,44 +48,13 @@ export default {
|
||||||
},
|
},
|
||||||
toggleFormDropdown() {
|
toggleFormDropdown() {
|
||||||
this.isDropdownShowing = !this.isDropdownShowing;
|
this.isDropdownShowing = !this.isDropdownShowing;
|
||||||
const { dropdown } = this.$refs.dropdown.$refs;
|
const { dropdown } = this.$children[2].$refs.dropdown.$refs;
|
||||||
if (dropdown && this.isDropdownShowing) {
|
if (dropdown && this.isDropdownShowing) {
|
||||||
dropdown.show();
|
dropdown.show();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isSelected(status) {
|
handleUpdating(updating) {
|
||||||
return this.alert.status === status;
|
this.isUpdating = updating;
|
||||||
},
|
|
||||||
updateAlertStatus(status) {
|
|
||||||
this.isUpdating = true;
|
|
||||||
this.$apollo
|
|
||||||
.mutate({
|
|
||||||
mutation: updateAlertStatus,
|
|
||||||
variables: {
|
|
||||||
iid: this.alert.iid,
|
|
||||||
status: status.toUpperCase(),
|
|
||||||
projectPath: this.projectPath,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.trackStatusUpdate(status);
|
|
||||||
this.hideDropdown();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.$emit(
|
|
||||||
'alert-sidebar-error',
|
|
||||||
s__(
|
|
||||||
'AlertManagement|There was an error while updating the status of the alert. Please try again.',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.isUpdating = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
trackStatusUpdate(status) {
|
|
||||||
const { category, action, label } = trackAlertStatusUpdateOptions;
|
|
||||||
Tracking.event(category, action, { label, property: status });
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -132,41 +89,15 @@ export default {
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
|
<alert-status
|
||||||
<gl-dropdown
|
:alert="alert"
|
||||||
ref="dropdown"
|
:project-path="projectPath"
|
||||||
:text="$options.statuses[alert.status]"
|
:is-dropdown-showing="isDropdownShowing"
|
||||||
class="w-100"
|
:is-sidebar="true"
|
||||||
toggle-class="dropdown-menu-toggle"
|
@alert-error="$emit('alert-error', $event)"
|
||||||
variant="outline-default"
|
@hide-dropdown="hideDropdown"
|
||||||
@keydown.esc.native="hideDropdown"
|
@handle-updating="handleUpdating"
|
||||||
@hide="hideDropdown"
|
|
||||||
>
|
|
||||||
<div class="dropdown-title">
|
|
||||||
<span class="alert-title">{{ s__('AlertManagement|Assign status') }}</span>
|
|
||||||
<gl-button
|
|
||||||
:aria-label="__('Close')"
|
|
||||||
variant="link"
|
|
||||||
class="dropdown-title-button dropdown-menu-close"
|
|
||||||
icon="close"
|
|
||||||
@click="hideDropdown"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div class="dropdown-content dropdown-body">
|
|
||||||
<gl-dropdown-item
|
|
||||||
v-for="(label, field) in $options.statuses"
|
|
||||||
:key="field"
|
|
||||||
data-testid="statusDropdownItem"
|
|
||||||
class="gl-vertical-align-middle"
|
|
||||||
:active="label.toUpperCase() === alert.status"
|
|
||||||
:active-class="'is-active'"
|
|
||||||
@click="updateAlertStatus(label)"
|
|
||||||
>
|
|
||||||
{{ label }}
|
|
||||||
</gl-dropdown-item>
|
|
||||||
</div>
|
|
||||||
</gl-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<gl-loading-icon v-if="isUpdating" :inline="true" />
|
<gl-loading-icon v-if="isUpdating" :inline="true" />
|
||||||
<p
|
<p
|
||||||
|
|
|
@ -1,29 +1,123 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { s__ } from '~/locale';
|
||||||
import Todo from '~/sidebar/components/todo_toggle/todo.vue';
|
import Todo from '~/sidebar/components/todo_toggle/todo.vue';
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
import createAlertTodo from '../../graphql/mutations/alert_todo_create.graphql';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
i18n: {
|
||||||
|
UPDATE_ALERT_TODO_ERROR: s__(
|
||||||
|
'AlertManagement|There was an error while updating the To Do of the alert.',
|
||||||
|
),
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
Todo,
|
Todo,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
alert: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
projectPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
sidebarCollapsed: {
|
sidebarCollapsed: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isUpdating: false,
|
||||||
|
isTodo: false,
|
||||||
|
todo: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
alertID() {
|
||||||
|
return parseInt(this.alert.iid, 10);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateToDoCount(add) {
|
||||||
|
const oldCount = parseInt(document.querySelector('.todos-count').innerText, 10);
|
||||||
|
const count = add ? oldCount + 1 : oldCount - 1;
|
||||||
|
const headerTodoEvent = new CustomEvent('todo:toggle', {
|
||||||
|
detail: {
|
||||||
|
count,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return document.dispatchEvent(headerTodoEvent);
|
||||||
|
},
|
||||||
|
toggleTodo() {
|
||||||
|
if (this.todo) {
|
||||||
|
return this.markAsDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isUpdating = true;
|
||||||
|
return this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: createAlertTodo,
|
||||||
|
variables: {
|
||||||
|
iid: this.alert.iid,
|
||||||
|
projectPath: this.projectPath,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(({ data: { alertTodoCreate: { todo = {}, errors = [] } } = {} } = {}) => {
|
||||||
|
if (errors[0]) {
|
||||||
|
return this.$emit(
|
||||||
|
'alert-error',
|
||||||
|
`${this.$options.i18n.UPDATE_ALERT_TODO_ERROR} ${errors[0]}.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.todo = todo.id;
|
||||||
|
return this.updateToDoCount(true);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$emit(
|
||||||
|
'alert-error',
|
||||||
|
`${this.$options.i18n.UPDATE_ALERT_TODO_ERROR} ${s__(
|
||||||
|
'AlertManagement|Please try again.',
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.isUpdating = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
markAsDone() {
|
||||||
|
this.isUpdating = true;
|
||||||
|
|
||||||
|
return axios
|
||||||
|
.delete(`/dashboard/todos/${this.todo.split('/').pop()}`)
|
||||||
|
.then(() => {
|
||||||
|
this.todo = '';
|
||||||
|
return this.updateToDoCount(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$emit('alert-error', this.$options.i18n.UPDATE_ALERT_TODO_ERROR);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.isUpdating = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- TODO: Implement after or as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/215946 -->
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="false" :class="{ 'block todo': sidebarCollapsed }">
|
<div :class="{ 'block todo': sidebarCollapsed, 'gl-ml-auto': !sidebarCollapsed }">
|
||||||
<todo
|
<todo
|
||||||
|
data-testid="alert-todo-button"
|
||||||
:collapsed="sidebarCollapsed"
|
:collapsed="sidebarCollapsed"
|
||||||
:issuable-id="1"
|
:issuable-id="alertID"
|
||||||
:is-todo="false"
|
:is-todo="todo !== ''"
|
||||||
:is-action-active="false"
|
:is-action-active="isUpdating"
|
||||||
issuable-type="alert"
|
issuable-type="alert"
|
||||||
@toggleTodo="() => {}"
|
@toggleTodo="toggleTodo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
||||||
return { ...author, id: id?.split('/').pop() };
|
return { ...author, id: id?.split('/').pop() };
|
||||||
},
|
},
|
||||||
iconHtml() {
|
iconHtml() {
|
||||||
return spriteIcon('user');
|
return spriteIcon(this.note?.systemNoteIconName);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,17 +3,26 @@ import VueApollo from 'vue-apollo';
|
||||||
import createDefaultClient from '~/lib/graphql';
|
import createDefaultClient from '~/lib/graphql';
|
||||||
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
|
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
|
||||||
import AlertDetails from './components/alert_details.vue';
|
import AlertDetails from './components/alert_details.vue';
|
||||||
|
import sidebarStatusQuery from './graphql/queries/sidebar_status.query.graphql';
|
||||||
|
|
||||||
Vue.use(VueApollo);
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
export default selector => {
|
export default selector => {
|
||||||
const domEl = document.querySelector(selector);
|
const domEl = document.querySelector(selector);
|
||||||
const { alertId, projectPath, projectIssuesPath } = domEl.dataset;
|
const { alertId, projectPath, projectIssuesPath, projectId } = domEl.dataset;
|
||||||
|
|
||||||
|
const resolvers = {
|
||||||
|
Mutation: {
|
||||||
|
toggleSidebarStatus: (_, __, { cache }) => {
|
||||||
|
const data = cache.readQuery({ query: sidebarStatusQuery });
|
||||||
|
data.sidebarStatus = !data.sidebarStatus;
|
||||||
|
cache.writeQuery({ query: sidebarStatusQuery, data });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const apolloProvider = new VueApollo({
|
const apolloProvider = new VueApollo({
|
||||||
defaultClient: createDefaultClient(
|
defaultClient: createDefaultClient(resolvers, {
|
||||||
{},
|
|
||||||
{
|
|
||||||
cacheConfig: {
|
cacheConfig: {
|
||||||
dataIdFromObject: object => {
|
dataIdFromObject: object => {
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
@ -23,25 +32,30 @@ export default selector => {
|
||||||
return defaultDataIdFromObject(object);
|
return defaultDataIdFromObject(object);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
apolloProvider.clients.defaultClient.cache.writeData({
|
||||||
|
data: {
|
||||||
|
sidebarStatus: false,
|
||||||
},
|
},
|
||||||
),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
new Vue({
|
new Vue({
|
||||||
el: selector,
|
el: selector,
|
||||||
|
provide: {
|
||||||
|
projectPath,
|
||||||
|
alertId,
|
||||||
|
projectIssuesPath,
|
||||||
|
projectId,
|
||||||
|
},
|
||||||
apolloProvider,
|
apolloProvider,
|
||||||
components: {
|
components: {
|
||||||
AlertDetails,
|
AlertDetails,
|
||||||
},
|
},
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
return createElement('alert-details', {
|
return createElement('alert-details', {});
|
||||||
props: {
|
|
||||||
alertId,
|
|
||||||
projectPath,
|
|
||||||
projectIssuesPath,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,4 +13,5 @@ fragment AlertNote on Note {
|
||||||
discussion {
|
discussion {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
systemNoteIconName
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,11 @@ fragment AlertDetailItem on AlertManagementAlert {
|
||||||
...AlertListItem
|
...AlertListItem
|
||||||
createdAt
|
createdAt
|
||||||
monitoringTool
|
monitoringTool
|
||||||
|
metricsDashboardUrl
|
||||||
service
|
service
|
||||||
description
|
description
|
||||||
updatedAt
|
updatedAt
|
||||||
|
endedAt
|
||||||
details
|
details
|
||||||
notes {
|
notes {
|
||||||
nodes {
|
nodes {
|
||||||
|
|
|
@ -4,7 +4,6 @@ fragment AlertListItem on AlertManagementAlert {
|
||||||
severity
|
severity
|
||||||
status
|
status
|
||||||
startedAt
|
startedAt
|
||||||
endedAt
|
|
||||||
eventCount
|
eventCount
|
||||||
issueIid
|
issueIid
|
||||||
assignees {
|
assignees {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
mutation($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) {
|
#import "../fragments/alert_note.fragment.graphql"
|
||||||
|
|
||||||
|
mutation alertSetAssignees($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) {
|
||||||
alertSetAssignees(
|
alertSetAssignees(
|
||||||
input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath }
|
input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath }
|
||||||
) {
|
) {
|
||||||
|
@ -10,6 +12,11 @@ mutation($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) {
|
||||||
username
|
username
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
notes {
|
||||||
|
nodes {
|
||||||
|
...AlertNote
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
mutation($projectPath: ID!, $iid: String!) {
|
||||||
|
alertTodoCreate(input: { iid: $iid, projectPath: $projectPath }) {
|
||||||
|
errors
|
||||||
|
alert {
|
||||||
|
iid
|
||||||
|
}
|
||||||
|
todo {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
mutation ($projectPath: ID!, $iid: String!) {
|
|
||||||
createAlertIssue(input: { iid: $iid, projectPath: $projectPath }) {
|
|
||||||
errors
|
|
||||||
issue {
|
|
||||||
iid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
mutation createAlertIssue($projectPath: ID!, $iid: String!) {
|
||||||
|
createAlertIssue(input: { iid: $iid, projectPath: $projectPath }) {
|
||||||
|
errors
|
||||||
|
issue {
|
||||||
|
iid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
mutation toggleSidebarStatus {
|
||||||
|
toggleSidebarStatus @client
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
mutation ($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) {
|
|
||||||
updateAlertStatus(input: { iid: $iid, status: $status, projectPath: $projectPath }) {
|
|
||||||
errors
|
|
||||||
alert {
|
|
||||||
iid,
|
|
||||||
status,
|
|
||||||
endedAt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#import "../fragments/alert_note.fragment.graphql"
|
||||||
|
|
||||||
|
mutation updateAlertStatus($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) {
|
||||||
|
updateAlertStatus(input: { iid: $iid, status: $status, projectPath: $projectPath }) {
|
||||||
|
errors
|
||||||
|
alert {
|
||||||
|
iid
|
||||||
|
status
|
||||||
|
endedAt
|
||||||
|
notes {
|
||||||
|
nodes {
|
||||||
|
...AlertNote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,28 @@
|
||||||
#import "../fragments/list_item.fragment.graphql"
|
#import "../fragments/list_item.fragment.graphql"
|
||||||
|
|
||||||
query getAlerts(
|
query getAlerts(
|
||||||
$projectPath: ID!,
|
$searchTerm: String
|
||||||
$statuses: [AlertManagementStatus!],
|
$projectPath: ID!
|
||||||
$sort: AlertManagementAlertSort,
|
$statuses: [AlertManagementStatus!]
|
||||||
$firstPageSize: Int,
|
$sort: AlertManagementAlertSort
|
||||||
$lastPageSize: Int,
|
$firstPageSize: Int
|
||||||
|
$lastPageSize: Int
|
||||||
$prevPageCursor: String = ""
|
$prevPageCursor: String = ""
|
||||||
$nextPageCursor: String = ""
|
$nextPageCursor: String = ""
|
||||||
) {
|
) {
|
||||||
project(fullPath: $projectPath, ) {
|
project(fullPath: $projectPath) {
|
||||||
alertManagementAlerts(
|
alertManagementAlerts(
|
||||||
statuses: $statuses,
|
search: $searchTerm
|
||||||
sort: $sort,
|
statuses: $statuses
|
||||||
|
sort: $sort
|
||||||
first: $firstPageSize
|
first: $firstPageSize
|
||||||
last: $lastPageSize,
|
last: $lastPageSize
|
||||||
after: $nextPageCursor,
|
after: $nextPageCursor
|
||||||
before: $prevPageCursor
|
before: $prevPageCursor
|
||||||
) {
|
) {
|
||||||
nodes {
|
nodes {
|
||||||
...AlertListItem
|
...AlertListItem
|
||||||
},
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
hasNextPage
|
hasNextPage
|
||||||
endCursor
|
endCursor
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
query getAlertsCount($projectPath: ID!) {
|
query getAlertsCount($searchTerm: String, $projectPath: ID!) {
|
||||||
project(fullPath: $projectPath) {
|
project(fullPath: $projectPath) {
|
||||||
alertManagementAlertStatusCounts {
|
alertManagementAlertStatusCounts(search: $searchTerm) {
|
||||||
all
|
all
|
||||||
open
|
open
|
||||||
acknowledged
|
acknowledged
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
query sidebarStatus {
|
||||||
|
sidebarStatus @client
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ import VueApollo from 'vue-apollo';
|
||||||
import createDefaultClient from '~/lib/graphql';
|
import createDefaultClient from '~/lib/graphql';
|
||||||
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
|
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||||
import AlertManagementList from './components/alert_management_list.vue';
|
import AlertManagementList from './components/alert_management_list_wrapper.vue';
|
||||||
|
|
||||||
Vue.use(VueApollo);
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
|
@ -11,11 +11,18 @@ export default () => {
|
||||||
const selector = '#js-alert_management';
|
const selector = '#js-alert_management';
|
||||||
|
|
||||||
const domEl = document.querySelector(selector);
|
const domEl = document.querySelector(selector);
|
||||||
const { projectPath, enableAlertManagementPath, emptyAlertSvgPath } = domEl.dataset;
|
const {
|
||||||
let { alertManagementEnabled, userCanEnableAlertManagement } = domEl.dataset;
|
projectPath,
|
||||||
|
enableAlertManagementPath,
|
||||||
|
emptyAlertSvgPath,
|
||||||
|
populatingAlertsHelpUrl,
|
||||||
|
opsgenieMvcTargetUrl,
|
||||||
|
} = domEl.dataset;
|
||||||
|
let { alertManagementEnabled, userCanEnableAlertManagement, opsgenieMvcEnabled } = domEl.dataset;
|
||||||
|
|
||||||
alertManagementEnabled = parseBoolean(alertManagementEnabled);
|
alertManagementEnabled = parseBoolean(alertManagementEnabled);
|
||||||
userCanEnableAlertManagement = parseBoolean(userCanEnableAlertManagement);
|
userCanEnableAlertManagement = parseBoolean(userCanEnableAlertManagement);
|
||||||
|
opsgenieMvcEnabled = parseBoolean(opsgenieMvcEnabled);
|
||||||
|
|
||||||
const apolloProvider = new VueApollo({
|
const apolloProvider = new VueApollo({
|
||||||
defaultClient: createDefaultClient(
|
defaultClient: createDefaultClient(
|
||||||
|
@ -45,9 +52,12 @@ export default () => {
|
||||||
props: {
|
props: {
|
||||||
projectPath,
|
projectPath,
|
||||||
enableAlertManagementPath,
|
enableAlertManagementPath,
|
||||||
|
populatingAlertsHelpUrl,
|
||||||
emptyAlertSvgPath,
|
emptyAlertSvgPath,
|
||||||
alertManagementEnabled,
|
alertManagementEnabled,
|
||||||
userCanEnableAlertManagement,
|
userCanEnableAlertManagement,
|
||||||
|
opsgenieMvcTargetUrl,
|
||||||
|
opsgenieMvcEnabled,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -64,6 +64,11 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
isDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -142,7 +147,7 @@ export default {
|
||||||
<gl-form-group :label="__('Active')" label-for="activated" label-class="label-bold">
|
<gl-form-group :label="__('Active')" label-for="activated" label-class="label-bold">
|
||||||
<toggle-button
|
<toggle-button
|
||||||
id="activated"
|
id="activated"
|
||||||
:disabled-input="loadingActivated"
|
:disabled-input="loadingActivated || isDisabled"
|
||||||
:is-loading="loadingActivated"
|
:is-loading="loadingActivated"
|
||||||
:value="activated"
|
:value="activated"
|
||||||
@change="toggleActivated"
|
@change="toggleActivated"
|
||||||
|
@ -152,7 +157,11 @@ export default {
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<gl-form-input id="url" :readonly="true" :value="url" />
|
<gl-form-input id="url" :readonly="true" :value="url" />
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<clipboard-button :text="url" :title="$options.COPY_TO_CLIPBOARD" />
|
<clipboard-button
|
||||||
|
:text="url"
|
||||||
|
:title="$options.COPY_TO_CLIPBOARD"
|
||||||
|
:disabled="isDisabled"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
|
@ -164,10 +173,16 @@ export default {
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<gl-form-input id="authorization-key" :readonly="true" :value="authorizationKey" />
|
<gl-form-input id="authorization-key" :readonly="true" :value="authorizationKey" />
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<clipboard-button :text="authorizationKey" :title="$options.COPY_TO_CLIPBOARD" />
|
<clipboard-button
|
||||||
|
:text="authorizationKey"
|
||||||
|
:title="$options.COPY_TO_CLIPBOARD"
|
||||||
|
:disabled="isDisabled"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<gl-button v-gl-modal.authKeyModal class="mt-2">{{ $options.RESET_KEY }}</gl-button>
|
<gl-button v-gl-modal.authKeyModal class="mt-2" :disabled="isDisabled">{{
|
||||||
|
$options.RESET_KEY
|
||||||
|
}}</gl-button>
|
||||||
<gl-modal
|
<gl-modal
|
||||||
modal-id="authKeyModal"
|
modal-id="authKeyModal"
|
||||||
:title="$options.RESET_KEY"
|
:title="$options.RESET_KEY"
|
||||||
|
|
|
@ -14,8 +14,11 @@ export default el => {
|
||||||
formPath,
|
formPath,
|
||||||
authorizationKey,
|
authorizationKey,
|
||||||
url,
|
url,
|
||||||
|
disabled,
|
||||||
} = el.dataset;
|
} = el.dataset;
|
||||||
|
|
||||||
const activated = parseBoolean(activatedStr);
|
const activated = parseBoolean(activatedStr);
|
||||||
|
const isDisabled = parseBoolean(disabled);
|
||||||
|
|
||||||
return new Vue({
|
return new Vue({
|
||||||
el,
|
el,
|
||||||
|
@ -28,6 +31,7 @@ export default el => {
|
||||||
formPath,
|
formPath,
|
||||||
initialAuthorizationKey: authorizationKey,
|
initialAuthorizationKey: authorizationKey,
|
||||||
url,
|
url,
|
||||||
|
isDisabled,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,563 @@
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
GlAlert,
|
||||||
|
GlButton,
|
||||||
|
GlForm,
|
||||||
|
GlFormGroup,
|
||||||
|
GlFormInput,
|
||||||
|
GlFormInputGroup,
|
||||||
|
GlFormTextarea,
|
||||||
|
GlLink,
|
||||||
|
GlModal,
|
||||||
|
GlModalDirective,
|
||||||
|
GlSprintf,
|
||||||
|
GlFormSelect,
|
||||||
|
} from '@gitlab/ui';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
|
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||||
|
import ToggleButton from '~/vue_shared/components/toggle_button.vue';
|
||||||
|
import csrf from '~/lib/utils/csrf';
|
||||||
|
import service from '../services';
|
||||||
|
import {
|
||||||
|
i18n,
|
||||||
|
serviceOptions,
|
||||||
|
JSON_VALIDATE_DELAY,
|
||||||
|
targetPrometheusUrlPlaceholder,
|
||||||
|
targetOpsgenieUrlPlaceholder,
|
||||||
|
} from '../constants';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
i18n,
|
||||||
|
csrf,
|
||||||
|
targetOpsgenieUrlPlaceholder,
|
||||||
|
targetPrometheusUrlPlaceholder,
|
||||||
|
components: {
|
||||||
|
GlAlert,
|
||||||
|
GlButton,
|
||||||
|
GlForm,
|
||||||
|
GlFormGroup,
|
||||||
|
GlFormInput,
|
||||||
|
GlFormInputGroup,
|
||||||
|
GlFormSelect,
|
||||||
|
GlFormTextarea,
|
||||||
|
GlLink,
|
||||||
|
GlModal,
|
||||||
|
GlSprintf,
|
||||||
|
ClipboardButton,
|
||||||
|
ToggleButton,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
'gl-modal': GlModalDirective,
|
||||||
|
},
|
||||||
|
mixins: [glFeatureFlagsMixin()],
|
||||||
|
props: {
|
||||||
|
prometheus: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
validator: ({ activated }) => {
|
||||||
|
return activated !== undefined;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
generic: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
validator: ({ formPath }) => {
|
||||||
|
return formPath !== undefined;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opsgenie: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activated: {
|
||||||
|
generic: this.generic.activated,
|
||||||
|
prometheus: this.prometheus.activated,
|
||||||
|
opsgenie: this.opsgenie?.activated,
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
authorizationKey: {
|
||||||
|
generic: this.generic.initialAuthorizationKey,
|
||||||
|
prometheus: this.prometheus.prometheusAuthorizationKey,
|
||||||
|
},
|
||||||
|
selectedEndpoint: serviceOptions[0].value,
|
||||||
|
options: serviceOptions,
|
||||||
|
targetUrl: null,
|
||||||
|
feedback: {
|
||||||
|
variant: 'danger',
|
||||||
|
feedbackMessage: null,
|
||||||
|
isFeedbackDismissed: false,
|
||||||
|
},
|
||||||
|
serverError: null,
|
||||||
|
testAlert: {
|
||||||
|
json: null,
|
||||||
|
error: null,
|
||||||
|
},
|
||||||
|
canSaveForm: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
sections() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
text: this.$options.i18n.usageSection,
|
||||||
|
url: this.generic.alertsUsageUrl,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.$options.i18n.setupSection,
|
||||||
|
url: this.generic.alertsSetupUrl,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
isPrometheus() {
|
||||||
|
return this.selectedEndpoint === 'prometheus';
|
||||||
|
},
|
||||||
|
isOpsgenie() {
|
||||||
|
return this.selectedEndpoint === 'opsgenie';
|
||||||
|
},
|
||||||
|
selectedService() {
|
||||||
|
switch (this.selectedEndpoint) {
|
||||||
|
case 'generic': {
|
||||||
|
return {
|
||||||
|
url: this.generic.url,
|
||||||
|
authKey: this.authorizationKey.generic,
|
||||||
|
active: this.activated.generic,
|
||||||
|
resetKey: this.resetGenericKey.bind(this),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case 'prometheus': {
|
||||||
|
return {
|
||||||
|
url: this.prometheus.prometheusUrl,
|
||||||
|
authKey: this.authorizationKey.prometheus,
|
||||||
|
active: this.activated.prometheus,
|
||||||
|
resetKey: this.resetPrometheusKey.bind(this),
|
||||||
|
targetUrl: this.prometheus.prometheusApiUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case 'opsgenie': {
|
||||||
|
return {
|
||||||
|
targetUrl: this.opsgenie.opsgenieMvcTargetUrl,
|
||||||
|
active: this.activated.opsgenie,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showFeedbackMsg() {
|
||||||
|
return this.feedback.feedbackMessage && !this.isFeedbackDismissed;
|
||||||
|
},
|
||||||
|
showAlertSave() {
|
||||||
|
return (
|
||||||
|
this.feedback.feedbackMessage === this.$options.i18n.testAlertFailed &&
|
||||||
|
!this.isFeedbackDismissed
|
||||||
|
);
|
||||||
|
},
|
||||||
|
prometheusInfo() {
|
||||||
|
return this.isPrometheus ? this.$options.i18n.prometheusInfo : '';
|
||||||
|
},
|
||||||
|
jsonIsValid() {
|
||||||
|
return this.testAlert.error === null;
|
||||||
|
},
|
||||||
|
canTestAlert() {
|
||||||
|
return this.selectedService.active && this.testAlert.json !== null;
|
||||||
|
},
|
||||||
|
canSaveConfig() {
|
||||||
|
return !this.loading && this.canSaveForm;
|
||||||
|
},
|
||||||
|
baseUrlPlaceholder() {
|
||||||
|
return this.isOpsgenie
|
||||||
|
? this.$options.targetOpsgenieUrlPlaceholder
|
||||||
|
: this.$options.targetPrometheusUrlPlaceholder;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'testAlert.json': debounce(function debouncedJsonValidate() {
|
||||||
|
this.validateJson();
|
||||||
|
}, JSON_VALIDATE_DELAY),
|
||||||
|
targetUrl(oldVal, newVal) {
|
||||||
|
if (newVal && oldVal !== this.selectedService.targetUrl) {
|
||||||
|
this.canSaveForm = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (
|
||||||
|
this.activated.prometheus ||
|
||||||
|
this.activated.generic ||
|
||||||
|
!this.opsgenie.opsgenieMvcIsAvailable
|
||||||
|
) {
|
||||||
|
this.removeOpsGenieOption();
|
||||||
|
} else if (this.activated.opsgenie) {
|
||||||
|
this.setOpsgenieAsDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
createUserErrorMessage(errors) {
|
||||||
|
// eslint-disable-next-line prefer-destructuring
|
||||||
|
this.serverError = Object.values(errors)[0][0];
|
||||||
|
},
|
||||||
|
setOpsgenieAsDefault() {
|
||||||
|
this.options = this.options.map(el => {
|
||||||
|
if (el.value !== 'opsgenie') {
|
||||||
|
return { ...el, disabled: true };
|
||||||
|
}
|
||||||
|
return { ...el, disabled: false };
|
||||||
|
});
|
||||||
|
this.selectedEndpoint = this.options.find(({ value }) => value === 'opsgenie').value;
|
||||||
|
if (this.targetUrl === null) {
|
||||||
|
this.targetUrl = this.selectedService.targetUrl;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeOpsGenieOption() {
|
||||||
|
this.options = this.options.map(el => {
|
||||||
|
if (el.value !== 'opsgenie') {
|
||||||
|
return { ...el, disabled: false };
|
||||||
|
}
|
||||||
|
return { ...el, disabled: true };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetFormValues() {
|
||||||
|
this.testAlert.json = null;
|
||||||
|
this.targetUrl = this.selectedService.targetUrl;
|
||||||
|
},
|
||||||
|
dismissFeedback() {
|
||||||
|
this.serverError = null;
|
||||||
|
this.feedback = { ...this.feedback, feedbackMessage: null };
|
||||||
|
this.isFeedbackDismissed = false;
|
||||||
|
},
|
||||||
|
resetGenericKey() {
|
||||||
|
return service
|
||||||
|
.updateGenericKey({ endpoint: this.generic.formPath, params: { service: { token: '' } } })
|
||||||
|
.then(({ data: { token } }) => {
|
||||||
|
this.authorizationKey.generic = token;
|
||||||
|
this.setFeedback({ feedbackMessage: this.$options.i18n.authKeyRest, variant: 'success' });
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.setFeedback({ feedbackMessage: this.$options.i18n.errorKeyMsg, variant: 'danger' });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetPrometheusKey() {
|
||||||
|
return service
|
||||||
|
.updatePrometheusKey({ endpoint: this.prometheus.prometheusResetKeyPath })
|
||||||
|
.then(({ data: { token } }) => {
|
||||||
|
this.authorizationKey.prometheus = token;
|
||||||
|
this.setFeedback({ feedbackMessage: this.$options.i18n.authKeyRest, variant: 'success' });
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.setFeedback({ feedbackMessage: this.$options.i18n.errorKeyMsg, variant: 'danger' });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toggleService(value) {
|
||||||
|
this.canSaveForm = true;
|
||||||
|
if (this.isPrometheus) {
|
||||||
|
this.activated.prometheus = value;
|
||||||
|
} else {
|
||||||
|
this.activated[this.selectedEndpoint] = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggle(value) {
|
||||||
|
return this.isPrometheus ? this.togglePrometheusActive(value) : this.toggleActivated(value);
|
||||||
|
},
|
||||||
|
toggleActivated(value) {
|
||||||
|
this.loading = true;
|
||||||
|
return service
|
||||||
|
.updateGenericActive({
|
||||||
|
endpoint: this[this.selectedEndpoint].formPath,
|
||||||
|
params: this.isOpsgenie
|
||||||
|
? { service: { opsgenie_mvc_target_url: this.targetUrl, opsgenie_mvc_enabled: value } }
|
||||||
|
: { service: { active: value } },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.activated[this.selectedEndpoint] = value;
|
||||||
|
this.toggleSuccess(value);
|
||||||
|
|
||||||
|
if (!this.isOpsgenie && value) {
|
||||||
|
if (!this.selectedService.authKey) {
|
||||||
|
return window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.removeOpsGenieOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isOpsgenie && value) {
|
||||||
|
return this.setOpsgenieAsDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-return-assign
|
||||||
|
return (this.options = serviceOptions);
|
||||||
|
})
|
||||||
|
.catch(({ response: { data: { errors } = {} } = {} }) => {
|
||||||
|
this.createUserErrorMessage(errors);
|
||||||
|
this.setFeedback({
|
||||||
|
feedbackMessage: `${this.$options.i18n.errorMsg}.`,
|
||||||
|
variant: 'danger',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
this.canSaveForm = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
togglePrometheusActive(value) {
|
||||||
|
this.loading = true;
|
||||||
|
return service
|
||||||
|
.updatePrometheusActive({
|
||||||
|
endpoint: this.prometheus.prometheusFormPath,
|
||||||
|
params: {
|
||||||
|
token: this.$options.csrf.token,
|
||||||
|
config: value,
|
||||||
|
url: this.targetUrl,
|
||||||
|
redirect: window.location,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.activated.prometheus = value;
|
||||||
|
this.toggleSuccess(value);
|
||||||
|
this.removeOpsGenieOption();
|
||||||
|
})
|
||||||
|
.catch(({ response: { data: { errors } = {} } = {} }) => {
|
||||||
|
this.createUserErrorMessage(errors);
|
||||||
|
this.setFeedback({
|
||||||
|
feedbackMessage: `${this.$options.i18n.errorMsg}.`,
|
||||||
|
variant: 'danger',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
this.canSaveForm = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toggleSuccess(value) {
|
||||||
|
if (value) {
|
||||||
|
this.setFeedback({
|
||||||
|
feedbackMessage: this.$options.i18n.endPointActivated,
|
||||||
|
variant: 'info',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setFeedback({
|
||||||
|
feedbackMessage: this.$options.i18n.changesSaved,
|
||||||
|
variant: 'info',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setFeedback({ feedbackMessage, variant }) {
|
||||||
|
this.feedback = { feedbackMessage, variant };
|
||||||
|
},
|
||||||
|
validateJson() {
|
||||||
|
this.testAlert.error = null;
|
||||||
|
try {
|
||||||
|
JSON.parse(this.testAlert.json);
|
||||||
|
} catch (e) {
|
||||||
|
this.testAlert.error = JSON.stringify(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validateTestAlert() {
|
||||||
|
this.loading = true;
|
||||||
|
this.validateJson();
|
||||||
|
return service
|
||||||
|
.updateTestAlert({
|
||||||
|
endpoint: this.selectedService.url,
|
||||||
|
data: this.testAlert.json,
|
||||||
|
authKey: this.selectedService.authKey,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.setFeedback({
|
||||||
|
feedbackMessage: this.$options.i18n.testAlertSuccess,
|
||||||
|
variant: 'success',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.setFeedback({
|
||||||
|
feedbackMessage: this.$options.i18n.testAlertFailed,
|
||||||
|
variant: 'danger',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onSubmit() {
|
||||||
|
this.toggle(this.selectedService.active);
|
||||||
|
},
|
||||||
|
onReset() {
|
||||||
|
this.testAlert.json = null;
|
||||||
|
this.dismissFeedback();
|
||||||
|
this.targetUrl = this.selectedService.targetUrl;
|
||||||
|
|
||||||
|
if (this.canSaveForm) {
|
||||||
|
this.canSaveForm = false;
|
||||||
|
this.activated[this.selectedEndpoint] = this[this.selectedEndpoint].activated;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<gl-alert v-if="showFeedbackMsg" :variant="feedback.variant" @dismiss="dismissFeedback">
|
||||||
|
{{ feedback.feedbackMessage }}
|
||||||
|
<br />
|
||||||
|
<i v-if="serverError">{{ __('Error message:') }} {{ serverError }}</i>
|
||||||
|
<gl-button
|
||||||
|
v-if="showAlertSave"
|
||||||
|
variant="danger"
|
||||||
|
category="primary"
|
||||||
|
class="gl-display-block gl-mt-3"
|
||||||
|
@click="toggle(selectedService.active)"
|
||||||
|
>
|
||||||
|
{{ __('Save anyway') }}
|
||||||
|
</gl-button>
|
||||||
|
</gl-alert>
|
||||||
|
<div data-testid="alert-settings-description" class="gl-mt-5">
|
||||||
|
<p v-for="section in sections" :key="section.text">
|
||||||
|
<gl-sprintf :message="section.text">
|
||||||
|
<template #link="{ content }">
|
||||||
|
<gl-link :href="section.url" target="_blank">{{ content }}</gl-link>
|
||||||
|
</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<gl-form @submit.prevent="onSubmit" @reset.prevent="onReset">
|
||||||
|
<gl-form-group
|
||||||
|
:label="$options.i18n.integrationsLabel"
|
||||||
|
label-for="integrations"
|
||||||
|
label-class="label-bold"
|
||||||
|
>
|
||||||
|
<gl-form-select
|
||||||
|
v-model="selectedEndpoint"
|
||||||
|
:options="options"
|
||||||
|
data-testid="alert-settings-select"
|
||||||
|
@change="resetFormValues"
|
||||||
|
/>
|
||||||
|
<span class="gl-text-gray-400">
|
||||||
|
<gl-sprintf :message="$options.i18n.integrationsInfo">
|
||||||
|
<template #link="{ content }">
|
||||||
|
<gl-link
|
||||||
|
class="gl-display-inline-block"
|
||||||
|
href="https://gitlab.com/groups/gitlab-org/-/epics/3362"
|
||||||
|
target="_blank"
|
||||||
|
>{{ content }}</gl-link
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
</span>
|
||||||
|
</gl-form-group>
|
||||||
|
<gl-form-group
|
||||||
|
:label="$options.i18n.activeLabel"
|
||||||
|
label-for="activated"
|
||||||
|
label-class="label-bold"
|
||||||
|
>
|
||||||
|
<toggle-button
|
||||||
|
id="activated"
|
||||||
|
:disabled-input="loading"
|
||||||
|
:is-loading="loading"
|
||||||
|
:value="selectedService.active"
|
||||||
|
@change="toggleService"
|
||||||
|
/>
|
||||||
|
</gl-form-group>
|
||||||
|
<gl-form-group
|
||||||
|
v-if="isOpsgenie || isPrometheus"
|
||||||
|
:label="$options.i18n.apiBaseUrlLabel"
|
||||||
|
label-for="api-url"
|
||||||
|
label-class="label-bold"
|
||||||
|
>
|
||||||
|
<gl-form-input
|
||||||
|
id="api-url"
|
||||||
|
v-model="targetUrl"
|
||||||
|
type="url"
|
||||||
|
:placeholder="baseUrlPlaceholder"
|
||||||
|
:disabled="!selectedService.active"
|
||||||
|
/>
|
||||||
|
<span class="gl-text-gray-400">
|
||||||
|
{{ $options.i18n.apiBaseUrlHelpText }}
|
||||||
|
</span>
|
||||||
|
</gl-form-group>
|
||||||
|
<template v-if="!isOpsgenie">
|
||||||
|
<gl-form-group :label="$options.i18n.urlLabel" label-for="url" label-class="label-bold">
|
||||||
|
<gl-form-input-group id="url" readonly :value="selectedService.url">
|
||||||
|
<template #append>
|
||||||
|
<clipboard-button
|
||||||
|
:text="selectedService.url"
|
||||||
|
:title="$options.i18n.copyToClipboard"
|
||||||
|
class="gl-m-0!"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</gl-form-input-group>
|
||||||
|
<span class="gl-text-gray-400">
|
||||||
|
{{ prometheusInfo }}
|
||||||
|
</span>
|
||||||
|
</gl-form-group>
|
||||||
|
<gl-form-group
|
||||||
|
:label="$options.i18n.authKeyLabel"
|
||||||
|
label-for="authorization-key"
|
||||||
|
label-class="label-bold"
|
||||||
|
>
|
||||||
|
<gl-form-input-group
|
||||||
|
id="authorization-key"
|
||||||
|
class="gl-mb-2"
|
||||||
|
readonly
|
||||||
|
:value="selectedService.authKey"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<clipboard-button
|
||||||
|
:text="selectedService.authKey || ''"
|
||||||
|
:title="$options.i18n.copyToClipboard"
|
||||||
|
class="gl-m-0!"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</gl-form-input-group>
|
||||||
|
<gl-button v-gl-modal.authKeyModal :disabled="!selectedService.active" class="gl-mt-3">{{
|
||||||
|
$options.i18n.resetKey
|
||||||
|
}}</gl-button>
|
||||||
|
<gl-modal
|
||||||
|
modal-id="authKeyModal"
|
||||||
|
:title="$options.i18n.resetKey"
|
||||||
|
:ok-title="$options.i18n.resetKey"
|
||||||
|
ok-variant="danger"
|
||||||
|
@ok="selectedService.resetKey"
|
||||||
|
>
|
||||||
|
{{ $options.i18n.restKeyInfo }}
|
||||||
|
</gl-modal>
|
||||||
|
</gl-form-group>
|
||||||
|
<gl-form-group
|
||||||
|
:label="$options.i18n.alertJson"
|
||||||
|
label-for="alert-json"
|
||||||
|
label-class="label-bold"
|
||||||
|
:invalid-feedback="testAlert.error"
|
||||||
|
>
|
||||||
|
<gl-form-textarea
|
||||||
|
id="alert-json"
|
||||||
|
v-model.trim="testAlert.json"
|
||||||
|
:disabled="!selectedService.active"
|
||||||
|
:state="jsonIsValid"
|
||||||
|
:placeholder="$options.i18n.alertJsonPlaceholder"
|
||||||
|
rows="6"
|
||||||
|
max-rows="10"
|
||||||
|
/>
|
||||||
|
</gl-form-group>
|
||||||
|
<gl-button :disabled="!canTestAlert" @click="validateTestAlert">{{
|
||||||
|
$options.i18n.testAlertInfo
|
||||||
|
}}</gl-button>
|
||||||
|
</template>
|
||||||
|
<div class="footer-block row-content-block gl-display-flex gl-justify-content-space-between">
|
||||||
|
<gl-button
|
||||||
|
variant="success"
|
||||||
|
category="primary"
|
||||||
|
:disabled="!canSaveConfig"
|
||||||
|
@click="onSubmit"
|
||||||
|
>
|
||||||
|
{{ __('Save changes') }}
|
||||||
|
</gl-button>
|
||||||
|
<gl-button variant="default" category="primary" :disabled="!canSaveConfig" @click="onReset">
|
||||||
|
{{ __('Cancel') }}
|
||||||
|
</gl-button>
|
||||||
|
</div>
|
||||||
|
</gl-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
50
app/assets/javascripts/alerts_settings/constants.js
Normal file
50
app/assets/javascripts/alerts_settings/constants.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
|
||||||
|
export const i18n = {
|
||||||
|
usageSection: s__(
|
||||||
|
'AlertSettings|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page.',
|
||||||
|
),
|
||||||
|
setupSection: s__(
|
||||||
|
"AlertSettings|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint.",
|
||||||
|
),
|
||||||
|
errorMsg: s__('AlertSettings|There was an error updating the alert settings'),
|
||||||
|
errorKeyMsg: s__(
|
||||||
|
'AlertSettings|There was an error while trying to reset the key. Please refresh the page to try again.',
|
||||||
|
),
|
||||||
|
restKeyInfo: s__(
|
||||||
|
'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.',
|
||||||
|
),
|
||||||
|
endPointActivated: s__('AlertSettings|Alerts endpoint successfully activated.'),
|
||||||
|
changesSaved: s__('AlertSettings|Your changes were successfully updated.'),
|
||||||
|
prometheusInfo: s__('AlertSettings|Add URL and auth key to your Prometheus config file'),
|
||||||
|
integrationsInfo: s__(
|
||||||
|
'AlertSettings|Learn more about our %{linkStart}upcoming integrations%{linkEnd}',
|
||||||
|
),
|
||||||
|
resetKey: s__('AlertSettings|Reset key'),
|
||||||
|
copyToClipboard: s__('AlertSettings|Copy'),
|
||||||
|
integrationsLabel: s__('AlertSettings|Integrations'),
|
||||||
|
apiBaseUrlLabel: s__('AlertSettings|API URL'),
|
||||||
|
authKeyLabel: s__('AlertSettings|Authorization key'),
|
||||||
|
urlLabel: s__('AlertSettings|Webhook URL'),
|
||||||
|
activeLabel: s__('AlertSettings|Active'),
|
||||||
|
apiBaseUrlHelpText: s__('AlertSettings|URL cannot be blank and must start with http or https'),
|
||||||
|
testAlertInfo: s__('AlertSettings|Test alert payload'),
|
||||||
|
alertJson: s__('AlertSettings|Alert test payload'),
|
||||||
|
alertJsonPlaceholder: s__('AlertSettings|Enter test alert JSON....'),
|
||||||
|
testAlertFailed: s__('AlertSettings|Test failed. Do you still want to save your changes anyway?'),
|
||||||
|
testAlertSuccess: s__(
|
||||||
|
'AlertSettings|Test alert sent successfully. If you have made other changes, please save them now.',
|
||||||
|
),
|
||||||
|
authKeyRest: s__('AlertSettings|Authorization key has been successfully reset'),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const serviceOptions = [
|
||||||
|
{ value: 'generic', text: s__('AlertSettings|Generic') },
|
||||||
|
{ value: 'prometheus', text: s__('AlertSettings|External Prometheus') },
|
||||||
|
{ value: 'opsgenie', text: s__('AlertSettings|Opsgenie') },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const JSON_VALIDATE_DELAY = 250;
|
||||||
|
|
||||||
|
export const targetPrometheusUrlPlaceholder = 'http://prometheus.example.com/';
|
||||||
|
export const targetOpsgenieUrlPlaceholder = 'https://app.opsgenie.com/alert/list/';
|
67
app/assets/javascripts/alerts_settings/index.js
Normal file
67
app/assets/javascripts/alerts_settings/index.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||||
|
import AlertSettingsForm from './components/alerts_settings_form.vue';
|
||||||
|
|
||||||
|
export default el => {
|
||||||
|
if (!el) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
prometheusActivated,
|
||||||
|
prometheusUrl,
|
||||||
|
prometheusAuthorizationKey,
|
||||||
|
prometheusFormPath,
|
||||||
|
prometheusResetKeyPath,
|
||||||
|
prometheusApiUrl,
|
||||||
|
activated: activatedStr,
|
||||||
|
alertsSetupUrl,
|
||||||
|
alertsUsageUrl,
|
||||||
|
formPath,
|
||||||
|
authorizationKey,
|
||||||
|
url,
|
||||||
|
opsgenieMvcAvailable,
|
||||||
|
opsgenieMvcFormPath,
|
||||||
|
opsgenieMvcEnabled,
|
||||||
|
opsgenieMvcTargetUrl,
|
||||||
|
} = el.dataset;
|
||||||
|
|
||||||
|
const genericActivated = parseBoolean(activatedStr);
|
||||||
|
const prometheusIsActivated = parseBoolean(prometheusActivated);
|
||||||
|
const opsgenieMvcActivated = parseBoolean(opsgenieMvcEnabled);
|
||||||
|
const opsgenieMvcIsAvailable = parseBoolean(opsgenieMvcAvailable);
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
prometheus: {
|
||||||
|
activated: prometheusIsActivated,
|
||||||
|
prometheusUrl,
|
||||||
|
prometheusAuthorizationKey,
|
||||||
|
prometheusFormPath,
|
||||||
|
prometheusResetKeyPath,
|
||||||
|
prometheusApiUrl,
|
||||||
|
},
|
||||||
|
generic: {
|
||||||
|
alertsSetupUrl,
|
||||||
|
alertsUsageUrl,
|
||||||
|
activated: genericActivated,
|
||||||
|
formPath,
|
||||||
|
initialAuthorizationKey: authorizationKey,
|
||||||
|
url,
|
||||||
|
},
|
||||||
|
opsgenie: {
|
||||||
|
formPath: opsgenieMvcFormPath,
|
||||||
|
activated: opsgenieMvcActivated,
|
||||||
|
opsgenieMvcTargetUrl,
|
||||||
|
opsgenieMvcIsAvailable,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Vue({
|
||||||
|
el,
|
||||||
|
render(createElement) {
|
||||||
|
return createElement(AlertSettingsForm, {
|
||||||
|
props,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
36
app/assets/javascripts/alerts_settings/services/index.js
Normal file
36
app/assets/javascripts/alerts_settings/services/index.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* eslint-disable @gitlab/require-i18n-strings */
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
updateGenericKey({ endpoint, params }) {
|
||||||
|
return axios.put(endpoint, params);
|
||||||
|
},
|
||||||
|
updatePrometheusKey({ endpoint }) {
|
||||||
|
return axios.post(endpoint);
|
||||||
|
},
|
||||||
|
updateGenericActive({ endpoint, params }) {
|
||||||
|
return axios.put(endpoint, params);
|
||||||
|
},
|
||||||
|
updatePrometheusActive({ endpoint, params: { token, config, url, redirect } }) {
|
||||||
|
const data = new FormData();
|
||||||
|
data.set('_method', 'put');
|
||||||
|
data.set('authenticity_token', token);
|
||||||
|
data.set('service[manual_configuration]', config);
|
||||||
|
data.set('service[api_url]', url);
|
||||||
|
data.set('redirect_to', redirect);
|
||||||
|
|
||||||
|
return axios.post(endpoint, data, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateTestAlert({ endpoint, data, authKey }) {
|
||||||
|
return axios.post(endpoint, data, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${authKey}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
|
@ -11,6 +11,9 @@ const Api = {
|
||||||
groupMembersPath: '/api/:version/groups/:id/members',
|
groupMembersPath: '/api/:version/groups/:id/members',
|
||||||
subgroupsPath: '/api/:version/groups/:id/subgroups',
|
subgroupsPath: '/api/:version/groups/:id/subgroups',
|
||||||
namespacesPath: '/api/:version/namespaces.json',
|
namespacesPath: '/api/:version/namespaces.json',
|
||||||
|
groupPackagesPath: '/api/:version/groups/:id/packages',
|
||||||
|
projectPackagesPath: '/api/:version/projects/:id/packages',
|
||||||
|
projectPackagePath: '/api/:version/projects/:id/packages/:package_id',
|
||||||
groupProjectsPath: '/api/:version/groups/:id/projects.json',
|
groupProjectsPath: '/api/:version/groups/:id/projects.json',
|
||||||
projectsPath: '/api/:version/projects.json',
|
projectsPath: '/api/:version/projects.json',
|
||||||
projectPath: '/api/:version/projects/:id',
|
projectPath: '/api/:version/projects/:id',
|
||||||
|
@ -36,7 +39,9 @@ const Api = {
|
||||||
userStatusPath: '/api/:version/users/:id/status',
|
userStatusPath: '/api/:version/users/:id/status',
|
||||||
userProjectsPath: '/api/:version/users/:id/projects',
|
userProjectsPath: '/api/:version/users/:id/projects',
|
||||||
userPostStatusPath: '/api/:version/user/status',
|
userPostStatusPath: '/api/:version/user/status',
|
||||||
commitPath: '/api/:version/projects/:id/repository/commits',
|
commitPath: '/api/:version/projects/:id/repository/commits/:sha',
|
||||||
|
commitsPath: '/api/:version/projects/:id/repository/commits',
|
||||||
|
|
||||||
applySuggestionPath: '/api/:version/suggestions/:id/apply',
|
applySuggestionPath: '/api/:version/suggestions/:id/apply',
|
||||||
applySuggestionBatchPath: '/api/:version/suggestions/batch_apply',
|
applySuggestionBatchPath: '/api/:version/suggestions/batch_apply',
|
||||||
commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
|
commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
|
||||||
|
@ -64,6 +69,32 @@ const Api = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
groupPackages(id, options = {}) {
|
||||||
|
const url = Api.buildUrl(this.groupPackagesPath).replace(':id', id);
|
||||||
|
return axios.get(url, options);
|
||||||
|
},
|
||||||
|
|
||||||
|
projectPackages(id, options = {}) {
|
||||||
|
const url = Api.buildUrl(this.projectPackagesPath).replace(':id', id);
|
||||||
|
return axios.get(url, options);
|
||||||
|
},
|
||||||
|
|
||||||
|
buildProjectPackageUrl(projectId, packageId) {
|
||||||
|
return Api.buildUrl(this.projectPackagePath)
|
||||||
|
.replace(':id', projectId)
|
||||||
|
.replace(':package_id', packageId);
|
||||||
|
},
|
||||||
|
|
||||||
|
projectPackage(projectId, packageId) {
|
||||||
|
const url = this.buildProjectPackageUrl(projectId, packageId);
|
||||||
|
return axios.get(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteProjectPackage(projectId, packageId) {
|
||||||
|
const url = this.buildProjectPackageUrl(projectId, packageId);
|
||||||
|
return axios.delete(url);
|
||||||
|
},
|
||||||
|
|
||||||
groupMembers(id, options) {
|
groupMembers(id, options) {
|
||||||
const url = Api.buildUrl(this.groupMembersPath).replace(':id', encodeURIComponent(id));
|
const url = Api.buildUrl(this.groupMembersPath).replace(':id', encodeURIComponent(id));
|
||||||
|
|
||||||
|
@ -308,9 +339,17 @@ const Api = {
|
||||||
.catch(() => flash(__('Something went wrong while fetching projects')));
|
.catch(() => flash(__('Something went wrong while fetching projects')));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
commit(id, sha, params = {}) {
|
||||||
|
const url = Api.buildUrl(this.commitPath)
|
||||||
|
.replace(':id', encodeURIComponent(id))
|
||||||
|
.replace(':sha', encodeURIComponent(sha));
|
||||||
|
|
||||||
|
return axios.get(url, { params });
|
||||||
|
},
|
||||||
|
|
||||||
commitMultiple(id, data) {
|
commitMultiple(id, data) {
|
||||||
// see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
// see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||||
const url = Api.buildUrl(Api.commitPath).replace(':id', encodeURIComponent(id));
|
const url = Api.buildUrl(Api.commitsPath).replace(':id', encodeURIComponent(id));
|
||||||
return axios.post(url, JSON.stringify(data), {
|
return axios.post(url, JSON.stringify(data), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
|
|
@ -9,14 +9,10 @@ import { updateTooltipTitle } from './lib/utils/common_utils';
|
||||||
import { isInVueNoteablePage } from './lib/utils/dom_utils';
|
import { isInVueNoteablePage } from './lib/utils/dom_utils';
|
||||||
import flash from './flash';
|
import flash from './flash';
|
||||||
import axios from './lib/utils/axios_utils';
|
import axios from './lib/utils/axios_utils';
|
||||||
|
import * as Emoji from '~/emoji';
|
||||||
|
|
||||||
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
||||||
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
|
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
|
||||||
const requestAnimationFrame =
|
|
||||||
window.requestAnimationFrame ||
|
|
||||||
window.webkitRequestAnimationFrame ||
|
|
||||||
window.mozRequestAnimationFrame ||
|
|
||||||
window.setTimeout;
|
|
||||||
|
|
||||||
const FROM_SENTENCE_REGEX = /(?:, and | and |, )/; // For separating lists produced by ruby's Array#toSentence
|
const FROM_SENTENCE_REGEX = /(?:, and | and |, )/; // For separating lists produced by ruby's Array#toSentence
|
||||||
|
|
||||||
|
@ -619,7 +615,7 @@ export class AwardsHandler {
|
||||||
let awardsHandlerPromise = null;
|
let awardsHandlerPromise = null;
|
||||||
export default function loadAwardsHandler(reload = false) {
|
export default function loadAwardsHandler(reload = false) {
|
||||||
if (!awardsHandlerPromise || reload) {
|
if (!awardsHandlerPromise || reload) {
|
||||||
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(Emoji => {
|
awardsHandlerPromise = Emoji.initEmojiMap().then(() => {
|
||||||
const awardsHandler = new AwardsHandler(Emoji);
|
const awardsHandler = new AwardsHandler(Emoji);
|
||||||
awardsHandler.bindEvents();
|
awardsHandler.bindEvents();
|
||||||
return awardsHandler;
|
return awardsHandler;
|
||||||
|
|
|
@ -164,7 +164,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<form
|
<form
|
||||||
:class="{ 'was-validated': wasValidated }"
|
:class="{ 'was-validated': wasValidated }"
|
||||||
class="prepend-top-default append-bottom-default needs-validation"
|
class="gl-mt-3 gl-mb-3 needs-validation"
|
||||||
novalidate
|
novalidate
|
||||||
@submit.prevent.stop="onSubmit"
|
@submit.prevent.stop="onSubmit"
|
||||||
>
|
>
|
||||||
|
|
|
@ -51,6 +51,7 @@ export default {
|
||||||
'scrollToDraft',
|
'scrollToDraft',
|
||||||
'toggleResolveDiscussion',
|
'toggleResolveDiscussion',
|
||||||
]),
|
]),
|
||||||
|
...mapActions(['setSelectedCommentPositionHover']),
|
||||||
update(data) {
|
update(data) {
|
||||||
this.updateDraft(data);
|
this.updateDraft(data);
|
||||||
},
|
},
|
||||||
|
@ -67,12 +68,16 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<article class="draft-note-component note-wrapper">
|
<article
|
||||||
|
class="draft-note-component note-wrapper"
|
||||||
|
@mouseenter="setSelectedCommentPositionHover(draft.position.line_range)"
|
||||||
|
@mouseleave="setSelectedCommentPositionHover()"
|
||||||
|
>
|
||||||
<ul class="notes draft-notes">
|
<ul class="notes draft-notes">
|
||||||
<noteable-note
|
<noteable-note
|
||||||
:note="draft"
|
:note="draft"
|
||||||
:diff-lines="diffFile.highlighted_diff_lines"
|
|
||||||
:line="line"
|
:line="line"
|
||||||
|
:discussion-root="true"
|
||||||
class="draft-note"
|
class="draft-note"
|
||||||
@handleEdit="handleEditing"
|
@handleEdit="handleEditing"
|
||||||
@cancelForm="handleNotEditing"
|
@cancelForm="handleNotEditing"
|
||||||
|
@ -81,7 +86,7 @@ export default {
|
||||||
@handleUpdateNote="update"
|
@handleUpdateNote="update"
|
||||||
@toggleResolveStatus="toggleResolveDiscussion(draft.id)"
|
@toggleResolveStatus="toggleResolveDiscussion(draft.id)"
|
||||||
>
|
>
|
||||||
<strong slot="note-header-info" class="badge draft-pending-label append-right-4">
|
<strong slot="note-header-info" class="badge draft-pending-label gl-mr-2">
|
||||||
{{ __('Pending') }}
|
{{ __('Pending') }}
|
||||||
</strong>
|
</strong>
|
||||||
</noteable-note>
|
</noteable-note>
|
||||||
|
|
|
@ -35,11 +35,15 @@ export default {
|
||||||
<tr :class="className" class="notes_holder">
|
<tr :class="className" class="notes_holder">
|
||||||
<td class="notes_line old"></td>
|
<td class="notes_line old"></td>
|
||||||
<td class="notes-content parallel old" colspan="2">
|
<td class="notes-content parallel old" colspan="2">
|
||||||
<div v-if="leftDraft.isDraft" class="content"><draft-note :draft="leftDraft" /></div>
|
<div v-if="leftDraft.isDraft" class="content">
|
||||||
|
<draft-note :draft="leftDraft" :line="line.left" />
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="notes_line new"></td>
|
<td class="notes_line new"></td>
|
||||||
<td class="notes-content parallel new" colspan="2">
|
<td class="notes-content parallel new" colspan="2">
|
||||||
<div v-if="rightDraft.isDraft" class="content"><draft-note :draft="rightDraft" /></div>
|
<div v-if="rightDraft.isDraft" class="content">
|
||||||
|
<draft-note :draft="rightDraft" :line="line.right" />
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -96,7 +96,7 @@ export default {
|
||||||
<preview-item :draft="draft" :is-last="isLast(index)" />
|
<preview-item :draft="draft" :is-last="isLast(index)" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<gl-loading-icon v-else size="lg" class="prepend-top-default append-bottom-default" />
|
<gl-loading-icon v-else size="lg" class="gl-mt-3 gl-mb-3" />
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-footer">
|
<div class="dropdown-footer">
|
||||||
<publish-button
|
<publish-button
|
||||||
|
|
|
@ -52,14 +52,12 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
linePosition() {
|
linePosition() {
|
||||||
if (this.draft.position && this.draft.position.position_type === IMAGE_DIFF_POSITION_TYPE) {
|
if (this.position?.position_type === IMAGE_DIFF_POSITION_TYPE) {
|
||||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||||
return `${this.draft.position.x}x ${this.draft.position.y}y`;
|
return `${this.position.x}x ${this.position.y}y`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = this.discussion ? this.discussion.position : this.draft.position;
|
return this.position?.new_line || this.position?.old_line;
|
||||||
|
|
||||||
return position?.new_line || position?.old_line;
|
|
||||||
},
|
},
|
||||||
content() {
|
content() {
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
|
@ -70,11 +68,14 @@ export default {
|
||||||
showLinePosition() {
|
showLinePosition() {
|
||||||
return this.draft.file_hash || this.isDiffDiscussion;
|
return this.draft.file_hash || this.isDiffDiscussion;
|
||||||
},
|
},
|
||||||
|
position() {
|
||||||
|
return this.draft.position || this.discussion.position;
|
||||||
|
},
|
||||||
startLineNumber() {
|
startLineNumber() {
|
||||||
return getStartLineNumber(this.draft.position?.line_range);
|
return getStartLineNumber(this.position?.line_range);
|
||||||
},
|
},
|
||||||
endLineNumber() {
|
endLineNumber() {
|
||||||
return getEndLineNumber(this.draft.position?.line_range);
|
return getEndLineNumber(this.position?.line_range);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import $ from 'jquery';
|
||||||
|
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This behavior collapses the right sidebar
|
||||||
|
* if the window size changes
|
||||||
|
*
|
||||||
|
* @sentrify
|
||||||
|
*/
|
||||||
|
export default () => {
|
||||||
|
const $sidebarGutterToggle = $('.js-sidebar-toggle');
|
||||||
|
let bootstrapBreakpoint = bp.getBreakpointSize();
|
||||||
|
|
||||||
|
$(window).on('resize.app', () => {
|
||||||
|
const oldBootstrapBreakpoint = bootstrapBreakpoint;
|
||||||
|
bootstrapBreakpoint = bp.getBreakpointSize();
|
||||||
|
|
||||||
|
if (bootstrapBreakpoint !== oldBootstrapBreakpoint) {
|
||||||
|
const breakpointSizes = ['md', 'sm', 'xs'];
|
||||||
|
|
||||||
|
if (breakpointSizes.includes(bootstrapBreakpoint)) {
|
||||||
|
const $gutterIcon = $sidebarGutterToggle.find('i');
|
||||||
|
if ($gutterIcon.hasClass('fa-angle-double-right')) {
|
||||||
|
$sidebarGutterToggle.trigger('click');
|
||||||
|
}
|
||||||
|
|
||||||
|
const sidebarGutterVueToggleEl = document.querySelector('.js-sidebar-vue-toggle');
|
||||||
|
|
||||||
|
// Sidebar has an icon which corresponds to collapsing the sidebar
|
||||||
|
// only then trigger the click.
|
||||||
|
if (sidebarGutterVueToggleEl) {
|
||||||
|
const collapseIcon = sidebarGutterVueToggleEl.querySelector('i.fa-angle-double-right');
|
||||||
|
|
||||||
|
if (collapseIcon) {
|
||||||
|
collapseIcon.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,22 +1,51 @@
|
||||||
import 'document-register-element';
|
import 'document-register-element';
|
||||||
import isEmojiUnicodeSupported from '../emoji/support';
|
import isEmojiUnicodeSupported from '../emoji/support';
|
||||||
|
import { initEmojiMap, getEmojiInfo, emojiFallbackImageSrc, emojiImageTag } from '../emoji';
|
||||||
|
|
||||||
class GlEmoji extends HTMLElement {
|
class GlEmoji extends HTMLElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
const emojiUnicode = this.textContent.trim();
|
this.initialize();
|
||||||
const { name, unicodeVersion, fallbackSrc, fallbackSpriteClass } = this.dataset;
|
}
|
||||||
|
initialize() {
|
||||||
|
let emojiUnicode = this.textContent.trim();
|
||||||
|
const { fallbackSpriteClass, fallbackSrc } = this.dataset;
|
||||||
|
let { name, unicodeVersion } = this.dataset;
|
||||||
|
|
||||||
|
return initEmojiMap().then(() => {
|
||||||
|
if (!unicodeVersion) {
|
||||||
|
const emojiInfo = getEmojiInfo(name);
|
||||||
|
|
||||||
|
if (emojiInfo) {
|
||||||
|
if (name !== emojiInfo.name) {
|
||||||
|
({ name } = emojiInfo);
|
||||||
|
this.dataset.name = emojiInfo.name;
|
||||||
|
}
|
||||||
|
unicodeVersion = emojiInfo.u;
|
||||||
|
this.dataset.unicodeVersion = unicodeVersion;
|
||||||
|
|
||||||
|
emojiUnicode = emojiInfo.e;
|
||||||
|
this.innerHTML = emojiInfo.e;
|
||||||
|
|
||||||
|
this.title = emojiInfo.d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const isEmojiUnicode =
|
const isEmojiUnicode =
|
||||||
this.childNodes &&
|
this.childNodes &&
|
||||||
Array.prototype.every.call(this.childNodes, childNode => childNode.nodeType === 3);
|
Array.prototype.every.call(this.childNodes, childNode => childNode.nodeType === 3);
|
||||||
const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
|
|
||||||
const hasCssSpriteFalback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
|
|
||||||
|
|
||||||
if (emojiUnicode && isEmojiUnicode && !isEmojiUnicodeSupported(emojiUnicode, unicodeVersion)) {
|
if (
|
||||||
|
emojiUnicode &&
|
||||||
|
isEmojiUnicode &&
|
||||||
|
!isEmojiUnicodeSupported(emojiUnicode, unicodeVersion)
|
||||||
|
) {
|
||||||
|
const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
|
||||||
|
const hasCssSpriteFallback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
|
||||||
|
|
||||||
// CSS sprite fallback takes precedence over image fallback
|
// CSS sprite fallback takes precedence over image fallback
|
||||||
if (hasCssSpriteFalback) {
|
if (hasCssSpriteFallback) {
|
||||||
if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) {
|
if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) {
|
||||||
const emojiSpriteLinkTag = document.createElement('link');
|
const emojiSpriteLinkTag = document.createElement('link');
|
||||||
emojiSpriteLinkTag.setAttribute('rel', 'stylesheet');
|
emojiSpriteLinkTag.setAttribute('rel', 'stylesheet');
|
||||||
|
@ -27,22 +56,15 @@ class GlEmoji extends HTMLElement {
|
||||||
// IE 11 doesn't like adding multiple at once :(
|
// IE 11 doesn't like adding multiple at once :(
|
||||||
this.classList.add('emoji-icon');
|
this.classList.add('emoji-icon');
|
||||||
this.classList.add(fallbackSpriteClass);
|
this.classList.add(fallbackSpriteClass);
|
||||||
} else {
|
} else if (hasImageFallback) {
|
||||||
import(/* webpackChunkName: 'emoji' */ '../emoji')
|
|
||||||
.then(({ emojiImageTag, emojiFallbackImageSrc }) => {
|
|
||||||
if (hasImageFallback) {
|
|
||||||
this.innerHTML = emojiImageTag(name, fallbackSrc);
|
this.innerHTML = emojiImageTag(name, fallbackSrc);
|
||||||
} else {
|
} else {
|
||||||
const src = emojiFallbackImageSrc(name);
|
const src = emojiFallbackImageSrc(name);
|
||||||
this.innerHTML = emojiImageTag(name, src);
|
this.innerHTML = emojiImageTag(name, src);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.catch(() => {
|
|
||||||
// do nothing
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function installGlEmojiElement() {
|
export default function installGlEmojiElement() {
|
||||||
|
|
|
@ -11,9 +11,13 @@ import './requires_input';
|
||||||
import initPageShortcuts from './shortcuts';
|
import initPageShortcuts from './shortcuts';
|
||||||
import './toggler_behavior';
|
import './toggler_behavior';
|
||||||
import './preview_markdown';
|
import './preview_markdown';
|
||||||
|
import initCollapseSidebarOnWindowResize from './collapse_sidebar_on_window_resize';
|
||||||
|
import initSelect2Dropdowns from './select2';
|
||||||
|
|
||||||
installGlEmojiElement();
|
installGlEmojiElement();
|
||||||
initGFMInput();
|
initGFMInput();
|
||||||
initCopyAsGFM();
|
initCopyAsGFM();
|
||||||
initCopyToClipboard();
|
initCopyToClipboard();
|
||||||
initPageShortcuts();
|
initPageShortcuts();
|
||||||
|
initCollapseSidebarOnWindowResize();
|
||||||
|
initSelect2Dropdowns();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { getSelectedFragment } from '~/lib/utils/common_utils';
|
import { getSelectedFragment, insertText } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
export class CopyAsGFM {
|
export class CopyAsGFM {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -79,7 +79,7 @@ export class CopyAsGFM {
|
||||||
}
|
}
|
||||||
|
|
||||||
static insertPastedText(target, text, gfm) {
|
static insertPastedText(target, text, gfm) {
|
||||||
window.gl.utils.insertText(target, textBefore => {
|
insertText(target, textBefore => {
|
||||||
// If the text before the cursor contains an odd number of backticks,
|
// If the text before the cursor contains an odd number of backticks,
|
||||||
// we are either inside an inline code span that starts with 1 backtick
|
// we are either inside an inline code span that starts with 1 backtick
|
||||||
// or a code block that starts with 3 backticks.
|
// or a code block that starts with 3 backticks.
|
||||||
|
|
|
@ -174,7 +174,7 @@ export default function renderMermaid($els) {
|
||||||
if (!$els.length) return;
|
if (!$els.length) return;
|
||||||
|
|
||||||
const visibleMermaids = $els.filter(function filter() {
|
const visibleMermaids = $els.filter(function filter() {
|
||||||
return $(this).closest('details').length === 0;
|
return $(this).closest('details').length === 0 && $(this).is(':visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
renderMermaids(visibleMermaids);
|
renderMermaids(visibleMermaids);
|
||||||
|
|
23
app/assets/javascripts/behaviors/select2.js
Normal file
23
app/assets/javascripts/behaviors/select2.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
if ($('select.select2').length) {
|
||||||
|
import(/* webpackChunkName: 'select2' */ 'select2/select2')
|
||||||
|
.then(() => {
|
||||||
|
$('select.select2').select2({
|
||||||
|
width: 'resolve',
|
||||||
|
minimumResultsForSearch: 10,
|
||||||
|
dropdownAutoWidth: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close select2 on escape
|
||||||
|
$('.js-select2').on('select2-close', () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
$('.select2-container-active').removeClass('select2-container-active');
|
||||||
|
$(':focus').blur();
|
||||||
|
}, 1);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,11 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlToggle, GlSprintf } from '@gitlab/ui';
|
import { GlToggle } from '@gitlab/ui';
|
||||||
import AccessorUtilities from '~/lib/utils/accessor';
|
import AccessorUtilities from '~/lib/utils/accessor';
|
||||||
import { disableShortcuts, enableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle';
|
import { disableShortcuts, enableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlSprintf,
|
|
||||||
GlToggle,
|
GlToggle,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -32,29 +31,10 @@ export default {
|
||||||
<gl-toggle
|
<gl-toggle
|
||||||
v-model="shortcutsEnabled"
|
v-model="shortcutsEnabled"
|
||||||
aria-describedby="shortcutsToggle"
|
aria-describedby="shortcutsToggle"
|
||||||
class="prepend-left-10 mb-0"
|
label="Keyboard shortcuts"
|
||||||
label-position="right"
|
label-position="left"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
>
|
/>
|
||||||
<template #labelOn>
|
|
||||||
<gl-sprintf
|
|
||||||
:message="__('%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled')"
|
|
||||||
>
|
|
||||||
<template #screenreaderOnly="{ content }">
|
|
||||||
<span class="sr-only">{{ content }}</span>
|
|
||||||
</template>
|
|
||||||
</gl-sprintf>
|
|
||||||
</template>
|
|
||||||
<template #labelOff>
|
|
||||||
<gl-sprintf
|
|
||||||
:message="__('%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled')"
|
|
||||||
>
|
|
||||||
<template #screenreaderOnly="{ content }">
|
|
||||||
<span class="sr-only">{{ content }}</span>
|
|
||||||
</template>
|
|
||||||
</gl-sprintf>
|
|
||||||
</template>
|
|
||||||
</gl-toggle>
|
|
||||||
<div id="shortcutsToggle" class="sr-only">{{ __('Enable or disable keyboard shortcuts') }}</div>
|
<div id="shortcutsToggle" class="sr-only">{{ __('Enable or disable keyboard shortcuts') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlDeprecatedButton, GlButtonGroup, GlIcon, GlTooltipDirective } from '@gitlab/ui';
|
import { GlButton, GlButtonGroup, GlIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import {
|
import {
|
||||||
RICH_BLOB_VIEWER,
|
RICH_BLOB_VIEWER,
|
||||||
RICH_BLOB_VIEWER_TITLE,
|
RICH_BLOB_VIEWER_TITLE,
|
||||||
|
@ -11,7 +11,7 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlButtonGroup,
|
GlButtonGroup,
|
||||||
GlDeprecatedButton,
|
GlButton,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
GlTooltip: GlTooltipDirective,
|
GlTooltip: GlTooltipDirective,
|
||||||
|
@ -46,7 +46,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<gl-button-group class="js-blob-viewer-switcher mx-2">
|
<gl-button-group class="js-blob-viewer-switcher mx-2">
|
||||||
<gl-deprecated-button
|
<gl-button
|
||||||
v-gl-tooltip.hover
|
v-gl-tooltip.hover
|
||||||
:aria-label="$options.SIMPLE_BLOB_VIEWER_TITLE"
|
:aria-label="$options.SIMPLE_BLOB_VIEWER_TITLE"
|
||||||
:title="$options.SIMPLE_BLOB_VIEWER_TITLE"
|
:title="$options.SIMPLE_BLOB_VIEWER_TITLE"
|
||||||
|
@ -55,8 +55,8 @@ export default {
|
||||||
@click="switchToViewer($options.SIMPLE_BLOB_VIEWER)"
|
@click="switchToViewer($options.SIMPLE_BLOB_VIEWER)"
|
||||||
>
|
>
|
||||||
<gl-icon name="code" :size="14" />
|
<gl-icon name="code" :size="14" />
|
||||||
</gl-deprecated-button>
|
</gl-button>
|
||||||
<gl-deprecated-button
|
<gl-button
|
||||||
v-gl-tooltip.hover
|
v-gl-tooltip.hover
|
||||||
:aria-label="$options.RICH_BLOB_VIEWER_TITLE"
|
:aria-label="$options.RICH_BLOB_VIEWER_TITLE"
|
||||||
:title="$options.RICH_BLOB_VIEWER_TITLE"
|
:title="$options.RICH_BLOB_VIEWER_TITLE"
|
||||||
|
@ -65,6 +65,6 @@ export default {
|
||||||
@click="switchToViewer($options.RICH_BLOB_VIEWER)"
|
@click="switchToViewer($options.RICH_BLOB_VIEWER)"
|
||||||
>
|
>
|
||||||
<gl-icon name="document" :size="14" />
|
<gl-icon name="document" :size="14" />
|
||||||
</gl-deprecated-button>
|
</gl-button>
|
||||||
</gl-button-group>
|
</gl-button-group>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -25,7 +25,7 @@ export const BLOB_RENDER_ERRORS = {
|
||||||
TOO_LARGE: {
|
TOO_LARGE: {
|
||||||
id: 'too_large',
|
id: 'too_large',
|
||||||
text: sprintf(__('it is larger than %{limit}'), {
|
text: sprintf(__('it is larger than %{limit}'), {
|
||||||
limit: numberToHumanSize(104857600), // 100MB in bytes
|
limit: numberToHumanSize(10485760), // 10MB in bytes
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
EXTERNAL: {
|
EXTERNAL: {
|
||||||
|
|
|
@ -62,9 +62,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="js-notebook-viewer-mounted container-fluid md gl-mt-3 gl-mb-3">
|
||||||
class="js-notebook-viewer-mounted container-fluid md prepend-top-default append-bottom-default"
|
|
||||||
>
|
|
||||||
<div v-if="loading && !error" class="text-center loading">
|
<div v-if="loading && !error" class="text-center loading">
|
||||||
<gl-loading-icon class="mt-5" size="lg" />
|
<gl-loading-icon class="mt-5" size="lg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="js-pdf-viewer container-fluid md prepend-top-default append-bottom-default">
|
<div class="js-pdf-viewer container-fluid md gl-mt-3 gl-mb-3">
|
||||||
<div v-if="loading && !error" class="text-center loading">
|
<div v-if="loading && !error" class="text-center loading">
|
||||||
<gl-loading-icon class="mt-5" size="lg" />
|
<gl-loading-icon class="mt-5" size="lg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -56,7 +56,7 @@ export default class SketchLoader {
|
||||||
error() {
|
error() {
|
||||||
const errorMsg = document.createElement('p');
|
const errorMsg = document.createElement('p');
|
||||||
|
|
||||||
errorMsg.className = 'prepend-top-default append-bottom-default text-center';
|
errorMsg.className = 'gl-mt-3 gl-mb-3 text-center';
|
||||||
errorMsg.textContent = __(`
|
errorMsg.textContent = __(`
|
||||||
Cannot show preview. For previews on sketch files, they must have the file format
|
Cannot show preview. For previews on sketch files, they must have the file format
|
||||||
introduced by Sketch version 43 and above.
|
introduced by Sketch version 43 and above.
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { GlPopover, GlSprintf, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
|
import { GlPopover, GlSprintf, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
|
||||||
import { parseBoolean, scrollToElement, setCookie, getCookie } from '~/lib/utils/common_utils';
|
import { parseBoolean, scrollToElement, setCookie, getCookie } from '~/lib/utils/common_utils';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import { glEmojiTag } from '~/emoji';
|
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
|
|
||||||
const trackingMixin = Tracking.mixin();
|
const trackingMixin = Tracking.mixin();
|
||||||
|
@ -11,14 +10,16 @@ const popoverStates = {
|
||||||
suggest_gitlab_ci_yml: {
|
suggest_gitlab_ci_yml: {
|
||||||
title: s__(`suggestPipeline|1/2: Choose a template`),
|
title: s__(`suggestPipeline|1/2: Choose a template`),
|
||||||
content: s__(
|
content: s__(
|
||||||
`suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}`,
|
`suggestPipeline|We’re adding a GitLab CI configuration file to add a pipeline to the project. You could create it manually, but we recommend that you start with a GitLab template that works out of the box.`,
|
||||||
|
),
|
||||||
|
footer: s__(
|
||||||
|
`suggestPipeline|Choose %{boldStart}Code Quality%{boldEnd} to add a pipeline that tests the quality of your code.`,
|
||||||
),
|
),
|
||||||
emoji: glEmojiTag('wave'),
|
|
||||||
},
|
},
|
||||||
suggest_commit_first_project_gitlab_ci_yml: {
|
suggest_commit_first_project_gitlab_ci_yml: {
|
||||||
title: s__(`suggestPipeline|2/2: Commit your changes`),
|
title: s__(`suggestPipeline|2/2: Commit your changes`),
|
||||||
content: s__(
|
content: s__(
|
||||||
`suggestPipeline|Commit the changes and your pipeline will automatically run for the first time.`,
|
`suggestPipeline|The template is ready! You can now commit it to create your first pipeline.`,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -66,6 +67,9 @@ export default {
|
||||||
suggestContent() {
|
suggestContent() {
|
||||||
return popoverStates[this.trackLabel].content || '';
|
return popoverStates[this.trackLabel].content || '';
|
||||||
},
|
},
|
||||||
|
suggestFooter() {
|
||||||
|
return popoverStates[this.trackLabel].footer || '';
|
||||||
|
},
|
||||||
emoji() {
|
emoji() {
|
||||||
return popoverStates[this.trackLabel].emoji || '';
|
return popoverStates[this.trackLabel].emoji || '';
|
||||||
},
|
},
|
||||||
|
@ -123,16 +127,13 @@ export default {
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<gl-sprintf :message="suggestContent">
|
<gl-sprintf :message="suggestContent" />
|
||||||
<template #bold="{content}">
|
<div class="mt-3">
|
||||||
|
<gl-sprintf :message="suggestFooter">
|
||||||
|
<template #bold="{ content }">
|
||||||
<strong> {{ content }} </strong>
|
<strong> {{ content }} </strong>
|
||||||
</template>
|
</template>
|
||||||
<template #footer="{content}">
|
|
||||||
<div class="mt-3">
|
|
||||||
{{ content }}
|
|
||||||
<span v-html="emoji"></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</gl-sprintf>
|
</gl-sprintf>
|
||||||
|
</div>
|
||||||
</gl-popover>
|
</gl-popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import '~/behaviors/markdown/render_gfm';
|
||||||
import Flash from '../../flash';
|
import Flash from '../../flash';
|
||||||
import { handleLocationHash } from '../../lib/utils/common_utils';
|
import { handleLocationHash } from '../../lib/utils/common_utils';
|
||||||
import axios from '../../lib/utils/axios_utils';
|
import axios from '../../lib/utils/axios_utils';
|
||||||
|
import eventHub from '../../notes/event_hub';
|
||||||
import { __ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
|
|
||||||
const loadRichBlobViewer = type => {
|
const loadRichBlobViewer = type => {
|
||||||
|
@ -178,6 +179,10 @@ export default class BlobViewer {
|
||||||
viewer.innerHTML = data.html;
|
viewer.innerHTML = data.html;
|
||||||
viewer.setAttribute('data-loaded', 'true');
|
viewer.setAttribute('data-loaded', 'true');
|
||||||
|
|
||||||
|
if (window.gon?.features?.codeNavigation) {
|
||||||
|
eventHub.$emit('showBlobInteractionZones', viewer.dataset.path);
|
||||||
|
}
|
||||||
|
|
||||||
return viewer;
|
return viewer;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import NewCommitForm from '../new_commit_form';
|
||||||
import EditBlob from './edit_blob';
|
import EditBlob from './edit_blob';
|
||||||
import BlobFileDropzone from '../blob/blob_file_dropzone';
|
import BlobFileDropzone from '../blob/blob_file_dropzone';
|
||||||
import initPopover from '~/blob/suggest_gitlab_ci_yml';
|
import initPopover from '~/blob/suggest_gitlab_ci_yml';
|
||||||
import { setCookie } from '~/lib/utils/common_utils';
|
import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
@ -51,10 +51,7 @@ export default () => {
|
||||||
new BlobFileDropzone(uploadBlobForm, method);
|
new BlobFileDropzone(uploadBlobForm, method);
|
||||||
new NewCommitForm(uploadBlobForm);
|
new NewCommitForm(uploadBlobForm);
|
||||||
|
|
||||||
window.gl.utils.disableButtonIfEmptyField(
|
disableButtonIfEmptyField(uploadBlobForm.find('.js-commit-message'), '.btn-upload-file');
|
||||||
uploadBlobForm.find('.js-commit-message'),
|
|
||||||
'.btn-upload-file',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteBlobForm.length) {
|
if (deleteBlobForm.length) {
|
||||||
|
|
4
app/assets/javascripts/blob_edit/constants.js
Normal file
4
app/assets/javascripts/blob_edit/constants.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { __ } from '~/locale';
|
||||||
|
|
||||||
|
export const BLOB_EDITOR_ERROR = __('An error occurred while rendering the editor');
|
||||||
|
export const BLOB_PREVIEW_ERROR = __('An error occurred previewing the blob');
|
|
@ -3,39 +3,87 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { __ } from '~/locale';
|
import { BLOB_EDITOR_ERROR, BLOB_PREVIEW_ERROR } from './constants';
|
||||||
import TemplateSelectorMediator from '../blob/file_template_mediator';
|
import TemplateSelectorMediator from '../blob/file_template_mediator';
|
||||||
import getModeByFileExtension from '~/lib/utils/ace_utils';
|
import getModeByFileExtension from '~/lib/utils/ace_utils';
|
||||||
import { addEditorMarkdownListeners } from '~/lib/utils/text_markdown';
|
import { addEditorMarkdownListeners } from '~/lib/utils/text_markdown';
|
||||||
|
|
||||||
|
const monacoEnabledGlobally = window.gon.features?.monacoBlobs;
|
||||||
|
|
||||||
export default class EditBlob {
|
export default class EditBlob {
|
||||||
// The options object has:
|
// The options object has:
|
||||||
// assetsPath, filePath, currentAction, projectId, isMarkdown
|
// assetsPath, filePath, currentAction, projectId, isMarkdown
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.configureAceEditor();
|
this.options.monacoEnabled = this.options.monacoEnabled ?? monacoEnabledGlobally;
|
||||||
|
const { isMarkdown, monacoEnabled } = this.options;
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
return monacoEnabled ? this.configureMonacoEditor() : this.configureAceEditor();
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.initModePanesAndLinks();
|
this.initModePanesAndLinks();
|
||||||
this.initSoftWrap();
|
|
||||||
this.initFileSelectors();
|
this.initFileSelectors();
|
||||||
|
this.initSoftWrap();
|
||||||
|
if (isMarkdown) {
|
||||||
|
addEditorMarkdownListeners(this.editor);
|
||||||
|
}
|
||||||
|
this.editor.focus();
|
||||||
|
})
|
||||||
|
.catch(() => createFlash(BLOB_EDITOR_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
configureMonacoEditor() {
|
||||||
|
const EditorPromise = import(
|
||||||
|
/* webpackChunkName: 'monaco_editor_lite' */ '~/editor/editor_lite'
|
||||||
|
);
|
||||||
|
const MarkdownExtensionPromise = this.options.isMarkdown
|
||||||
|
? import('~/editor/editor_markdown_ext')
|
||||||
|
: Promise.resolve(false);
|
||||||
|
|
||||||
|
return Promise.all([EditorPromise, MarkdownExtensionPromise])
|
||||||
|
.then(([EditorModule, MarkdownExtension]) => {
|
||||||
|
const EditorLite = EditorModule.default;
|
||||||
|
const editorEl = document.getElementById('editor');
|
||||||
|
const fileNameEl =
|
||||||
|
document.getElementById('file_path') || document.getElementById('file_name');
|
||||||
|
const fileContentEl = document.getElementById('file-content');
|
||||||
|
const form = document.querySelector('.js-edit-blob-form');
|
||||||
|
|
||||||
|
this.editor = new EditorLite();
|
||||||
|
|
||||||
|
if (MarkdownExtension) {
|
||||||
|
this.editor.use(MarkdownExtension.default);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.createInstance({
|
||||||
|
el: editorEl,
|
||||||
|
blobPath: fileNameEl.value,
|
||||||
|
blobContent: editorEl.innerText,
|
||||||
|
});
|
||||||
|
|
||||||
|
fileNameEl.addEventListener('change', () => {
|
||||||
|
this.editor.updateModelLanguage(fileNameEl.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
form.addEventListener('submit', () => {
|
||||||
|
fileContentEl.value = this.editor.getValue();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => createFlash(BLOB_EDITOR_ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
configureAceEditor() {
|
configureAceEditor() {
|
||||||
const { filePath, assetsPath, isMarkdown } = this.options;
|
const { filePath, assetsPath } = this.options;
|
||||||
ace.config.set('modePath', `${assetsPath}/ace`);
|
ace.config.set('modePath', `${assetsPath}/ace`);
|
||||||
ace.config.loadModule('ace/ext/searchbox');
|
ace.config.loadModule('ace/ext/searchbox');
|
||||||
ace.config.loadModule('ace/ext/modelist');
|
ace.config.loadModule('ace/ext/modelist');
|
||||||
|
|
||||||
this.editor = ace.edit('editor');
|
this.editor = ace.edit('editor');
|
||||||
|
|
||||||
if (isMarkdown) {
|
|
||||||
addEditorMarkdownListeners(this.editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This prevents warnings re: automatic scrolling being logged
|
// This prevents warnings re: automatic scrolling being logged
|
||||||
this.editor.$blockScrolling = Infinity;
|
this.editor.$blockScrolling = Infinity;
|
||||||
|
|
||||||
this.editor.focus();
|
|
||||||
|
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
this.editor.getSession().setMode(getModeByFileExtension(filePath));
|
this.editor.getSession().setMode(getModeByFileExtension(filePath));
|
||||||
}
|
}
|
||||||
|
@ -81,7 +129,7 @@ export default class EditBlob {
|
||||||
currentPane.empty().append(data);
|
currentPane.empty().append(data);
|
||||||
currentPane.renderGFM();
|
currentPane.renderGFM();
|
||||||
})
|
})
|
||||||
.catch(() => createFlash(__('An error occurred previewing the blob')));
|
.catch(() => createFlash(BLOB_PREVIEW_ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$toggleButton.show();
|
this.$toggleButton.show();
|
||||||
|
@ -90,14 +138,19 @@ export default class EditBlob {
|
||||||
}
|
}
|
||||||
|
|
||||||
initSoftWrap() {
|
initSoftWrap() {
|
||||||
this.isSoftWrapped = false;
|
this.isSoftWrapped = Boolean(this.options.monacoEnabled);
|
||||||
this.$toggleButton = $('.soft-wrap-toggle');
|
this.$toggleButton = $('.soft-wrap-toggle');
|
||||||
|
this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped);
|
||||||
this.$toggleButton.on('click', () => this.toggleSoftWrap());
|
this.$toggleButton.on('click', () => this.toggleSoftWrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSoftWrap() {
|
toggleSoftWrap() {
|
||||||
this.isSoftWrapped = !this.isSoftWrapped;
|
this.isSoftWrapped = !this.isSoftWrapped;
|
||||||
this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped);
|
this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped);
|
||||||
|
if (this.options.monacoEnabled) {
|
||||||
|
this.editor.updateOptions({ wordWrap: this.isSoftWrapped ? 'on' : 'off' });
|
||||||
|
} else {
|
||||||
this.editor.getSession().setUseWrapMode(this.isSoftWrapped);
|
this.editor.getSession().setUseWrapMode(this.isSoftWrapped);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,192 +0,0 @@
|
||||||
import $ from 'jquery';
|
|
||||||
import Sortable from 'sortablejs';
|
|
||||||
import Vue from 'vue';
|
|
||||||
import { GlButtonGroup, GlDeprecatedButton, GlLabel, GlTooltip } from '@gitlab/ui';
|
|
||||||
import isWipLimitsOn from 'ee_else_ce/boards/mixins/is_wip_limits';
|
|
||||||
import { s__, __, sprintf } from '~/locale';
|
|
||||||
import Icon from '~/vue_shared/components/icon.vue';
|
|
||||||
import Tooltip from '~/vue_shared/directives/tooltip';
|
|
||||||
import AccessorUtilities from '../../lib/utils/accessor';
|
|
||||||
import BoardBlankState from './board_blank_state.vue';
|
|
||||||
import BoardDelete from './board_delete';
|
|
||||||
import BoardList from './board_list.vue';
|
|
||||||
import IssueCount from './issue_count.vue';
|
|
||||||
import boardsStore from '../stores/boards_store';
|
|
||||||
import { getBoardSortableDefaultOptions, sortableEnd } from '../mixins/sortable_default_options';
|
|
||||||
import { ListType } from '../constants';
|
|
||||||
import { isScopedLabel } from '~/lib/utils/common_utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Please don't edit this file, have a look at:
|
|
||||||
* ./board_column.vue
|
|
||||||
* https://gitlab.com/gitlab-org/gitlab/-/issues/212300
|
|
||||||
*
|
|
||||||
* This file here will be deleted soon
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
export default Vue.extend({
|
|
||||||
components: {
|
|
||||||
BoardBlankState,
|
|
||||||
BoardDelete,
|
|
||||||
BoardList,
|
|
||||||
Icon,
|
|
||||||
GlButtonGroup,
|
|
||||||
IssueCount,
|
|
||||||
GlDeprecatedButton,
|
|
||||||
GlLabel,
|
|
||||||
GlTooltip,
|
|
||||||
},
|
|
||||||
directives: {
|
|
||||||
Tooltip,
|
|
||||||
},
|
|
||||||
mixins: [isWipLimitsOn],
|
|
||||||
props: {
|
|
||||||
list: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({}),
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
issueLinkBase: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
rootPath: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
boardId: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
// Does not do anything but is used
|
|
||||||
// to support the API of the new board_column.vue
|
|
||||||
canAdminList: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
detailIssue: boardsStore.detail,
|
|
||||||
filter: boardsStore.filter,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isLoggedIn() {
|
|
||||||
return Boolean(gon.current_user_id);
|
|
||||||
},
|
|
||||||
showListHeaderButton() {
|
|
||||||
return (
|
|
||||||
!this.disabled && this.list.type !== ListType.closed && this.list.type !== ListType.blank
|
|
||||||
);
|
|
||||||
},
|
|
||||||
issuesTooltip() {
|
|
||||||
const { issuesSize } = this.list;
|
|
||||||
|
|
||||||
return sprintf(__('%{issuesSize} issues'), { issuesSize });
|
|
||||||
},
|
|
||||||
// Only needed to make karma pass.
|
|
||||||
weightCountToolTip() {}, // eslint-disable-line vue/return-in-computed-property
|
|
||||||
caretTooltip() {
|
|
||||||
return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
|
|
||||||
},
|
|
||||||
isNewIssueShown() {
|
|
||||||
return this.list.type === ListType.backlog || this.showListHeaderButton;
|
|
||||||
},
|
|
||||||
isSettingsShown() {
|
|
||||||
return (
|
|
||||||
this.list.type !== ListType.backlog &&
|
|
||||||
this.showListHeaderButton &&
|
|
||||||
this.list.isExpanded &&
|
|
||||||
this.isWipLimitsOn
|
|
||||||
);
|
|
||||||
},
|
|
||||||
showBoardListAndBoardInfo() {
|
|
||||||
return this.list.type !== ListType.blank && this.list.type !== ListType.promotion;
|
|
||||||
},
|
|
||||||
uniqueKey() {
|
|
||||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
|
||||||
return `boards.${this.boardId}.${this.list.type}.${this.list.id}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
filter: {
|
|
||||||
handler() {
|
|
||||||
this.list.page = 1;
|
|
||||||
this.list.getIssues(true).catch(() => {
|
|
||||||
// TODO: handle request error
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deep: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
const instance = this;
|
|
||||||
|
|
||||||
const sortableOptions = getBoardSortableDefaultOptions({
|
|
||||||
disabled: this.disabled,
|
|
||||||
group: 'boards',
|
|
||||||
draggable: '.is-draggable',
|
|
||||||
handle: '.js-board-handle',
|
|
||||||
onEnd(e) {
|
|
||||||
sortableEnd();
|
|
||||||
|
|
||||||
const sortable = this;
|
|
||||||
|
|
||||||
if (e.newIndex !== undefined && e.oldIndex !== e.newIndex) {
|
|
||||||
const order = sortable.toArray();
|
|
||||||
const list = boardsStore.findList('id', parseInt(e.item.dataset.id, 10));
|
|
||||||
|
|
||||||
instance.$nextTick(() => {
|
|
||||||
boardsStore.moveList(list, order);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Sortable.create(this.$el.parentNode, sortableOptions);
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (
|
|
||||||
this.list.isExpandable &&
|
|
||||||
AccessorUtilities.isLocalStorageAccessSafe() &&
|
|
||||||
!this.isLoggedIn
|
|
||||||
) {
|
|
||||||
const isCollapsed = localStorage.getItem(`${this.uniqueKey}.expanded`) === 'false';
|
|
||||||
|
|
||||||
this.list.isExpanded = !isCollapsed;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showScopedLabels(label) {
|
|
||||||
return boardsStore.scopedLabels.enabled && isScopedLabel(label);
|
|
||||||
},
|
|
||||||
|
|
||||||
showNewIssueForm() {
|
|
||||||
this.$refs['board-list'].showIssueForm = !this.$refs['board-list'].showIssueForm;
|
|
||||||
},
|
|
||||||
toggleExpanded() {
|
|
||||||
if (this.list.isExpandable) {
|
|
||||||
this.list.isExpanded = !this.list.isExpanded;
|
|
||||||
|
|
||||||
if (AccessorUtilities.isLocalStorageAccessSafe() && !this.isLoggedIn) {
|
|
||||||
localStorage.setItem(`${this.uniqueKey}.expanded`, this.list.isExpanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isLoggedIn) {
|
|
||||||
this.list.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// When expanding/collapsing, the tooltip on the caret button sometimes stays open.
|
|
||||||
// Close all tooltips manually to prevent dangling tooltips.
|
|
||||||
$('.tooltip').tooltip('hide');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
template: '#js-board-template',
|
|
||||||
});
|
|
|
@ -54,7 +54,7 @@ export default {
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
v-if="!isSwimlanesOn"
|
v-if="!isSwimlanesOn"
|
||||||
class="boards-list w-100 py-3 px-2 text-nowrap"
|
class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap"
|
||||||
data-qa-selector="boards_list"
|
data-qa-selector="boards_list"
|
||||||
>
|
>
|
||||||
<board-column
|
<board-column
|
||||||
|
@ -77,6 +77,7 @@ export default {
|
||||||
:can-admin-list="canAdminList"
|
:can-admin-list="canAdminList"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:board-id="boardId"
|
:board-id="boardId"
|
||||||
|
:group-id="groupId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,10 +5,11 @@ import {
|
||||||
GlLabel,
|
GlLabel,
|
||||||
GlTooltip,
|
GlTooltip,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
|
GlSprintf,
|
||||||
GlTooltipDirective,
|
GlTooltipDirective,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import isWipLimitsOn from 'ee_else_ce/boards/mixins/is_wip_limits';
|
import isWipLimitsOn from 'ee_else_ce/boards/mixins/is_wip_limits';
|
||||||
import { s__, __, sprintf } from '~/locale';
|
import { n__, s__ } from '~/locale';
|
||||||
import AccessorUtilities from '../../lib/utils/accessor';
|
import AccessorUtilities from '../../lib/utils/accessor';
|
||||||
import BoardDelete from './board_delete';
|
import BoardDelete from './board_delete';
|
||||||
import IssueCount from './issue_count.vue';
|
import IssueCount from './issue_count.vue';
|
||||||
|
@ -25,6 +26,7 @@ export default {
|
||||||
GlLabel,
|
GlLabel,
|
||||||
GlTooltip,
|
GlTooltip,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
|
GlSprintf,
|
||||||
IssueCount,
|
IssueCount,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
|
@ -82,10 +84,20 @@ export default {
|
||||||
this.listType !== ListType.promotion
|
this.listType !== ListType.promotion
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
issuesTooltip() {
|
showMilestoneListDetails() {
|
||||||
|
return (
|
||||||
|
this.list.type === 'milestone' &&
|
||||||
|
this.list.milestone &&
|
||||||
|
(this.list.isExpanded || !this.isSwimlanesHeader)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
showAssigneeListDetails() {
|
||||||
|
return this.list.type === 'assignee' && (this.list.isExpanded || !this.isSwimlanesHeader);
|
||||||
|
},
|
||||||
|
issuesTooltipLabel() {
|
||||||
const { issuesSize } = this.list;
|
const { issuesSize } = this.list;
|
||||||
|
|
||||||
return sprintf(__('%{issuesSize} issues'), { issuesSize });
|
return n__(`%d issue`, `%d issues`, issuesSize);
|
||||||
},
|
},
|
||||||
chevronTooltip() {
|
chevronTooltip() {
|
||||||
return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
|
return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
|
||||||
|
@ -111,6 +123,9 @@ export default {
|
||||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||||
return `boards.${this.boardId}.${this.listType}.${this.list.id}`;
|
return `boards.${this.boardId}.${this.listType}.${this.list.id}`;
|
||||||
},
|
},
|
||||||
|
collapsedTooltipTitle() {
|
||||||
|
return this.listTitle || this.listAssignee;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showScopedLabels(label) {
|
showScopedLabels(label) {
|
||||||
|
@ -147,7 +162,7 @@ export default {
|
||||||
'has-border': list.label && list.label.color,
|
'has-border': list.label && list.label.color,
|
||||||
'gl-relative': list.isExpanded,
|
'gl-relative': list.isExpanded,
|
||||||
'gl-h-full': !list.isExpanded,
|
'gl-h-full': !list.isExpanded,
|
||||||
'board-inner gl-rounded-base gl-border-b-0': isSwimlanesHeader,
|
'board-inner gl-rounded-top-left-base gl-rounded-top-right-base': isSwimlanesHeader,
|
||||||
}"
|
}"
|
||||||
:style="{ borderTopColor: list.label && list.label.color ? list.label.color : null }"
|
:style="{ borderTopColor: list.label && list.label.color ? list.label.color : null }"
|
||||||
class="board-header gl-relative"
|
class="board-header gl-relative"
|
||||||
|
@ -157,7 +172,9 @@ export default {
|
||||||
<h3
|
<h3
|
||||||
:class="{
|
:class="{
|
||||||
'user-can-drag': !disabled && !list.preset,
|
'user-can-drag': !disabled && !list.preset,
|
||||||
'gl-border-b-0': !list.isExpanded,
|
'gl-py-3': !list.isExpanded && !isSwimlanesHeader,
|
||||||
|
'gl-border-b-0': !list.isExpanded || isSwimlanesHeader,
|
||||||
|
'gl-py-2': !list.isExpanded && isSwimlanesHeader,
|
||||||
}"
|
}"
|
||||||
class="board-title gl-m-0 gl-display-flex js-board-handle"
|
class="board-title gl-m-0 gl-display-flex js-board-handle"
|
||||||
>
|
>
|
||||||
|
@ -167,21 +184,17 @@ export default {
|
||||||
:aria-label="chevronTooltip"
|
:aria-label="chevronTooltip"
|
||||||
:title="chevronTooltip"
|
:title="chevronTooltip"
|
||||||
:icon="chevronIcon"
|
:icon="chevronIcon"
|
||||||
class="board-title-caret no-drag"
|
class="board-title-caret no-drag gl-cursor-pointer"
|
||||||
variant="link"
|
variant="link"
|
||||||
@click="toggleExpanded"
|
@click="toggleExpanded"
|
||||||
/>
|
/>
|
||||||
<!-- The following is only true in EE and if it is a milestone -->
|
<!-- The following is only true in EE and if it is a milestone -->
|
||||||
<span
|
<span v-if="showMilestoneListDetails" aria-hidden="true" class="gl-mr-2 milestone-icon">
|
||||||
v-if="list.type === 'milestone' && list.milestone"
|
|
||||||
aria-hidden="true"
|
|
||||||
class="gl-mr-2 milestone-icon"
|
|
||||||
>
|
|
||||||
<gl-icon name="timer" />
|
<gl-icon name="timer" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
v-if="list.type === 'assignee'"
|
v-if="showAssigneeListDetails"
|
||||||
:href="list.assignee.path"
|
:href="list.assignee.path"
|
||||||
class="user-avatar-link js-no-trigger"
|
class="user-avatar-link js-no-trigger"
|
||||||
>
|
>
|
||||||
|
@ -195,7 +208,10 @@ export default {
|
||||||
width="20"
|
width="20"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<div class="board-title-text">
|
<div
|
||||||
|
class="board-title-text"
|
||||||
|
:class="{ 'gl-display-none': !list.isExpanded && isSwimlanesHeader }"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="list.type !== 'label'"
|
v-if="list.type !== 'label'"
|
||||||
v-gl-tooltip.hover
|
v-gl-tooltip.hover
|
||||||
|
@ -208,7 +224,7 @@ export default {
|
||||||
{{ list.title }}
|
{{ list.title }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="list.type === 'assignee'" class="board-title-sub-text gl-ml-2">
|
<span v-if="list.type === 'assignee'" class="board-title-sub-text gl-ml-2">
|
||||||
@{{ list.assignee.username }}
|
@{{ listAssignee }}
|
||||||
</span>
|
</span>
|
||||||
<gl-label
|
<gl-label
|
||||||
v-if="list.type === 'label'"
|
v-if="list.type === 'label'"
|
||||||
|
@ -220,6 +236,33 @@ export default {
|
||||||
:title="list.label.title"
|
:title="list.label.title"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-if="isSwimlanesHeader && !list.isExpanded"
|
||||||
|
ref="collapsedInfo"
|
||||||
|
aria-hidden="true"
|
||||||
|
class="board-header-collapsed-info-icon gl-mt-2 gl-cursor-pointer gl-text-gray-700"
|
||||||
|
>
|
||||||
|
<gl-icon name="information" />
|
||||||
|
</span>
|
||||||
|
<gl-tooltip v-if="isSwimlanesHeader && !list.isExpanded" :target="() => $refs.collapsedInfo">
|
||||||
|
<div class="gl-font-weight-bold gl-pb-2">{{ collapsedTooltipTitle }}</div>
|
||||||
|
<div v-if="list.maxIssueCount !== 0">
|
||||||
|
•
|
||||||
|
<gl-sprintf :message="__('%{issuesSize} with a limit of %{maxIssueCount}')">
|
||||||
|
<template #issuesSize>{{ issuesTooltipLabel }}</template>
|
||||||
|
<template #maxIssueCount>{{ list.maxIssueCount }}</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
</div>
|
||||||
|
<div v-else>• {{ issuesTooltipLabel }}</div>
|
||||||
|
<div v-if="weightFeatureAvailable">
|
||||||
|
•
|
||||||
|
<gl-sprintf :message="__('%{totalWeight} total weight')">
|
||||||
|
<template #totalWeight>{{ list.totalWeight }}</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
</div>
|
||||||
|
</gl-tooltip>
|
||||||
|
|
||||||
<board-delete
|
<board-delete
|
||||||
v-if="canAdminList && !list.preset && list.id"
|
v-if="canAdminList && !list.preset && list.id"
|
||||||
:list="list"
|
:list="list"
|
||||||
|
@ -229,7 +272,7 @@ export default {
|
||||||
v-gl-tooltip.hover.bottom
|
v-gl-tooltip.hover.bottom
|
||||||
:class="{ 'gl-display-none': !list.isExpanded }"
|
:class="{ 'gl-display-none': !list.isExpanded }"
|
||||||
:aria-label="__('Delete list')"
|
:aria-label="__('Delete list')"
|
||||||
class="board-delete no-drag gl-pr-0 gl-shadow-none gl-mr-3"
|
class="board-delete no-drag gl-pr-0 gl-shadow-none! gl-mr-3"
|
||||||
:title="__('Delete list')"
|
:title="__('Delete list')"
|
||||||
icon="remove"
|
icon="remove"
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -238,10 +281,11 @@ export default {
|
||||||
</board-delete>
|
</board-delete>
|
||||||
<div
|
<div
|
||||||
v-if="showBoardListAndBoardInfo"
|
v-if="showBoardListAndBoardInfo"
|
||||||
class="issue-count-badge gl-pr-0 no-drag text-secondary"
|
class="issue-count-badge gl-display-inline-flex gl-pr-0 no-drag text-secondary"
|
||||||
|
:class="{ 'gl-display-none': !list.isExpanded && isSwimlanesHeader }"
|
||||||
>
|
>
|
||||||
<span class="gl-display-inline-flex">
|
<span class="gl-display-inline-flex">
|
||||||
<gl-tooltip :target="() => $refs.issueCount" :title="issuesTooltip" />
|
<gl-tooltip :target="() => $refs.issueCount" :title="issuesTooltipLabel" />
|
||||||
<span ref="issueCount" class="issue-count-badge-count">
|
<span ref="issueCount" class="issue-count-badge-count">
|
||||||
<gl-icon class="gl-mr-2" name="issues" />
|
<gl-icon class="gl-mr-2" name="issues" />
|
||||||
<issue-count :issues-size="list.issuesSize" :max-issue-count="list.maxIssueCount" />
|
<issue-count :issues-size="list.issuesSize" :max-issue-count="list.maxIssueCount" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { GlDeprecatedButton } from '@gitlab/ui';
|
import { GlButton } from '@gitlab/ui';
|
||||||
import { getMilestone } from 'ee_else_ce/boards/boards_util';
|
import { getMilestone } from 'ee_else_ce/boards/boards_util';
|
||||||
import ListIssue from 'ee_else_ce/boards/models/issue';
|
import ListIssue from 'ee_else_ce/boards/models/issue';
|
||||||
import eventHub from '../eventhub';
|
import eventHub from '../eventhub';
|
||||||
|
@ -11,7 +11,7 @@ export default {
|
||||||
name: 'BoardNewIssue',
|
name: 'BoardNewIssue',
|
||||||
components: {
|
components: {
|
||||||
ProjectSelect,
|
ProjectSelect,
|
||||||
GlDeprecatedButton,
|
GlButton,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
groupId: {
|
groupId: {
|
||||||
|
@ -120,21 +120,18 @@ export default {
|
||||||
/>
|
/>
|
||||||
<project-select v-if="groupId" :group-id="groupId" :list="list" />
|
<project-select v-if="groupId" :group-id="groupId" :list="list" />
|
||||||
<div class="clearfix prepend-top-10">
|
<div class="clearfix prepend-top-10">
|
||||||
<gl-deprecated-button
|
<gl-button
|
||||||
ref="submit-button"
|
ref="submit-button"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
class="float-left"
|
class="float-left"
|
||||||
variant="success"
|
variant="success"
|
||||||
|
category="primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
>{{ __('Submit issue') }}</gl-deprecated-button
|
>{{ __('Submit issue') }}</gl-button
|
||||||
>
|
|
||||||
<gl-deprecated-button
|
|
||||||
class="float-right"
|
|
||||||
type="button"
|
|
||||||
variant="default"
|
|
||||||
@click="cancel"
|
|
||||||
>{{ __('Cancel') }}</gl-deprecated-button
|
|
||||||
>
|
>
|
||||||
|
<gl-button class="float-right" type="button" variant="default" @click="cancel">{{
|
||||||
|
__('Cancel')
|
||||||
|
}}</gl-button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -233,7 +233,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="boards-switcher js-boards-selector append-right-10">
|
<div class="boards-switcher js-boards-selector gl-mr-3">
|
||||||
<span class="boards-selector-wrapper js-boards-selector-wrapper">
|
<span class="boards-selector-wrapper js-boards-selector-wrapper">
|
||||||
<gl-dropdown
|
<gl-dropdown
|
||||||
data-qa-selector="boards_dropdown"
|
data-qa-selector="boards_dropdown"
|
||||||
|
|
|
@ -153,7 +153,7 @@ export default {
|
||||||
v-gl-tooltip
|
v-gl-tooltip
|
||||||
name="issue-block"
|
name="issue-block"
|
||||||
:title="__('Blocked issue')"
|
:title="__('Blocked issue')"
|
||||||
class="issue-blocked-icon append-right-4"
|
class="issue-blocked-icon gl-mr-2"
|
||||||
:aria-label="__('Blocked issue')"
|
:aria-label="__('Blocked issue')"
|
||||||
/>
|
/>
|
||||||
<icon
|
<icon
|
||||||
|
@ -161,7 +161,7 @@ export default {
|
||||||
v-gl-tooltip
|
v-gl-tooltip
|
||||||
name="eye-slash"
|
name="eye-slash"
|
||||||
:title="__('Confidential')"
|
:title="__('Confidential')"
|
||||||
class="confidential-icon append-right-4"
|
class="confidential-icon gl-mr-2"
|
||||||
:aria-label="__('Confidential')"
|
:aria-label="__('Confidential')"
|
||||||
/>
|
/>
|
||||||
<a :href="issue.path" :title="issue.title" class="js-no-trigger" @mousemove.stop>{{
|
<a :href="issue.path" :title="issue.title" class="js-no-trigger" @mousemove.stop>{{
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default {
|
||||||
<button
|
<button
|
||||||
ref="selectAllBtn"
|
ref="selectAllBtn"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-success btn-inverted prepend-left-10"
|
class="btn btn-success btn-inverted gl-ml-3"
|
||||||
@click="toggleAll"
|
@click="toggleAll"
|
||||||
>
|
>
|
||||||
{{ selectAllText }}
|
{{ selectAllText }}
|
||||||
|
|
|
@ -80,15 +80,7 @@ export default () => {
|
||||||
el: $boardApp,
|
el: $boardApp,
|
||||||
components: {
|
components: {
|
||||||
BoardContent,
|
BoardContent,
|
||||||
Board: () =>
|
Board: () => import('ee_else_ce/boards/components/board_column.vue'),
|
||||||
window?.gon?.features?.sfcIssueBoards
|
|
||||||
? import('ee_else_ce/boards/components/board_column.vue')
|
|
||||||
: /**
|
|
||||||
* Please have a look at, we are moving to the SFC soon:
|
|
||||||
* https://gitlab.com/gitlab-org/gitlab/-/issues/212300
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
import('ee_else_ce/boards/components/board'),
|
|
||||||
BoardSidebar,
|
BoardSidebar,
|
||||||
BoardAddIssuesModal,
|
BoardAddIssuesModal,
|
||||||
BoardSettingsSidebar: () =>
|
BoardSettingsSidebar: () =>
|
||||||
|
@ -360,7 +352,7 @@ export default () => {
|
||||||
template: `
|
template: `
|
||||||
<div class="board-extra-actions">
|
<div class="board-extra-actions">
|
||||||
<button
|
<button
|
||||||
class="btn btn-success prepend-left-10"
|
class="btn btn-success gl-ml-3"
|
||||||
type="button"
|
type="button"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
ref="addIssuesButton"
|
ref="addIssuesButton"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue