New upstream version 13.5.5
This commit is contained in:
parent
03a7b5db89
commit
30798b500b
6091 changed files with 237405 additions and 85396 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -96,4 +96,4 @@ apollo.config.js
|
||||||
/tmp/matching_foss_tests.txt
|
/tmp/matching_foss_tests.txt
|
||||||
/tmp/matching_tests.txt
|
/tmp/matching_tests.txt
|
||||||
ee/changelogs/unreleased-ee
|
ee/changelogs/unreleased-ee
|
||||||
|
/sitespeed-result
|
||||||
|
|
|
@ -17,7 +17,7 @@ stages:
|
||||||
# in cases where jobs require Docker-in-Docker, the job
|
# in cases where jobs require Docker-in-Docker, the job
|
||||||
# definition must be extended with `.use-docker-in-docker`
|
# definition must be extended with `.use-docker-in-docker`
|
||||||
default:
|
default:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.28-lfs-2.9-chrome-84-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.28-lfs-2.9-chrome-85-node-12.18-yarn-1.22-postgresql-11-graphicsmagick-1.3.34"
|
||||||
tags:
|
tags:
|
||||||
- gitlab-org
|
- gitlab-org
|
||||||
# All jobs are interruptible by default
|
# All jobs are interruptible by default
|
||||||
|
|
|
@ -184,7 +184,7 @@ Dangerfile @gl-quality/eng-prod
|
||||||
/lib/gitlab/auth/ldap/ @dblessing @mkozono
|
/lib/gitlab/auth/ldap/ @dblessing @mkozono
|
||||||
|
|
||||||
[Templates]
|
[Templates]
|
||||||
/lib/gitlab/ci/templates/ @nolith @dosuken123
|
/lib/gitlab/ci/templates/ @nolith @shinya.maeda
|
||||||
/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
|
||||||
|
|
||||||
|
@ -213,10 +213,10 @@ Dangerfile @gl-quality/eng-prod
|
||||||
/ee/spec/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
|
/doc/user/project/code_owners.md @reprazent @kerrizor @garyh
|
||||||
|
|
||||||
[Telemetry]
|
[Product Analytics]
|
||||||
/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/telemetry/engineers
|
/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product_analytics/engineers
|
||||||
/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/telemetry/engineers
|
/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/product_analytics/engineers
|
||||||
/lib/gitlab/grafana_embed_usage_data.rb @gitlab-org/growth/telemetry/engineers
|
/lib/gitlab/grafana_embed_usage_data.rb @gitlab-org/growth/product_analytics/engineers
|
||||||
/lib/gitlab/usage_data.rb @gitlab-org/growth/telemetry/engineers
|
/lib/gitlab/usage_data.rb @gitlab-org/growth/product_analytics/engineers
|
||||||
/lib/gitlab/cycle_analytics/usage_data.rb @gitlab-org/growth/telemetry/engineers
|
/lib/gitlab/cycle_analytics/usage_data.rb @gitlab-org/growth/product_analytics/engineers
|
||||||
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/telemetry/engineers
|
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product_analytics/engineers
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
# Help pages are excluded from scan as they are static pages.
|
# Help pages are excluded from scan as they are static pages.
|
||||||
# profile/two_factor_auth is excluded from scan to prevent 2FA from being turned on from user profile, which will reduce coverage.
|
# profile/two_factor_auth is excluded from scan to prevent 2FA from being turned on from user profile, which will reduce coverage.
|
||||||
- 'export DAST_AUTH_EXCLUDE_URLS="${DAST_WEBSITE}/help/.*,${DAST_WEBSITE}/profile/two_factor_auth,${DAST_WEBSITE}/users/sign_out"'
|
- 'export DAST_AUTH_EXCLUDE_URLS="${DAST_WEBSITE}/help/.*,${DAST_WEBSITE}/profile/two_factor_auth,${DAST_WEBSITE}/users/sign_out"'
|
||||||
|
# Exclude the automatically generated monitoring project from being tested due to https://gitlab.com/gitlab-org/gitlab/-/issues/260362
|
||||||
|
- 'DAST_AUTH_EXCLUDE_URLS="${DAST_AUTH_EXCLUDE_URLS},https://.*\.gitlab-review\.app/gitlab-instance-(administrators-)?[a-zA-Z0-9]{8}/.*"'
|
||||||
- enable_rule () { read all_rules; rule=$1; echo $all_rules | sed -r "s/(,)?$rule(,)?/\1-1\2/" ; }
|
- enable_rule () { read all_rules; rule=$1; echo $all_rules | sed -r "s/(,)?$rule(,)?/\1-1\2/" ; }
|
||||||
# Sort ids in DAST_RULES ascendingly, which is required when using DAST_RULES as argument to enable_rule
|
# Sort ids in DAST_RULES ascendingly, which is required when using DAST_RULES as argument to enable_rule
|
||||||
- 'DAST_RULES=$(echo $DAST_RULES | tr "," "\n" | sort -n | paste -sd ",")'
|
- 'DAST_RULES=$(echo $DAST_RULES | tr "," "\n" | sort -n | paste -sd ",")'
|
||||||
|
|
|
@ -14,14 +14,17 @@
|
||||||
SIZE: 0 # number of external projects to fork, requires network connection
|
SIZE: 0 # number of external projects to fork, requires network connection
|
||||||
# SEED_NESTED_GROUPS: "false" # requires network connection
|
# SEED_NESTED_GROUPS: "false" # requires network connection
|
||||||
|
|
||||||
|
.run-dev-fixtures-script: &run-dev-fixtures-script
|
||||||
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
|
- run_timed_command "RAILS_ENV=test bundle exec rake db:seed_fu"
|
||||||
|
|
||||||
run-dev-fixtures:
|
run-dev-fixtures:
|
||||||
extends:
|
extends:
|
||||||
- .run-dev-fixtures
|
- .run-dev-fixtures
|
||||||
- .dev-fixtures:rules:ee-and-foss
|
- .dev-fixtures:rules:ee-and-foss
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *run-dev-fixtures-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- run_timed_command "RAILS_ENV=test bundle exec rake db:seed_fu"
|
|
||||||
|
|
||||||
run-dev-fixtures-ee:
|
run-dev-fixtures-ee:
|
||||||
extends:
|
extends:
|
||||||
|
@ -29,7 +32,5 @@ run-dev-fixtures-ee:
|
||||||
- .dev-fixtures:rules:ee-only
|
- .dev-fixtures:rules:ee-only
|
||||||
- .use-pg11-ee
|
- .use-pg11-ee
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- cp ee/db/fixtures/development/* $FIXTURE_PATH
|
- cp ee/db/fixtures/development/* $FIXTURE_PATH
|
||||||
- run_timed_command "RAILS_ENV=test bundle exec rake db:seed_fu"
|
- *run-dev-fixtures-script
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
- .docs:rules:review-docs
|
- .docs:rules:review-docs
|
||||||
image: ruby:2.6-alpine
|
image: ruby:2.6-alpine
|
||||||
stage: review
|
stage: review
|
||||||
dependencies: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
# We're cloning the repo instead of downloading the script for now
|
# We're cloning the repo instead of downloading the script for now
|
||||||
# because some repos are private and CI_JOB_TOKEN cannot access files.
|
# because some repos are private and CI_JOB_TOKEN cannot access files.
|
||||||
|
@ -42,7 +42,7 @@ docs lint:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
- .docs:rules:docs-lint
|
- .docs:rules:docs-lint
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-docs/lint:vale-2.3.4-markdownlint-0.23.2"
|
image: "registry.gitlab.com/gitlab-org/gitlab-docs/lint:ruby-2.7.2-alpine-3.12-vale-2.4.3-markdownlint-0.24.0"
|
||||||
stage: test
|
stage: test
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
|
|
|
@ -7,19 +7,21 @@
|
||||||
# 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
|
||||||
|
|
||||||
|
.yarn-install: &yarn-install
|
||||||
|
- source scripts/utils.sh
|
||||||
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
|
|
||||||
.compile-assets-base:
|
.compile-assets-base:
|
||||||
extends:
|
extends:
|
||||||
- .frontend-base
|
- .frontend-base
|
||||||
- .assets-compile-cache
|
- .assets-compile-cache
|
||||||
image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.28-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.28-lfs-2.9-node-12.18-yarn-1.22-graphicsmagick-1.3.34
|
||||||
variables:
|
variables:
|
||||||
WEBPACK_VENDOR_DLL: "true"
|
WEBPACK_VENDOR_DLL: "true"
|
||||||
stage: prepare
|
stage: prepare
|
||||||
script:
|
script:
|
||||||
- node --version
|
- *yarn-install
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- run_timed_command "bin/rake gitlab:assets:compile"
|
||||||
- free -m
|
|
||||||
- run_timed_command "bin/rake gitlab:assets:compile > assets-compile.log 2>&1"
|
|
||||||
- run_timed_command "scripts/clean-old-cached-assets"
|
- run_timed_command "scripts/clean-old-cached-assets"
|
||||||
|
|
||||||
compile-production-assets:
|
compile-production-assets:
|
||||||
|
@ -34,7 +36,6 @@ compile-production-assets:
|
||||||
name: webpack-report
|
name: webpack-report
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
paths:
|
paths:
|
||||||
- assets-compile.log
|
|
||||||
# These assets are used in multiple locations:
|
# These assets are used in multiple locations:
|
||||||
# - in `build-assets-image` job to create assets image for packaging systems
|
# - in `build-assets-image` job to create assets image for packaging systems
|
||||||
# - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1
|
# - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1
|
||||||
|
@ -51,7 +52,6 @@ compile-test-assets:
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 7d
|
expire_in: 7d
|
||||||
paths:
|
paths:
|
||||||
- assets-compile.log
|
|
||||||
- public/assets/
|
- public/assets/
|
||||||
- node_modules/@gitlab/svgs/dist/icons.json # app/helpers/icons_helper.rb uses this file
|
- node_modules/@gitlab/svgs/dist/icons.json # app/helpers/icons_helper.rb uses this file
|
||||||
when: always
|
when: always
|
||||||
|
@ -87,8 +87,7 @@ update-yarn-cache:
|
||||||
- .shared:rules:update-cache
|
- .shared:rules:update-cache
|
||||||
stage: prepare
|
stage: prepare
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
- *yarn-install
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
|
||||||
cache:
|
cache:
|
||||||
policy: push
|
policy: push
|
||||||
|
|
||||||
|
@ -139,14 +138,14 @@ eslint-as-if-foss:
|
||||||
- .as-if-foss
|
- .as-if-foss
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- *yarn-install
|
||||||
- yarn run eslint
|
- run_timed_command "yarn run eslint"
|
||||||
|
|
||||||
.karma-base:
|
.karma-base:
|
||||||
extends: .frontend-test-base
|
extends: .frontend-test-base
|
||||||
script:
|
script:
|
||||||
- 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"
|
- *yarn-install
|
||||||
- run_timed_command "yarn karma"
|
- run_timed_command "yarn karma"
|
||||||
|
|
||||||
karma:
|
karma:
|
||||||
|
@ -177,7 +176,7 @@ karma-as-if-foss:
|
||||||
.jest-base:
|
.jest-base:
|
||||||
extends: .frontend-test-base
|
extends: .frontend-test-base
|
||||||
script:
|
script:
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- *yarn-install
|
||||||
- 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"
|
||||||
|
|
||||||
jest:
|
jest:
|
||||||
|
@ -202,7 +201,7 @@ jest-integration:
|
||||||
- .frontend-test-base
|
- .frontend-test-base
|
||||||
- .frontend:rules:default-frontend-jobs
|
- .frontend:rules:default-frontend-jobs
|
||||||
script:
|
script:
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- *yarn-install
|
||||||
- run_timed_command "yarn jest:integration --ci"
|
- run_timed_command "yarn jest:integration --ci"
|
||||||
needs: ["frontend-fixtures"]
|
needs: ["frontend-fixtures"]
|
||||||
|
|
||||||
|
@ -222,8 +221,7 @@ coverage-frontend:
|
||||||
needs: ["jest"]
|
needs: ["jest"]
|
||||||
stage: post-test
|
stage: post-test
|
||||||
before_script:
|
before_script:
|
||||||
- source scripts/utils.sh
|
- *yarn-install
|
||||||
- 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+)?)%/'
|
coverage: '/^Statements\s*:\s*?(\d+(?:\.\d+)?)%/'
|
||||||
|
@ -243,9 +241,8 @@ coverage-frontend:
|
||||||
stage: test
|
stage: test
|
||||||
dependencies: []
|
dependencies: []
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
- *yarn-install
|
||||||
- run_timed_command "yarn install --frozen-lockfile"
|
- run_timed_command "retry yarn run webpack-prod"
|
||||||
- run_timed_command "yarn run webpack-prod"
|
|
||||||
|
|
||||||
qa-frontend-node:10:
|
qa-frontend-node:10:
|
||||||
extends: .qa-frontend-node
|
extends: .qa-frontend-node
|
||||||
|
@ -268,8 +265,7 @@ webpack-dev-server:
|
||||||
WEBPACK_MEMORY_TEST: "true"
|
WEBPACK_MEMORY_TEST: "true"
|
||||||
WEBPACK_VENDOR_DLL: "true"
|
WEBPACK_VENDOR_DLL: "true"
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
- *yarn-install
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
|
||||||
- run_timed_command "retry yarn webpack-vendor"
|
- run_timed_command "retry yarn webpack-vendor"
|
||||||
- run_timed_command "node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js"
|
- run_timed_command "node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js"
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
|
@ -34,6 +34,13 @@
|
||||||
- tmp/rubocop_cache/
|
- tmp/rubocop_cache/
|
||||||
policy: pull
|
policy: pull
|
||||||
|
|
||||||
|
.coverage-cache:
|
||||||
|
cache:
|
||||||
|
key: "coverage-cache-v1"
|
||||||
|
paths:
|
||||||
|
- vendor/ruby/
|
||||||
|
policy: pull
|
||||||
|
|
||||||
.qa-cache:
|
.qa-cache:
|
||||||
cache:
|
cache:
|
||||||
key: "qa-v1"
|
key: "qa-v1"
|
||||||
|
@ -64,7 +71,7 @@
|
||||||
policy: pull
|
policy: pull
|
||||||
|
|
||||||
.use-pg11:
|
.use-pg11:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.28-lfs-2.9-chrome-84-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.28-lfs-2.9-chrome-85-node-12.18-yarn-1.22-postgresql-11-graphicsmagick-1.3.34"
|
||||||
services:
|
services:
|
||||||
- name: postgres:11.6
|
- name: postgres:11.6
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
|
@ -73,7 +80,7 @@
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-pg12:
|
.use-pg12:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.28-lfs-2.9-chrome-84-node-12.x-yarn-1.21-postgresql-12-graphicsmagick-1.3.34"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.28-lfs-2.9-chrome-85-node-12.18-yarn-1.22-postgresql-12-graphicsmagick-1.3.34"
|
||||||
services:
|
services:
|
||||||
- name: postgres:12
|
- name: postgres:12
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
|
@ -82,22 +89,24 @@
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
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.28-lfs-2.9-chrome-84-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.28-lfs-2.9-chrome-85-node-12.18-yarn-1.22-postgresql-11-graphicsmagick-1.3.34"
|
||||||
services:
|
services:
|
||||||
- name: postgres:11.6
|
- name: postgres:11.6
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:4.0-alpine
|
- name: redis:4.0-alpine
|
||||||
- name: elasticsearch:6.4.2
|
- name: elasticsearch:7.9.2
|
||||||
|
command: ["elasticsearch", "-E", "discovery.type=single-node"]
|
||||||
variables:
|
variables:
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-pg12-ee:
|
.use-pg12-ee:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.28-lfs-2.9-chrome-84-node-12.x-yarn-1.21-postgresql-12-graphicsmagick-1.3.34"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.28-lfs-2.9-chrome-85-node-12.18-yarn-1.22-postgresql-12-graphicsmagick-1.3.34"
|
||||||
services:
|
services:
|
||||||
- name: postgres:12
|
- name: postgres:12
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:4.0-alpine
|
- name: redis:4.0-alpine
|
||||||
- name: elasticsearch:6.4.2
|
- name: elasticsearch:7.9.2
|
||||||
|
command: ["elasticsearch", "-E", "discovery.type=single-node"]
|
||||||
variables:
|
variables:
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
stage: notify
|
stage: notify
|
||||||
dependencies: []
|
dependencies: []
|
||||||
cache: {}
|
cache: {}
|
||||||
|
variables:
|
||||||
|
MERGE_REQUEST_URL: ${CI_MERGE_REQUEST_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID}
|
||||||
before_script:
|
before_script:
|
||||||
- apk update && apk add git curl bash
|
- apk update && apk add git curl bash
|
||||||
|
|
||||||
|
@ -16,8 +18,19 @@ notify-update-gitaly:
|
||||||
variables:
|
variables:
|
||||||
NOTIFY_CHANNEL: g_create_gitaly
|
NOTIFY_CHANNEL: g_create_gitaly
|
||||||
GITALY_UPDATE_BRANCH: release-tools/update-gitaly
|
GITALY_UPDATE_BRANCH: release-tools/update-gitaly
|
||||||
MERGE_REQUEST_URL: ${CI_MERGE_REQUEST_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID}
|
|
||||||
script:
|
script:
|
||||||
- echo "NOTIFY_CHANNEL is ${NOTIFY_CHANNEL}"
|
- echo "NOTIFY_CHANNEL is ${NOTIFY_CHANNEL}"
|
||||||
- echo "CI_PIPELINE_URL is ${CI_PIPELINE_URL}"
|
- echo "CI_PIPELINE_URL is ${CI_PIPELINE_URL}"
|
||||||
- scripts/slack ${NOTIFY_CHANNEL} "☠️ \`${GITALY_UPDATE_BRANCH}\` failed! ☠️ See ${CI_PIPELINE_URL} (triggered from ${MERGE_REQUEST_URL})" ci_failing
|
- scripts/slack ${NOTIFY_CHANNEL} "☠️ \`${GITALY_UPDATE_BRANCH}\` failed! ☠️ See ${CI_PIPELINE_URL} (triggered from ${MERGE_REQUEST_URL})" ci_failing "GitLab QA Bot"
|
||||||
|
|
||||||
|
notify-security-pipeline:
|
||||||
|
extends:
|
||||||
|
- .notify-slack
|
||||||
|
- .delivery:rules:security-pipeline-merge-result-failure
|
||||||
|
variables:
|
||||||
|
NOTIFY_CHANNEL: f_upcoming_release
|
||||||
|
script:
|
||||||
|
- echo "NOTIFY_CHANNEL is ${NOTIFY_CHANNEL}"
|
||||||
|
- echo "CI_PIPELINE_URL is ${CI_PIPELINE_URL}"
|
||||||
|
# <!subteam^S0127FU8PDE> mentions the `@release-managers` group
|
||||||
|
- scripts/slack ${NOTIFY_CHANNEL} "<!subteam^S0127FU8PDE> ☠️ Pipeline for merged result failed! ☠️ See ${CI_PIPELINE_URL} (triggered from ${MERGE_REQUEST_URL})" ci_failing "GitLab Release Tools Bot"
|
||||||
|
|
|
@ -6,14 +6,23 @@
|
||||||
- .default-before_script
|
- .default-before_script
|
||||||
- .rails-cache
|
- .rails-cache
|
||||||
|
|
||||||
|
.base-script: &base-script
|
||||||
|
# Only install knapsack after bundle install! Otherwise oddly some native
|
||||||
|
# gems could not be found under some circumstance. No idea why, hours wasted.
|
||||||
|
- run_timed_command "gem install knapsack --no-document"
|
||||||
|
- run_timed_command "scripts/gitaly-test-build"
|
||||||
|
- run_timed_command "scripts/gitaly-test-spawn"
|
||||||
|
- source ./scripts/rspec_helpers.sh
|
||||||
|
|
||||||
.rspec-base:
|
.rspec-base:
|
||||||
extends: .rails-job-base
|
extends: .rails-job-base
|
||||||
stage: test
|
stage: test
|
||||||
|
variables:
|
||||||
|
RUBY_GC_MALLOC_LIMIT: 67108864
|
||||||
|
RUBY_GC_MALLOC_LIMIT_MAX: 134217728
|
||||||
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"]
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"]
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *base-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag ~level:migration"
|
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag ~level:migration"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
|
@ -25,6 +34,7 @@
|
||||||
- rspec_profiling/
|
- rspec_profiling/
|
||||||
- tmp/capybara/
|
- tmp/capybara/
|
||||||
- tmp/memory_test/
|
- tmp/memory_test/
|
||||||
|
- tmp/feature_flags/
|
||||||
- log/*.log
|
- log/*.log
|
||||||
reports:
|
reports:
|
||||||
junit: junit_rspec.xml
|
junit: junit_rspec.xml
|
||||||
|
@ -32,9 +42,7 @@
|
||||||
.rspec-base-migration:
|
.rspec-base-migration:
|
||||||
extends: .rails:rules:ee-and-foss-migration
|
extends: .rails:rules:ee-and-foss-migration
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *base-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
|
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
|
||||||
|
|
||||||
.rspec-base-pg11:
|
.rspec-base-pg11:
|
||||||
|
@ -67,9 +75,7 @@
|
||||||
.rspec-ee-base-geo:
|
.rspec-ee-base-geo:
|
||||||
extends: .rspec-base
|
extends: .rspec-base
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *base-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_paralellized_job "--tag ~quarantine --tag geo"
|
- rspec_paralellized_job "--tag ~quarantine --tag geo"
|
||||||
|
|
||||||
.rspec-ee-base-geo-pg11:
|
.rspec-ee-base-geo-pg11:
|
||||||
|
@ -160,6 +166,25 @@ update-rails-cache:
|
||||||
cache:
|
cache:
|
||||||
policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
|
policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
|
||||||
|
|
||||||
|
.coverage-base:
|
||||||
|
extends:
|
||||||
|
- .default-retry
|
||||||
|
- .default-before_script
|
||||||
|
- .coverage-cache
|
||||||
|
variables:
|
||||||
|
SETUP_DB: "false"
|
||||||
|
USE_BUNDLE_INSTALL: "false"
|
||||||
|
|
||||||
|
update-coverage-cache:
|
||||||
|
extends:
|
||||||
|
- .coverage-base
|
||||||
|
- .shared:rules:update-cache
|
||||||
|
stage: prepare
|
||||||
|
script:
|
||||||
|
- run_timed_command "bundle install --jobs=$(nproc) --path=vendor --retry=3 --quiet --without default development test production puma unicorn kerberos metrics omnibus ed25519"
|
||||||
|
cache:
|
||||||
|
policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
|
||||||
|
|
||||||
.static-analysis-base:
|
.static-analysis-base:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
|
@ -178,7 +203,7 @@ update-static-analysis-cache:
|
||||||
script:
|
script:
|
||||||
- rm -rf ./node_modules # We remove node_modules because there's no mechanism to remove stall entries.
|
- rm -rf ./node_modules # We remove node_modules because there's no mechanism to remove stall entries.
|
||||||
- run_timed_command "retry yarn install --frozen-lockfile"
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
- bundle exec rubocop --parallel # For the moment we only cache `vendor/ruby/`, `node_modules/`, and `tmp/rubocop_cache` so we don't need to run all the tasks,
|
- run_timed_command "bundle exec rubocop --parallel" # For the moment we only cache `vendor/ruby/`, `node_modules/`, and `tmp/rubocop_cache` so we don't need to run all the tasks,
|
||||||
cache:
|
cache:
|
||||||
# We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up but RuboCop has a mechanism
|
# We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up but RuboCop has a mechanism
|
||||||
# for keeping only the N latest cache files, so we take advantage of it with `pull-push` and removing `node_modules` at the start of the job.
|
# for keeping only the N latest cache files, so we take advantage of it with `pull-push` and removing `node_modules` at the start of the job.
|
||||||
|
@ -287,8 +312,7 @@ gitlab:setup:
|
||||||
# db/fixtures/development/04_project.rb thanks to SIZE=1 below
|
# db/fixtures/development/04_project.rb thanks to SIZE=1 below
|
||||||
- git clone https://gitlab.com/gitlab-org/gitlab-test.git
|
- git clone https://gitlab.com/gitlab-org/gitlab-test.git
|
||||||
/home/git/repositories/gitlab-org/gitlab-test.git
|
/home/git/repositories/gitlab-org/gitlab-test.git
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *base-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- force=yes SIZE=1 FIXTURE_PATH="db/fixtures/development" bundle exec rake gitlab:setup
|
- force=yes SIZE=1 FIXTURE_PATH="db/fixtures/development" bundle exec rake gitlab:setup
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_failure
|
when: on_failure
|
||||||
|
@ -313,7 +337,7 @@ db:backup_and_restore:
|
||||||
|
|
||||||
rspec:coverage:
|
rspec:coverage:
|
||||||
extends:
|
extends:
|
||||||
- .rails-job-base
|
- .coverage-base
|
||||||
- .rails:rules:rspec-coverage
|
- .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)
|
||||||
|
@ -333,11 +357,10 @@ rspec:coverage:
|
||||||
- rspec-ee system pg11 geo
|
- rspec-ee system pg11 geo
|
||||||
- memory-static
|
- memory-static
|
||||||
- memory-on-boot
|
- memory-on-boot
|
||||||
variables:
|
|
||||||
SETUP_DB: "false"
|
|
||||||
script:
|
script:
|
||||||
- bundle exec scripts/merge-simplecov
|
- run_timed_command "bundle install --jobs=$(nproc) --path=vendor --retry=3 --quiet --without default development test production puma unicorn kerberos metrics omnibus ed25519"
|
||||||
- bundle exec scripts/gather-test-memory-data
|
- run_timed_command "bundle exec scripts/merge-simplecov"
|
||||||
|
- run_timed_command "bundle exec scripts/gather-test-memory-data"
|
||||||
coverage: '/LOC \((\d+\.\d+%)\) covered.$/'
|
coverage: '/LOC \((\d+\.\d+%)\) covered.$/'
|
||||||
artifacts:
|
artifacts:
|
||||||
name: coverage
|
name: coverage
|
||||||
|
@ -348,6 +371,32 @@ rspec:coverage:
|
||||||
- tmp/memory_test/
|
- tmp/memory_test/
|
||||||
reports:
|
reports:
|
||||||
cobertura: coverage/coverage.xml
|
cobertura: coverage/coverage.xml
|
||||||
|
|
||||||
|
rspec:feature-flags:
|
||||||
|
extends:
|
||||||
|
- .coverage-base
|
||||||
|
- .rails:rules:rspec-feature-flags
|
||||||
|
stage: post-test
|
||||||
|
# We cannot use needs since it would mean needing 84 jobs (since most are parallelized)
|
||||||
|
# so we use `dependencies` here.
|
||||||
|
dependencies:
|
||||||
|
- setup-test-env
|
||||||
|
- rspec migration pg11
|
||||||
|
- rspec unit pg11
|
||||||
|
- rspec integration pg11
|
||||||
|
- rspec system pg11
|
||||||
|
- rspec-ee migration pg11
|
||||||
|
- rspec-ee unit pg11
|
||||||
|
- rspec-ee integration pg11
|
||||||
|
- rspec-ee system pg11
|
||||||
|
- rspec-ee unit pg11 geo
|
||||||
|
- rspec-ee integration pg11 geo
|
||||||
|
- rspec-ee system pg11 geo
|
||||||
|
- memory-static
|
||||||
|
- memory-on-boot
|
||||||
|
script:
|
||||||
|
- run_timed_command "bundle install --jobs=$(nproc) --path=vendor --retry=3 --quiet --without default development test production puma unicorn kerberos metrics omnibus ed25519"
|
||||||
|
- run_timed_command "bundle exec scripts/used-feature-flags"
|
||||||
# EE/FOSS: default refs (MRs, master, schedules) jobs #
|
# EE/FOSS: default refs (MRs, master, schedules) jobs #
|
||||||
#######################################################
|
#######################################################
|
||||||
|
|
||||||
|
@ -512,9 +561,7 @@ rspec fail-fast:
|
||||||
stage: test
|
stage: test
|
||||||
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets", "detect-tests"]
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets", "detect-tests"]
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *base-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_fail_fast tmp/matching_tests.txt "--tag ~quarantine"
|
- rspec_fail_fast tmp/matching_tests.txt "--tag ~quarantine"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 7d
|
expire_in: 7d
|
||||||
|
@ -527,9 +574,7 @@ rspec foss-impact:
|
||||||
- .rails:rules:rspec-foss-impact
|
- .rails:rules:rspec-foss-impact
|
||||||
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss", "detect-tests as-if-foss"]
|
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss", "detect-tests as-if-foss"]
|
||||||
script:
|
script:
|
||||||
- run_timed_command "scripts/gitaly-test-build"
|
- *base-script
|
||||||
- run_timed_command "scripts/gitaly-test-spawn"
|
|
||||||
- source scripts/rspec_helpers.sh
|
|
||||||
- rspec_matched_foss_tests tmp/matching_foss_tests.txt "--tag ~quarantine"
|
- rspec_matched_foss_tests tmp/matching_foss_tests.txt "--tag ~quarantine"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 7d
|
expire_in: 7d
|
||||||
|
|
|
@ -151,3 +151,20 @@ dependency_scanning:
|
||||||
reports:
|
reports:
|
||||||
dependency_scanning: gl-dependency-scanning-report.json
|
dependency_scanning: gl-dependency-scanning-report.json
|
||||||
expire_in: 1 week # GitLab-specific
|
expire_in: 1 week # GitLab-specific
|
||||||
|
|
||||||
|
license_scanning:
|
||||||
|
extends:
|
||||||
|
- .default-retry
|
||||||
|
- .reports:rules:license_scanning
|
||||||
|
stage: test
|
||||||
|
image:
|
||||||
|
name: "registry.gitlab.com/gitlab-org/security-products/analyzers/license-finder:3"
|
||||||
|
entrypoint: [""]
|
||||||
|
needs: []
|
||||||
|
script:
|
||||||
|
- /run.sh analyze .
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
license_scanning: gl-license-scanning-report.json
|
||||||
|
expire_in: 1 week # GitLab-specific
|
||||||
|
dependencies: []
|
||||||
|
|
|
@ -16,6 +16,11 @@ review-cleanup:
|
||||||
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
|
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
|
||||||
- gcp_cleanup
|
- gcp_cleanup
|
||||||
|
|
||||||
|
.base-before_script: &base-before_script
|
||||||
|
- source ./scripts/utils.sh
|
||||||
|
- source ./scripts/review_apps/review-apps.sh
|
||||||
|
- install_api_client_dependencies_with_apk
|
||||||
|
|
||||||
review-build-cng:
|
review-build-cng:
|
||||||
extends:
|
extends:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
|
@ -23,7 +28,7 @@ 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:
|
||||||
|
@ -62,9 +67,7 @@ review-deploy:
|
||||||
- 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
|
- *base-before_script
|
||||||
- install_api_client_dependencies_with_apk
|
|
||||||
- source scripts/review_apps/review-apps.sh
|
|
||||||
script:
|
script:
|
||||||
- check_kube_domain
|
- check_kube_domain
|
||||||
- ensure_namespace
|
- ensure_namespace
|
||||||
|
@ -72,7 +75,7 @@ review-deploy:
|
||||||
- download_chart
|
- download_chart
|
||||||
- date
|
- date
|
||||||
- deploy || (display_deployment_debug && exit 1)
|
- deploy || (display_deployment_debug && exit 1)
|
||||||
- disable_sign_ups
|
- disable_sign_ups || (delete_release && exit 1)
|
||||||
# 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"'
|
||||||
|
@ -81,10 +84,9 @@ review-deploy:
|
||||||
# Run seed-dast-test-data.sh only when DAST_RUN is set to true. This is to pupulate review app with data for DAST scan.
|
# Run seed-dast-test-data.sh only when DAST_RUN is set to true. This is to pupulate review app with data for DAST scan.
|
||||||
# Set DAST_RUN to true when jobs are manually scheduled.
|
# Set DAST_RUN to true when jobs are manually scheduled.
|
||||||
- if [ "$DAST_RUN" == "true" ]; then source scripts/review_apps/seed-dast-test-data.sh; TRACE=1 trigger_proj_user_creation; fi
|
- if [ "$DAST_RUN" == "true" ]; then source scripts/review_apps/seed-dast-test-data.sh; TRACE=1 trigger_proj_user_creation; fi
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths: [environment_url.txt]
|
paths: [environment_url.txt]
|
||||||
expire_in: 2 days
|
expire_in: 7 days
|
||||||
when: always
|
when: always
|
||||||
|
|
||||||
.review-stop-base:
|
.review-stop-base:
|
||||||
|
@ -98,9 +100,7 @@ review-deploy:
|
||||||
# See https://gitlab.com/gitlab-org/gitlab/issues/191273
|
# See https://gitlab.com/gitlab-org/gitlab/issues/191273
|
||||||
GIT_DEPTH: 1
|
GIT_DEPTH: 1
|
||||||
before_script:
|
before_script:
|
||||||
- apk add --update openssl
|
- *base-before_script
|
||||||
- source ./scripts/utils.sh
|
|
||||||
- source ./scripts/review_apps/review-apps.sh
|
|
||||||
|
|
||||||
review-stop-failed-deployment:
|
review-stop-failed-deployment:
|
||||||
extends:
|
extends:
|
||||||
|
@ -143,8 +143,7 @@ review-stop:
|
||||||
- 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
|
- *base-before_script
|
||||||
- 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:
|
||||||
|
@ -174,7 +173,7 @@ review-performance:
|
||||||
- .default-retry
|
- .default-retry
|
||||||
- .review:rules:review-performance
|
- .review:rules:review-performance
|
||||||
image:
|
image:
|
||||||
name: sitespeedio/sitespeed.io:6.3.1
|
name: sitespeedio/sitespeed.io
|
||||||
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.
|
||||||
|
@ -232,6 +231,6 @@ danger-review:
|
||||||
stage: test
|
stage: test
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- source scripts/utils.sh
|
- source ./scripts/utils.sh
|
||||||
- retry yarn install --frozen-lockfile
|
- run_timed_command "retry yarn install --frozen-lockfile"
|
||||||
- danger --fail-on-errors=true --verbose
|
- danger --fail-on-errors=true --verbose
|
||||||
|
|
|
@ -73,6 +73,12 @@
|
||||||
.if-rspec-fail-fast-skipped: &if-rspec-fail-fast-skipped
|
.if-rspec-fail-fast-skipped: &if-rspec-fail-fast-skipped
|
||||||
if: '$CI_MERGE_REQUEST_TITLE =~ /SKIP RSPEC FAIL-FAST/'
|
if: '$CI_MERGE_REQUEST_TITLE =~ /SKIP RSPEC FAIL-FAST/'
|
||||||
|
|
||||||
|
# For Security merge requests, the gitlab-release-tools-bot triggers a new
|
||||||
|
# pipeline for the "Pipelines for merged results" feature. If the pipeline
|
||||||
|
# fails, we notify release managers.
|
||||||
|
.if-security-pipeline-merge-result: &if-security-pipeline-merge-result
|
||||||
|
if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $CI_PROJECT_NAMESPACE == "gitlab-org/security" && $GITLAB_USER_LOGIN == "gitlab-release-tools-bot"'
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# Changes patterns #
|
# Changes patterns #
|
||||||
####################
|
####################
|
||||||
|
@ -132,7 +138,10 @@
|
||||||
|
|
||||||
.db-patterns: &db-patterns
|
.db-patterns: &db-patterns
|
||||||
- "{,ee/}{,spec/}{db,migrations}/**/*"
|
- "{,ee/}{,spec/}{db,migrations}/**/*"
|
||||||
|
- "{,ee/}{,spec/}lib/{,ee/}gitlab/database/**/*"
|
||||||
|
- "{,ee/}{,spec/}lib/{,ee/}gitlab/database{,_spec}.rb"
|
||||||
- "{,ee/}{,spec/}lib/{,ee/}gitlab/background_migration/**/*"
|
- "{,ee/}{,spec/}lib/{,ee/}gitlab/background_migration/**/*"
|
||||||
|
- "{,ee/}{,spec/}lib/{,ee/}gitlab/background_migration{,_spec}.rb"
|
||||||
- "config/prometheus/common_metrics.yml" # Used by Gitlab::DatabaseImporters::CommonMetrics::Importer
|
- "config/prometheus/common_metrics.yml" # Used by Gitlab::DatabaseImporters::CommonMetrics::Importer
|
||||||
- "{,ee/}app/models/project_statistics.rb" # Used to calculate sizes in migration specs
|
- "{,ee/}app/models/project_statistics.rb" # Used to calculate sizes in migration specs
|
||||||
|
|
||||||
|
@ -282,6 +291,14 @@
|
||||||
when: manual
|
when: manual
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
##################
|
||||||
|
# Delivery rules #
|
||||||
|
##################
|
||||||
|
.delivery:rules:security-pipeline-merge-result-failure:
|
||||||
|
rules:
|
||||||
|
- <<: *if-security-pipeline-merge-result
|
||||||
|
when: on_failure
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Dev fixtures rules #
|
# Dev fixtures rules #
|
||||||
######################
|
######################
|
||||||
|
@ -336,6 +353,7 @@
|
||||||
.frontend:rules:compile-test-assets:
|
.frontend:rules:compile-test-assets:
|
||||||
rules:
|
rules:
|
||||||
- changes: *code-backstage-qa-patterns
|
- changes: *code-backstage-qa-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
.frontend:rules:compile-test-assets-as-if-foss:
|
.frontend:rules:compile-test-assets-as-if-foss:
|
||||||
rules:
|
rules:
|
||||||
|
@ -483,6 +501,7 @@
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-default-refs
|
- <<: *if-default-refs
|
||||||
changes: *code-backstage-qa-patterns
|
changes: *code-backstage-qa-patterns
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
.rails:rules:ee-only-migration:
|
.rails:rules:ee-only-migration:
|
||||||
rules:
|
rules:
|
||||||
|
@ -628,6 +647,13 @@
|
||||||
- <<: *if-master-schedule-2-hourly
|
- <<: *if-master-schedule-2-hourly
|
||||||
- <<: *if-merge-request-title-run-all-rspec
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
|
.rails:rules:rspec-feature-flags:
|
||||||
|
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:
|
.rails:rules:master-schedule-nightly--code-backstage:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-master-schedule-nightly
|
- <<: *if-master-schedule-nightly
|
||||||
|
@ -702,6 +728,14 @@
|
||||||
- <<: *if-master-schedule-nightly
|
- <<: *if-master-schedule-nightly
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
.reports:rules:license_scanning:
|
||||||
|
rules:
|
||||||
|
- if: '$LICENSE_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\blicense_scanning\b/'
|
||||||
|
when: never
|
||||||
|
- <<: *if-default-refs
|
||||||
|
changes: *code-backstage-qa-patterns
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
################
|
################
|
||||||
# Review rules #
|
# Review rules #
|
||||||
################
|
################
|
||||||
|
@ -859,6 +893,7 @@
|
||||||
- <<: *if-default-refs
|
- <<: *if-default-refs
|
||||||
changes: *code-backstage-patterns
|
changes: *code-backstage-patterns
|
||||||
when: on_success
|
when: on_success
|
||||||
|
- <<: *if-merge-request-title-run-all-rspec
|
||||||
|
|
||||||
.test-metadata:rules:update-tests-metadata:
|
.test-metadata:rules:update-tests-metadata:
|
||||||
rules:
|
rules:
|
||||||
|
|
|
@ -38,6 +38,6 @@ update-tests-metadata:
|
||||||
- rspec-ee integration pg11 geo
|
- rspec-ee integration pg11 geo
|
||||||
- rspec-ee system pg11 geo
|
- rspec-ee system pg11 geo
|
||||||
script:
|
script:
|
||||||
- retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document
|
- run_timed_command "retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document"
|
||||||
- source scripts/rspec_helpers.sh
|
- source ./scripts/rspec_helpers.sh
|
||||||
- update_tests_metadata
|
- update_tests_metadata
|
||||||
|
|
|
@ -30,14 +30,14 @@ If applicable, any groups/projects that are happy to have this feature turned on
|
||||||
|
|
||||||
## Roll Out Steps
|
## Roll Out Steps
|
||||||
|
|
||||||
- [ ] Enable on staging
|
- [ ] Enable on staging (`/chatops run feature set feature_name true --staging`)
|
||||||
- [ ] Test on staging
|
- [ ] Test on staging
|
||||||
- [ ] Ensure that documentation has been updated
|
- [ ] Ensure that documentation has been updated
|
||||||
- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour
|
- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour (`/chatops run feature set --project=gitlab-org/gitlab feature_name true`)
|
||||||
- [ ] Coordinate a time to enable the flag with `#production` and `#g_delivery` on slack.
|
- [ ] Coordinate a time to enable the flag with `#production` and `#g_delivery` on slack.
|
||||||
- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
|
- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
|
||||||
- [ ] Enable on GitLab.com by running chatops command in `#production`
|
- [ ] Enable on GitLab.com by running chatops command in `#production` (`/chatops run feature set feature_name true`)
|
||||||
- [ ] Cross post chatops slack command to `#support_gitlab-com` ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#where-to-run-commands)) and in your team channel
|
- [ ] Cross post chatops Slack command to `#support_gitlab-com` ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#where-to-run-commands)) and in your team channel
|
||||||
- [ ] Announce on the issue that the flag has been enabled
|
- [ ] Announce on the issue that the flag has been enabled
|
||||||
- [ ] Remove feature flag and add changelog entry
|
- [ ] Remove feature flag and add changelog entry
|
||||||
- [ ] After the flag removal is deployed, [clean up the feature flag](https://docs.gitlab.com/ee/development/feature_flags/controls.html#cleaning-up) by running chatops command in `#production` channel
|
- [ ] After the flag removal is deployed, [clean up the feature flag](https://docs.gitlab.com/ee/development/feature_flags/controls.html#cleaning-up) by running chatops command in `#production` channel
|
||||||
|
|
|
@ -78,7 +78,11 @@ See the test engineering planning process and reach out to your counterpart Soft
|
||||||
|
|
||||||
### What does success look like, and how can we measure that?
|
### What does success look like, and how can we measure that?
|
||||||
|
|
||||||
<!-- Define both the success metrics and acceptance criteria. Note that success metrics indicate the desired business outcomes, while acceptance criteria indicate when the solution is working correctly. If there is no way to measure success, link to an issue that will implement a way to measure this. -->
|
<!--
|
||||||
|
Define both the success metrics and acceptance criteria. Note that success metrics indicate the desired business outcomes, while acceptance criteria indicate when the solution is working correctly. If there is no way to measure success, link to an issue that will implement a way to measure this.
|
||||||
|
|
||||||
|
Create tracking issue using the the Snowplow event tracking template. See https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Snowplow%20event%20tracking.md
|
||||||
|
-->
|
||||||
|
|
||||||
### What is the type of buyer?
|
### What is the type of buyer?
|
||||||
|
|
||||||
|
|
62
.gitlab/issue_templates/Implementation.md
Normal file
62
.gitlab/issue_templates/Implementation.md
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<!--
|
||||||
|
Implementation issues are used break-up a large piece of work into small, discrete tasks that can
|
||||||
|
move independently through the build workflow steps. They're typically used to populate a Feature
|
||||||
|
Epic. Once created, an implementation issue is usually refined in order to populate and review the
|
||||||
|
implementation plan and weight.
|
||||||
|
Example workflow: https://about.gitlab.com/handbook/engineering/development/threat-management/planning/diagram.html#plan
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Why are we doing this work
|
||||||
|
<!--
|
||||||
|
A brief explanation of the why, not the what or how. Assume the reader doesn't know the
|
||||||
|
background and won't have time to dig-up information from comment threads.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Relevant links
|
||||||
|
<!--
|
||||||
|
Information that the developer might need to refer to when implementing the issue.
|
||||||
|
|
||||||
|
- [Design Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>)
|
||||||
|
- [Design 1](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>/designs/<image>.png)
|
||||||
|
- [Design 2](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>/designs/<image>.png)
|
||||||
|
- [Similar implementation](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/<id>)
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Non-functional requirements
|
||||||
|
<!--
|
||||||
|
Add details for required items and delete others.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] Documentation:
|
||||||
|
- [ ] Feature flag:
|
||||||
|
- [ ] Performance:
|
||||||
|
- [ ] Testing:
|
||||||
|
|
||||||
|
|
||||||
|
## Implementation plan
|
||||||
|
<!--
|
||||||
|
Steps and the parts of the code that will need to get updated. The plan can also
|
||||||
|
call-out responsibilities for other team members or teams.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] ~frontend Step 1
|
||||||
|
- [ ] @person Step 1a
|
||||||
|
- [ ] ~frontend Step 2
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Workflow and other relevant labels
|
||||||
|
|
||||||
|
~"group::" ~"Category:" ~"GitLab Ultimate"
|
||||||
|
-->
|
||||||
|
/label ~"workflow::refinement"
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Other settings you might want to include when creating the issue.
|
||||||
|
|
||||||
|
/milestone %"Next 1-3 releases"
|
||||||
|
/assign @
|
||||||
|
/epic &
|
||||||
|
-->
|
|
@ -16,7 +16,7 @@ Please add information here about why you're planning on migrating. Include any
|
||||||
<!-- Please complete as many items in this list as possible. If you're not sure yet, add "TBD" (To be Decided) or "Unknown" -->
|
<!-- Please complete as many items in this list as possible. If you're not sure yet, add "TBD" (To be Decided) or "Unknown" -->
|
||||||
|
|
||||||
* **Timeline.** -
|
* **Timeline.** -
|
||||||
* **Product.** - GitLab Gold/Ultimate or Commnunity Edition
|
* **Product.** - GitLab Gold/Ultimate or Community Edition
|
||||||
* **Project's License.** What kind of OSI-approved license does your project use?
|
* **Project's License.** What kind of OSI-approved license does your project use?
|
||||||
|
|
||||||
## Current Tooling and Replacements
|
## Current Tooling and Replacements
|
||||||
|
|
|
@ -31,7 +31,7 @@ Your Security Implementation Issue should have `4` merge requests associated:
|
||||||
|
|
||||||
## Blog post
|
## Blog post
|
||||||
|
|
||||||
Dev: {https://dev.gitlab.org/gitlab/www-gitlab-com/merge_requests/ link}<br/>
|
Security: {https://gitlab.com/gitlab-org/security/www-gitlab-com/merge_requests/ link}<br/>
|
||||||
GitLab.com: {https://gitlab.com/gitlab-com/www-gitlab-com/merge_requests/ link}
|
GitLab.com: {https://gitlab.com/gitlab-com/www-gitlab-com/merge_requests/ link}
|
||||||
|
|
||||||
## Email notification
|
## Email notification
|
||||||
|
|
42
.gitlab/issue_templates/Snowplow event tracking.md
Normal file
42
.gitlab/issue_templates/Snowplow event tracking.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<!--
|
||||||
|
* Use this issue template for creating requests to track snowplow events
|
||||||
|
* Snowplow events can be both Frontend (javascript) or Backend (Ruby)
|
||||||
|
* Snowplow is currently not used for self-hosted instances of GitLab - Self-hosted still rely on usage ping for product analytics - Snowplow is used for GitLab SaaS
|
||||||
|
* You do not need to create an issue to track generic front-end events, such as All page views, sessions, link clicks, some button clicks, etc.
|
||||||
|
* What you should capture are specific events with defined business logic. For example, when a user creates an incident by escalating an existing alert, or when a user creates and pushes up a new Node package to the NPM registry.
|
||||||
|
* For more details read https://about.gitlab.com/handbook/business-ops/data-team/programs/data-for-product-managers/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
We generally recommend events be tracked using a [structured event](https://docs.snowplowanalytics.com/docs/understanding-tracking-design/out-of-the-box-vs-custom-events-and-entities/#structured-events) which has 5 properties you can use. There may be instances where structured events are not sufficient. You may want to track an event where the property changes frequently or is general something very unique. In those cases, use a [self-describing event](https://docs.snowplowanalytics.com/docs/understanding-tracking-design/out-of-the-box-vs-custom-events-and-entities/#self-describing-events)
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Structured Snowplow events to track
|
||||||
|
|
||||||
|
* Category: The page or backend area of the application. Unless infeasible, please use the Rails page attribute by default in the frontend, and namespace + classname on the backend. If you're not sure what it is, work with your engineering manager to figure it out.
|
||||||
|
* Action: A string that is used to define the user action. The first word should always describe the action or aspect: clicks should be `click`, activations should be `activate`, creations should be `create`, etc. Use underscores to describe what was acted on; for example, activating a form field would be `activate_form_input`. An interface action like clicking on a dropdown would be `click_dropdown`, while a behavior like creating a project record from the backend would be `create_project`
|
||||||
|
* Label: Optional. The specific element, or object that's being acted on. This is either the label of the element (e.g. a tab labeled 'Create from template' may be `create_from_template`) or a unique identifier if no text is available (e.g. closing the Groups dropdown in the top navbar might be `groups_dropdown_close`), or it could be the name or title attribute of a record being created.
|
||||||
|
* Property: Optional. Any additional property of the element, or object being acted on.
|
||||||
|
* Value: Optional, numeric. Describes a numeric value or something directly related to the event. This could be the value of an input (e.g. `10` when clicking `internal` visibility)
|
||||||
|
|
||||||
|
| Category | Action | Label | Property | Feature Issue | Additional Information |
|
||||||
|
| ------ | ------ | ------ | ------ | ------ | ------ |
|
||||||
|
| cell | cell | cell | cell | cell | cell |
|
||||||
|
| cell | cell | cell | cell | cell | cell |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Snowplow event tracking starts with instrumentation and completed after a chart is created in Sisense.
|
||||||
|
|
||||||
|
Use this checklist to ensure all steps are completed
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Snowplow event tracking checklist
|
||||||
|
* [ ] Engineering complete work and deploy changes to GitLab SaaS
|
||||||
|
* [ ] Verify the new Snowplow events are listed in the [Snowplow Event Exploration](https://app.periscopedata.com/app/gitlab/539181/Snowplow-Event-Exploration---last-30-days) dashboard
|
||||||
|
* [ ] Create chart(s) to track your event(s) in the relevant dashboard
|
||||||
|
* [ ] Use the [Chart Snowplow Actions](https://app.periscopedata.com/app/gitlab/snippet/Chart-Snowplow-Actions/5546da87ae2c4a3fbc98415c88b3eedd/edit) SQL snippet to quickly visualize usage. See [example](https://app.periscopedata.com/app/gitlab/737489/Health-Group-Dashboard?widget=9797112&udv=0)
|
||||||
|
|
||||||
|
<!-- Label reminders - you should have one of each of the following labels if you can figure out the correct ones -->
|
||||||
|
/label ~devops:: ~group: ~Category:
|
||||||
|
/label ~"snowplow tracking events"
|
|
@ -1,5 +1,5 @@
|
||||||
## Actionable Insights
|
## Actionable Insights
|
||||||
Actionable insights always have a follow-up action that needs to take place as a result of the research observation or data, and a clear recommendation or action associated with it. An actionable insight both defines the insight and clearly calls out the next step. These insights are tracked over time.
|
Actionable insights always have a follow-up action that needs to take place as a result of the research observation or data, and a clear recommendation or action associated with it. An actionable insight both defines the insight and clearly calls out the next step. These insights are tracked over time and at the group level.
|
||||||
|
|
||||||
#### Link
|
#### Link
|
||||||
|
|
||||||
|
@ -10,6 +10,10 @@ Actionable insights always have a follow-up action that needs to take place as a
|
||||||
|
|
||||||
- [ ] Assign this issue to the appropriate Product Manager, Product Designer, or UX Researcher
|
- [ ] Assign this issue to the appropriate Product Manager, Product Designer, or UX Researcher
|
||||||
|
|
||||||
|
#### Group label
|
||||||
|
|
||||||
|
- [ ] Add the appropriate `Group` (such as `~"group::source code"`) label to the issue. This is done to identify and track actionable insights at the group level.
|
||||||
|
|
||||||
#### Description
|
#### Description
|
||||||
|
|
||||||
- [ ] Provide some brief details on the actionable insight and the action to take
|
- [ ] Provide some brief details on the actionable insight and the action to take
|
||||||
|
|
|
@ -15,18 +15,16 @@ Closes
|
||||||
## Moving docs to a new location?
|
## Moving docs to a new location?
|
||||||
|
|
||||||
Read the guidelines:
|
Read the guidelines:
|
||||||
https://docs.gitlab.com/ee/development/documentation/index.html#changing-document-location
|
https://docs.gitlab.com/ee/development/documentation/index.html#move-or-rename-a-page
|
||||||
|
|
||||||
- [ ] Make sure the old link is not removed and has its contents replaced with
|
- [ ] Make sure the old link is not removed and has its contents replaced with
|
||||||
a link to the new location.
|
a link to the new location.
|
||||||
- [ ] Make sure internal links pointing to the document in question are not broken.
|
- [ ] Make sure internal links pointing to the document in question are not broken.
|
||||||
- [ ] Search and replace any links referring to old docs in GitLab Rails app,
|
- [ ] Search and replace any links referring to old docs in GitLab Rails app,
|
||||||
specifically under the `app/views/` and `ee/app/views` (for GitLab EE) directories.
|
specifically under the `app/views/` and `ee/app/views` (for GitLab EE) directories.
|
||||||
- [ ] Make sure to add [`redirect_from`](https://docs.gitlab.com/ce/development/documentation/index.html#redirections-for-pages-with-disqus-comments)
|
- [ ] Make sure to add [`redirect_from`](https://docs.gitlab.com/ee/development/documentation/index.html#redirections-for-pages-with-disqus-comments)
|
||||||
to the new document if there are any Disqus comments on the old document thread.
|
to the new document if there are any Disqus comments on the old document thread.
|
||||||
- [ ] Update the link in `features.yml` (if applicable)
|
- [ ] Update the link in `features.yml` (if applicable)
|
||||||
- [ ] If working on CE and the `ee-compat-check` jobs fails, submit an MR to EE
|
- [ ] Assign one of the technical writers for review.
|
||||||
with the changes as well (https://docs.gitlab.com/ce/development/documentation/index.html#cherry-picking-from-ce-to-ee).
|
|
||||||
- [ ] Ping one of the technical writers for review.
|
|
||||||
|
|
||||||
/label ~documentation
|
/label ~documentation
|
||||||
|
|
|
@ -48,10 +48,13 @@ All reviewers can help ensure accuracy, clarity, completeness, and adherence to
|
||||||
- [ ] 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).
|
- [ ] 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).
|
||||||
- [ ] Ensure docs metadata are present and up-to-date.
|
- [ ] Ensure docs metadata are present and up-to-date.
|
||||||
- [ ] Ensure ~"Technical Writing" and ~"documentation" are added.
|
- [ ] Ensure ~"Technical Writing" and ~"documentation" are added.
|
||||||
- [ ] Add the corresponding `docs::` scoped label.
|
- [ ] Add the corresponding `docs::` [scoped label](https://gitlab.com/groups/gitlab-org/-/labels?utf8=%E2%9C%93&subscribed=&search=docs%3A%3A).
|
||||||
|
- [ ] If working on UI text, add the corresponding `UI Text` [scoped label](https://gitlab.com/groups/gitlab-org/-/labels?utf8=%E2%9C%93&subscribed=&search=ui+text).
|
||||||
- [ ] Add ~"tw::doing" when starting work on the MR.
|
- [ ] 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.
|
- [ ] Add ~"tw::finished" if Technical Writing team work on the MR is complete but it remains open.
|
||||||
|
|
||||||
|
For more information about labels, see [Technical Writing workflows - Labels](https://about.gitlab.com/handbook/engineering/ux/technical-writing/workflow/#labels).
|
||||||
|
|
||||||
**3. Maintainer**
|
**3. Maintainer**
|
||||||
|
|
||||||
1. [ ] Review by assigned maintainer, who can always request/require the above reviews. Maintainer's review can occur before or after a technical writer review.
|
1. [ ] Review by assigned maintainer, who can always request/require the above reviews. Maintainer's review can occur before or after a technical writer review.
|
||||||
|
|
|
@ -22,6 +22,6 @@ Please describe the proposal and add a link to the source (for example, http://w
|
||||||
- [ ] In the relevant Slack channels (e.g. `#development`, `#backend`, `#frontend`)
|
- [ ] In the relevant Slack channels (e.g. `#development`, `#backend`, `#frontend`)
|
||||||
- [ ] (Optional depending on the impact of the change) In the Engineering Week in Review
|
- [ ] (Optional depending on the impact of the change) In the Engineering Week in Review
|
||||||
|
|
||||||
/label ~"Engineering Productivity" ~"Style decision" ~"development guidelines" ~"static analysis"
|
/label ~"Engineering Productivity" ~"development guidelines" ~"static code analysis"
|
||||||
|
|
||||||
/cc @gitlab-org/maintainers/rails-backend
|
/cc @gitlab-org/maintainers/rails-backend
|
||||||
|
|
|
@ -21,7 +21,7 @@ See [the general developer security release guidelines](https://gitlab.com/gitla
|
||||||
- [ ] Assign to a reviewer and maintainer, per our [Code Review process].
|
- [ ] 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].
|
||||||
- [ ] Ensure it's approved by an AppSec engineer.
|
- [ ] 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.
|
- Please see the security release [Code reviews and Approvals](https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#code-reviews-and-approvals) documentation for details on which AppSec team member to ping for approval.
|
||||||
- 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.
|
- 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.
|
||||||
- [ ] For a backport MR targeting a versioned stable branch (`X-Y-stable-ee`)
|
- [ ] For a backport MR targeting a versioned stable branch (`X-Y-stable-ee`)
|
||||||
- [ ] Ensure it's approved by a maintainer.
|
- [ ] Ensure it's approved by a maintainer.
|
||||||
|
|
89
.gitpod.yml
Normal file
89
.gitpod.yml
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
image: registry.gitlab.com/gitlab-org/gitlab-development-kit/gitpod-workspace:gitpod-workspace-image
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- name: GDK
|
||||||
|
command: gp sync-await gdk-copied && cd /workspace/gitlab-development-kit && gdk help
|
||||||
|
|
||||||
|
- init: |
|
||||||
|
echo "$(date) – Copying GDK" | tee -a /workspace/startup.log
|
||||||
|
mv $HOME/.rvm-workspace /workspace/.rvm
|
||||||
|
cp -r $HOME/gitlab-development-kit /workspace/
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
cd /workspace/gitlab-development-kit
|
||||||
|
[[ ! -L /workspace/gitlab-development-kit/gitlab ]] && ln -fs /workspace/gitlab /workspace/gitlab-development-kit/gitlab
|
||||||
|
# make webpack static, prevents that GitLab tries to connect to localhost webpack from browser outside the workspace
|
||||||
|
echo "webpack:" >> gdk.yml
|
||||||
|
echo " static: true" >> gdk.yml
|
||||||
|
# reconfigure GDK
|
||||||
|
echo "$(date) – Reconfiguring GDK" | tee -a /workspace/startup.log
|
||||||
|
gdk reconfigure
|
||||||
|
# run DB migrations
|
||||||
|
echo "$(date) – Running DB migrations" | tee -a /workspace/startup.log
|
||||||
|
make gitlab-db-migrate
|
||||||
|
cd -
|
||||||
|
# stop GDK
|
||||||
|
echo "$(date) – Stopping GDK" | tee -a /workspace/startup.log
|
||||||
|
gdk stop
|
||||||
|
echo "$(date) – GDK stopped" | tee -a /workspace/startup.log
|
||||||
|
)
|
||||||
|
command: |
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
gp sync-done gdk-copied
|
||||||
|
SECONDS=0
|
||||||
|
cd /workspace/gitlab-development-kit
|
||||||
|
# update GDK
|
||||||
|
if [ "$GITLAB_UPDATE_GDK" == true ]; then
|
||||||
|
echo "$(date) – Updating GDK" | tee -a /workspace/startup.log
|
||||||
|
gdk update
|
||||||
|
fi
|
||||||
|
# start GDK
|
||||||
|
echo "$(date) – Starting GDK" | tee -a /workspace/startup.log
|
||||||
|
export RAILS_HOSTS=$(gp url 3000 | sed -e 's+^http[s]*://++')
|
||||||
|
gdk start
|
||||||
|
# Run DB migrations
|
||||||
|
if [ "$GITLAB_RUN_DB_MIGRATIONS" == true ]; then
|
||||||
|
make gitlab-db-migrate
|
||||||
|
fi
|
||||||
|
# Fix DB key
|
||||||
|
if [ "$GITLAB_FIX_DB_KEY" = true ]; then
|
||||||
|
echo "$(date) – Fixing DB key" | tee -a /workspace/startup.log
|
||||||
|
cd gitlab
|
||||||
|
# see https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56403#note_132515069
|
||||||
|
printf 'ApplicationSetting.last.update_column(:runners_registration_token_encrypted, nil)\nexit\n' | bundle exec rails c
|
||||||
|
cd -
|
||||||
|
fi
|
||||||
|
# Waiting for GitLab ...
|
||||||
|
gp await-port 3000
|
||||||
|
printf "Waiting for GitLab at $(gp url 3000) ..."
|
||||||
|
until $(curl -sNL $(gp url 3000) | grep -q "GitLab"); do printf '.'; sleep 5; done && echo ""
|
||||||
|
# Give Gitpod a few more seconds to set up everything ...
|
||||||
|
sleep 5
|
||||||
|
printf "$(date) – GitLab is up (took ~%.1f minutes)\n" "$((10*$SECONDS/60))e-1" | tee -a /workspace/startup.log
|
||||||
|
gp preview $(gp url 3000) || true
|
||||||
|
)
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- port: 3000 # rails-web
|
||||||
|
onOpen: ignore
|
||||||
|
- port: 3010 # gitlab-pages
|
||||||
|
onOpen: ignore
|
||||||
|
- port: 3808 # webpack
|
||||||
|
onOpen: ignore
|
||||||
|
- port: 5000 # auto_devops
|
||||||
|
onOpen: ignore
|
||||||
|
- port: 5778 # jaeger
|
||||||
|
onOpen: ignore
|
||||||
|
- port: 9000 # object_store / minio
|
||||||
|
onOpen: ignore
|
||||||
|
|
||||||
|
vscode:
|
||||||
|
extensions:
|
||||||
|
- rebornix.ruby@0.27.0:QyGBeRyslOfdRgOPRGm6PQ==
|
||||||
|
- wingrunr21.vscode-ruby@0.27.0:beIqQUhLRuJ5Vao4B2Lyng==
|
||||||
|
- karunamurti.haml@1.1.0:twCwOYt3/Ttfb3+iwblPDA==
|
||||||
|
- octref.vetur@0.25.0:UofirBhedyhdx/jCnPeJDg==
|
||||||
|
- dbaeumer.vscode-eslint@2.1.3:1NRvj3UKNTNwmYjptmUmIw==
|
||||||
|
- GitLab.gitlab-workflow@3.3.0:50q1byIi4M01G9qrTCCAYQ==
|
|
@ -7,377 +7,374 @@
|
||||||
# versions of Haml-Lint, may require this file to be generated again.
|
# versions of Haml-Lint, may require this file to be generated again.
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
|
|
||||||
# Offense count: 1552
|
# Offense count: 1552
|
||||||
NoPlainNodes:
|
NoPlainNodes:
|
||||||
enabled: true
|
enabled: true
|
||||||
exclude:
|
exclude:
|
||||||
- "app/views/admin/abuse_reports/_abuse_report.html.haml"
|
- 'app/views/admin/abuse_reports/_abuse_report.html.haml'
|
||||||
- "app/views/admin/abuse_reports/index.html.haml"
|
- 'app/views/admin/abuse_reports/index.html.haml'
|
||||||
- "app/views/admin/appearances/_form.html.haml"
|
- 'app/views/admin/appearances/_form.html.haml'
|
||||||
- "app/views/admin/application_settings/_abuse.html.haml"
|
- 'app/views/admin/application_settings/_abuse.html.haml'
|
||||||
- "app/views/admin/application_settings/_diff_limits.html.haml"
|
- 'app/views/admin/application_settings/_diff_limits.html.haml'
|
||||||
- "app/views/admin/application_settings/_gitaly.html.haml"
|
- 'app/views/admin/application_settings/_gitaly.html.haml'
|
||||||
- "app/views/admin/application_settings/_ip_limits.html.haml"
|
- 'app/views/admin/application_settings/_ip_limits.html.haml'
|
||||||
- "app/views/admin/application_settings/_performance.html.haml"
|
- 'app/views/admin/application_settings/_performance.html.haml'
|
||||||
- "app/views/admin/application_settings/_plantuml.html.haml"
|
- 'app/views/admin/application_settings/_plantuml.html.haml'
|
||||||
- "app/views/admin/application_settings/_prometheus.html.haml"
|
- 'app/views/admin/application_settings/_prometheus.html.haml'
|
||||||
- "app/views/admin/application_settings/_realtime.html.haml"
|
- 'app/views/admin/application_settings/_realtime.html.haml'
|
||||||
- "app/views/admin/application_settings/_repository_check.html.haml"
|
- 'app/views/admin/application_settings/_repository_check.html.haml'
|
||||||
- "app/views/admin/application_settings/_signin.html.haml"
|
- 'app/views/admin/application_settings/_signin.html.haml'
|
||||||
- "app/views/admin/application_settings/_signup.html.haml"
|
- 'app/views/admin/application_settings/_signup.html.haml'
|
||||||
- "app/views/admin/application_settings/_spam.html.haml"
|
- 'app/views/admin/application_settings/_spam.html.haml'
|
||||||
- "app/views/admin/application_settings/_terminal.html.haml"
|
- 'app/views/admin/application_settings/_terminal.html.haml'
|
||||||
- "app/views/admin/application_settings/_usage.html.haml"
|
- 'app/views/admin/application_settings/_usage.html.haml'
|
||||||
- "app/views/admin/application_settings/_visibility_and_access.html.haml"
|
- 'app/views/admin/application_settings/_visibility_and_access.html.haml'
|
||||||
- "app/views/admin/applications/_delete_form.html.haml"
|
- 'app/views/admin/applications/_delete_form.html.haml'
|
||||||
- "app/views/admin/applications/_form.html.haml"
|
- 'app/views/admin/applications/_form.html.haml'
|
||||||
- "app/views/admin/applications/edit.html.haml"
|
- 'app/views/admin/applications/edit.html.haml'
|
||||||
- "app/views/admin/applications/index.html.haml"
|
- 'app/views/admin/applications/index.html.haml'
|
||||||
- "app/views/admin/applications/new.html.haml"
|
- 'app/views/admin/applications/new.html.haml'
|
||||||
- "app/views/admin/applications/show.html.haml"
|
- 'app/views/admin/applications/show.html.haml'
|
||||||
- "app/views/admin/background_jobs/show.html.haml"
|
- 'app/views/admin/background_jobs/show.html.haml'
|
||||||
- "app/views/admin/broadcast_messages/index.html.haml"
|
- 'app/views/admin/broadcast_messages/index.html.haml'
|
||||||
- "app/views/admin/dashboard/index.html.haml"
|
- 'app/views/admin/dashboard/index.html.haml'
|
||||||
- "app/views/admin/deploy_keys/new.html.haml"
|
- 'app/views/admin/deploy_keys/new.html.haml'
|
||||||
- "app/views/admin/health_check/show.html.haml"
|
- 'app/views/admin/health_check/show.html.haml'
|
||||||
- "app/views/admin/hook_logs/_index.html.haml"
|
- 'app/views/admin/hook_logs/_index.html.haml'
|
||||||
- "app/views/admin/hook_logs/show.html.haml"
|
- 'app/views/admin/hook_logs/show.html.haml'
|
||||||
- "app/views/admin/hooks/_form.html.haml"
|
- 'app/views/admin/hooks/_form.html.haml'
|
||||||
- "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/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'
|
||||||
- "app/views/admin/runners/show.html.haml"
|
- 'app/views/admin/runners/show.html.haml'
|
||||||
- "app/views/admin/services/_form.html.haml"
|
- 'app/views/admin/services/_form.html.haml'
|
||||||
- "app/views/admin/services/index.html.haml"
|
- 'app/views/admin/services/index.html.haml'
|
||||||
- "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/_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'
|
||||||
- "app/views/admin/users/_projects.html.haml"
|
- 'app/views/admin/users/_projects.html.haml'
|
||||||
- "app/views/admin/users/new.html.haml"
|
- 'app/views/admin/users/new.html.haml'
|
||||||
- "app/views/admin/users/projects.html.haml"
|
- 'app/views/admin/users/projects.html.haml'
|
||||||
- "app/views/admin/users/show.html.haml"
|
- 'app/views/admin/users/show.html.haml'
|
||||||
- 'app/views/authentication/_authenticate.html.haml'
|
- 'app/views/authentication/_authenticate.html.haml'
|
||||||
- 'app/views/authentication/_register.html.haml'
|
- 'app/views/authentication/_register.html.haml'
|
||||||
- "app/views/clusters/clusters/_cluster.html.haml"
|
- 'app/views/clusters/clusters/_cluster.html.haml'
|
||||||
- "app/views/clusters/clusters/new.html.haml"
|
- 'app/views/clusters/clusters/new.html.haml'
|
||||||
- "app/views/dashboard/milestones/index.html.haml"
|
- 'app/views/dashboard/milestones/index.html.haml'
|
||||||
- "app/views/dashboard/projects/_blank_state_admin_welcome.html.haml"
|
- 'app/views/dashboard/projects/_blank_state_admin_welcome.html.haml'
|
||||||
- "app/views/dashboard/projects/_blank_state_welcome.html.haml"
|
- 'app/views/dashboard/projects/_blank_state_welcome.html.haml'
|
||||||
- "app/views/dashboard/todos/_todo.html.haml"
|
- 'app/views/dashboard/todos/_todo.html.haml'
|
||||||
- "app/views/dashboard/todos/index.html.haml"
|
- 'app/views/dashboard/todos/index.html.haml'
|
||||||
- "app/views/devise/confirmations/almost_there.haml"
|
- 'app/views/devise/confirmations/almost_there.haml'
|
||||||
- "app/views/devise/mailer/_confirmation_instructions_account.html.haml"
|
- 'app/views/devise/mailer/_confirmation_instructions_account.html.haml'
|
||||||
- "app/views/devise/mailer/_confirmation_instructions_secondary.html.haml"
|
- 'app/views/devise/mailer/_confirmation_instructions_secondary.html.haml'
|
||||||
- "app/views/devise/mailer/email_changed.html.haml"
|
- 'app/views/devise/mailer/email_changed.html.haml'
|
||||||
- "app/views/devise/mailer/password_change.html.haml"
|
- 'app/views/devise/mailer/password_change.html.haml'
|
||||||
- "app/views/devise/mailer/reset_password_instructions.html.haml"
|
- 'app/views/devise/mailer/reset_password_instructions.html.haml'
|
||||||
- "app/views/devise/mailer/unlock_instructions.html.haml"
|
- 'app/views/devise/mailer/unlock_instructions.html.haml'
|
||||||
- "app/views/devise/passwords/edit.html.haml"
|
- 'app/views/devise/passwords/edit.html.haml'
|
||||||
- "app/views/devise/sessions/_new_base.html.haml"
|
- 'app/views/devise/sessions/_new_base.html.haml'
|
||||||
- "app/views/devise/sessions/_new_crowd.html.haml"
|
- 'app/views/devise/sessions/_new_crowd.html.haml'
|
||||||
- "app/views/devise/sessions/_new_ldap.html.haml"
|
- 'app/views/devise/sessions/_new_ldap.html.haml'
|
||||||
- "app/views/devise/sessions/new.html.haml"
|
- 'app/views/devise/sessions/new.html.haml'
|
||||||
- "app/views/devise/sessions/two_factor.html.haml"
|
- 'app/views/devise/sessions/two_factor.html.haml'
|
||||||
- "app/views/devise/shared/_omniauth_box.html.haml"
|
- 'app/views/devise/shared/_omniauth_box.html.haml'
|
||||||
- "app/views/devise/shared/_sign_in_link.html.haml"
|
- 'app/views/devise/shared/_sign_in_link.html.haml'
|
||||||
- "app/views/devise/shared/_tabs_normal.html.haml"
|
- 'app/views/devise/shared/_tabs_normal.html.haml'
|
||||||
- "app/views/discussions/_discussion.html.haml"
|
- 'app/views/discussions/_discussion.html.haml'
|
||||||
- "app/views/discussions/_headline.html.haml"
|
- 'app/views/discussions/_headline.html.haml'
|
||||||
- "app/views/discussions/_notes.html.haml"
|
- 'app/views/discussions/_notes.html.haml'
|
||||||
- "app/views/doorkeeper/applications/_delete_form.html.haml"
|
- 'app/views/doorkeeper/applications/_delete_form.html.haml'
|
||||||
- "app/views/doorkeeper/authorized_applications/_delete_form.html.haml"
|
- 'app/views/doorkeeper/authorized_applications/_delete_form.html.haml'
|
||||||
- "app/views/errors/encoding.html.haml"
|
- 'app/views/errors/encoding.html.haml'
|
||||||
- "app/views/errors/git_not_found.html.haml"
|
- 'app/views/errors/git_not_found.html.haml'
|
||||||
- "app/views/errors/omniauth_error.html.haml"
|
- 'app/views/errors/omniauth_error.html.haml'
|
||||||
- "app/views/errors/precondition_failed.html.haml"
|
- 'app/views/errors/precondition_failed.html.haml'
|
||||||
- "app/views/events/_event_push.atom.haml"
|
- 'app/views/events/_event_push.atom.haml'
|
||||||
- "app/views/events/event/_push.html.haml"
|
- 'app/views/events/event/_push.html.haml'
|
||||||
- "app/views/groups/_create_chat_team.html.haml"
|
- 'app/views/groups/_create_chat_team.html.haml'
|
||||||
- "app/views/groups/_group_admin_settings.html.haml"
|
- 'app/views/groups/_group_admin_settings.html.haml'
|
||||||
- "app/views/groups/labels/edit.html.haml"
|
- 'app/views/groups/labels/edit.html.haml'
|
||||||
- "app/views/groups/labels/new.html.haml"
|
- 'app/views/groups/labels/new.html.haml'
|
||||||
- "app/views/groups/milestones/edit.html.haml"
|
- 'app/views/groups/milestones/edit.html.haml'
|
||||||
- "app/views/groups/milestones/index.html.haml"
|
- 'app/views/groups/milestones/index.html.haml'
|
||||||
- "app/views/groups/milestones/new.html.haml"
|
- 'app/views/groups/milestones/new.html.haml'
|
||||||
- "app/views/groups/projects.html.haml"
|
- 'app/views/groups/projects.html.haml'
|
||||||
- "app/views/groups/runners/edit.html.haml"
|
- 'app/views/groups/runners/edit.html.haml'
|
||||||
- "app/views/groups/settings/_advanced.html.haml"
|
- 'app/views/groups/settings/_advanced.html.haml'
|
||||||
- "app/views/groups/settings/_lfs.html.haml"
|
- 'app/views/groups/settings/_lfs.html.haml'
|
||||||
- "app/views/help/_shortcuts.html.haml"
|
- 'app/views/help/_shortcuts.html.haml'
|
||||||
- "app/views/help/index.html.haml"
|
- 'app/views/help/index.html.haml'
|
||||||
- "app/views/help/instance_configuration.html.haml"
|
- 'app/views/help/instance_configuration.html.haml'
|
||||||
- "app/views/help/instance_configuration/_gitlab_ci.html.haml"
|
- 'app/views/help/instance_configuration/_gitlab_ci.html.haml'
|
||||||
- "app/views/help/instance_configuration/_gitlab_pages.html.haml"
|
- 'app/views/help/instance_configuration/_gitlab_pages.html.haml'
|
||||||
- "app/views/import/bitbucket/status.html.haml"
|
- 'app/views/import/bitbucket/status.html.haml'
|
||||||
- "app/views/import/bitbucket_server/status.html.haml"
|
- 'app/views/import/bitbucket_server/status.html.haml'
|
||||||
- "app/views/invites/show.html.haml"
|
- 'app/views/invites/show.html.haml'
|
||||||
- "app/views/jira_connect/subscriptions/index.html.haml"
|
- 'app/views/jira_connect/subscriptions/index.html.haml'
|
||||||
- "app/views/layouts/_mailer.html.haml"
|
- 'app/views/layouts/_mailer.html.haml'
|
||||||
- "app/views/layouts/experiment_mailer.html.haml"
|
- 'app/views/layouts/experiment_mailer.html.haml'
|
||||||
- "app/views/layouts/header/_default.html.haml"
|
- 'app/views/layouts/header/_default.html.haml'
|
||||||
- "app/views/layouts/header/_new_dropdown.haml"
|
- 'app/views/layouts/header/_new_dropdown.haml'
|
||||||
- "app/views/layouts/jira_connect.html.haml"
|
- 'app/views/layouts/jira_connect.html.haml'
|
||||||
- "app/views/layouts/notify.html.haml"
|
- 'app/views/layouts/notify.html.haml'
|
||||||
- "app/views/notify/_failed_builds.html.haml"
|
- 'app/views/notify/_failed_builds.html.haml'
|
||||||
- "app/views/notify/_reassigned_issuable_email.html.haml"
|
- 'app/views/notify/_reassigned_issuable_email.html.haml'
|
||||||
- "app/views/notify/_removal_notification.html.haml"
|
- 'app/views/notify/_removal_notification.html.haml'
|
||||||
- "app/views/notify/_successful_pipeline.html.haml"
|
- 'app/views/notify/_successful_pipeline.html.haml'
|
||||||
- "app/views/notify/autodevops_disabled_email.html.haml"
|
- 'app/views/notify/autodevops_disabled_email.html.haml'
|
||||||
- "app/views/notify/changed_milestone_email.html.haml"
|
- 'app/views/notify/changed_milestone_email.html.haml'
|
||||||
- "app/views/notify/import_issues_csv_email.html.haml"
|
- 'app/views/notify/import_issues_csv_email.html.haml'
|
||||||
- "app/views/notify/issue_moved_email.html.haml"
|
- 'app/views/notify/issue_moved_email.html.haml'
|
||||||
- "app/views/notify/member_access_denied_email.html.haml"
|
- 'app/views/notify/member_access_denied_email.html.haml'
|
||||||
- "app/views/notify/member_invite_accepted_email.html.haml"
|
- 'app/views/notify/member_invite_accepted_email.html.haml'
|
||||||
- "app/views/notify/member_invited_email.html.haml"
|
- 'app/views/notify/member_invited_email.html.haml'
|
||||||
- "app/views/notify/new_gpg_key_email.html.haml"
|
- 'app/views/notify/new_gpg_key_email.html.haml'
|
||||||
- "app/views/notify/new_mention_in_issue_email.html.haml"
|
- 'app/views/notify/new_mention_in_issue_email.html.haml'
|
||||||
- "app/views/notify/new_ssh_key_email.html.haml"
|
- 'app/views/notify/new_ssh_key_email.html.haml'
|
||||||
- "app/views/notify/new_user_email.html.haml"
|
- 'app/views/notify/new_user_email.html.haml'
|
||||||
- "app/views/notify/pages_domain_disabled_email.html.haml"
|
- 'app/views/notify/pages_domain_disabled_email.html.haml'
|
||||||
- "app/views/notify/pages_domain_enabled_email.html.haml"
|
- 'app/views/notify/pages_domain_enabled_email.html.haml'
|
||||||
- "app/views/notify/pages_domain_verification_failed_email.html.haml"
|
- 'app/views/notify/pages_domain_verification_failed_email.html.haml'
|
||||||
- "app/views/notify/pages_domain_verification_succeeded_email.html.haml"
|
- 'app/views/notify/pages_domain_verification_succeeded_email.html.haml'
|
||||||
- "app/views/notify/pipeline_failed_email.html.haml"
|
- 'app/views/notify/pipeline_failed_email.html.haml'
|
||||||
- "app/views/notify/project_was_exported_email.html.haml"
|
- 'app/views/notify/project_was_exported_email.html.haml'
|
||||||
- "app/views/notify/project_was_moved_email.html.haml"
|
- 'app/views/notify/project_was_moved_email.html.haml'
|
||||||
- "app/views/notify/project_was_not_exported_email.html.haml"
|
- 'app/views/notify/project_was_not_exported_email.html.haml'
|
||||||
- "app/views/notify/push_to_merge_request_email.html.haml"
|
- 'app/views/notify/push_to_merge_request_email.html.haml'
|
||||||
- "app/views/notify/remote_mirror_update_failed_email.html.haml"
|
- 'app/views/notify/remote_mirror_update_failed_email.html.haml'
|
||||||
- "app/views/notify/removed_milestone_issue_email.html.haml"
|
- 'app/views/notify/removed_milestone_issue_email.html.haml'
|
||||||
- "app/views/notify/removed_milestone_merge_request_email.html.haml"
|
- 'app/views/notify/removed_milestone_merge_request_email.html.haml'
|
||||||
- "app/views/notify/repository_push_email.html.haml"
|
- 'app/views/notify/repository_push_email.html.haml'
|
||||||
- "app/views/profiles/chat_names/_chat_name.html.haml"
|
- 'app/views/profiles/chat_names/_chat_name.html.haml'
|
||||||
- "app/views/profiles/chat_names/index.html.haml"
|
- 'app/views/profiles/chat_names/index.html.haml'
|
||||||
- "app/views/profiles/chat_names/new.html.haml"
|
- 'app/views/profiles/chat_names/new.html.haml'
|
||||||
- "app/views/projects/_bitbucket_import_modal.html.haml"
|
- 'app/views/projects/_bitbucket_import_modal.html.haml'
|
||||||
- "app/views/projects/_customize_workflow.html.haml"
|
- 'app/views/projects/_customize_workflow.html.haml'
|
||||||
- "app/views/projects/_deletion_failed.html.haml"
|
- 'app/views/projects/_deletion_failed.html.haml'
|
||||||
- "app/views/projects/_fork_suggestion.html.haml"
|
- 'app/views/projects/_fork_suggestion.html.haml'
|
||||||
- "app/views/projects/_gitlab_import_modal.html.haml"
|
- 'app/views/projects/_gitlab_import_modal.html.haml'
|
||||||
- "app/views/projects/_home_panel.html.haml"
|
- 'app/views/projects/_home_panel.html.haml'
|
||||||
- "app/views/projects/_import_project_pane.html.haml"
|
- 'app/views/projects/_import_project_pane.html.haml'
|
||||||
- "app/views/projects/_issuable_by_email.html.haml"
|
- 'app/views/projects/_issuable_by_email.html.haml'
|
||||||
- "app/views/projects/_readme.html.haml"
|
- 'app/views/projects/_readme.html.haml'
|
||||||
- "app/views/projects/artifacts/_artifact.html.haml"
|
- 'app/views/projects/artifacts/_artifact.html.haml'
|
||||||
- "app/views/projects/artifacts/_tree_file.html.haml"
|
- 'app/views/projects/artifacts/_tree_file.html.haml'
|
||||||
- "app/views/projects/artifacts/browse.html.haml"
|
- 'app/views/projects/artifacts/browse.html.haml'
|
||||||
- "app/views/projects/blame/_age_map_legend.html.haml"
|
- 'app/views/projects/blame/_age_map_legend.html.haml'
|
||||||
- "app/views/projects/blame/show.html.haml"
|
- 'app/views/projects/blame/show.html.haml'
|
||||||
- "app/views/projects/blob/_editor.html.haml"
|
- 'app/views/projects/blob/_editor.html.haml'
|
||||||
- "app/views/projects/blob/_header_content.html.haml"
|
- 'app/views/projects/blob/_header_content.html.haml'
|
||||||
- "app/views/projects/blob/_remove.html.haml"
|
- 'app/views/projects/blob/_remove.html.haml'
|
||||||
- "app/views/projects/blob/_render_error.html.haml"
|
- 'app/views/projects/blob/_render_error.html.haml'
|
||||||
- "app/views/projects/blob/edit.html.haml"
|
- 'app/views/projects/blob/edit.html.haml'
|
||||||
- "app/views/projects/blob/new.html.haml"
|
- 'app/views/projects/blob/new.html.haml'
|
||||||
- "app/views/projects/blob/preview.html.haml"
|
- 'app/views/projects/blob/preview.html.haml'
|
||||||
- "app/views/projects/blob/viewers/_empty.html.haml"
|
- 'app/views/projects/blob/viewers/_empty.html.haml'
|
||||||
- "app/views/projects/blob/viewers/_stl.html.haml"
|
- 'app/views/projects/blob/viewers/_stl.html.haml'
|
||||||
- "app/views/projects/branches/_branch.html.haml"
|
- 'app/views/projects/branches/_branch.html.haml'
|
||||||
- "app/views/projects/branches/_delete_protected_modal.html.haml"
|
- 'app/views/projects/branches/_delete_protected_modal.html.haml'
|
||||||
- "app/views/projects/branches/new.html.haml"
|
- 'app/views/projects/branches/new.html.haml'
|
||||||
- "app/views/projects/ci/builds/_build.html.haml"
|
- 'app/views/projects/ci/builds/_build.html.haml'
|
||||||
- "app/views/projects/ci/lints/_create.html.haml"
|
- 'app/views/projects/ci/lints/_create.html.haml'
|
||||||
- "app/views/projects/compare/_form.html.haml"
|
- 'app/views/projects/compare/_form.html.haml'
|
||||||
- "app/views/projects/compare/index.html.haml"
|
- 'app/views/projects/compare/index.html.haml'
|
||||||
- "app/views/projects/cycle_analytics/_empty_stage.html.haml"
|
- 'app/views/projects/cycle_analytics/_empty_stage.html.haml'
|
||||||
- "app/views/projects/cycle_analytics/_no_access.html.haml"
|
- 'app/views/projects/cycle_analytics/_no_access.html.haml'
|
||||||
- "app/views/projects/cycle_analytics/_overview.html.haml"
|
- 'app/views/projects/cycle_analytics/_overview.html.haml'
|
||||||
- "app/views/projects/cycle_analytics/show.html.haml"
|
- 'app/views/projects/cycle_analytics/show.html.haml'
|
||||||
- "app/views/projects/deploy_keys/_form.html.haml"
|
- 'app/views/projects/deploy_keys/_form.html.haml'
|
||||||
- "app/views/projects/deploy_keys/_index.html.haml"
|
- 'app/views/projects/deploy_keys/_index.html.haml'
|
||||||
- "app/views/projects/deploy_keys/edit.html.haml"
|
- 'app/views/projects/deploy_keys/edit.html.haml'
|
||||||
- "app/views/projects/deployments/_deployment.html.haml"
|
- 'app/views/projects/deployments/_deployment.html.haml'
|
||||||
- "app/views/projects/diffs/_file_header.html.haml"
|
- 'app/views/projects/diffs/_file_header.html.haml'
|
||||||
- "app/views/projects/diffs/_replaced_image_diff.html.haml"
|
- 'app/views/projects/diffs/_replaced_image_diff.html.haml'
|
||||||
- "app/views/projects/diffs/_stats.html.haml"
|
- 'app/views/projects/diffs/_stats.html.haml'
|
||||||
- "app/views/projects/empty.html.haml"
|
- 'app/views/projects/empty.html.haml'
|
||||||
- "app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml"
|
- 'app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml'
|
||||||
- "app/views/projects/hook_logs/_index.html.haml"
|
- 'app/views/projects/hook_logs/_index.html.haml'
|
||||||
- "app/views/projects/hook_logs/show.html.haml"
|
- 'app/views/projects/hook_logs/show.html.haml'
|
||||||
- "app/views/projects/hooks/edit.html.haml"
|
- 'app/views/projects/hooks/edit.html.haml'
|
||||||
- "app/views/projects/imports/new.html.haml"
|
- 'app/views/projects/imports/new.html.haml'
|
||||||
- "app/views/projects/imports/show.html.haml"
|
- 'app/views/projects/imports/show.html.haml'
|
||||||
- "app/views/projects/issues/_new_branch.html.haml"
|
- 'app/views/projects/issues/_new_branch.html.haml'
|
||||||
- "app/views/projects/issues/import_csv/_modal.html.haml"
|
- 'app/views/projects/issues/import_csv/_modal.html.haml'
|
||||||
- "app/views/projects/issues/show.html.haml"
|
- 'app/views/projects/issues/show.html.haml'
|
||||||
- "app/views/projects/jobs/_header.html.haml"
|
- 'app/views/projects/jobs/_header.html.haml'
|
||||||
- "app/views/projects/jobs/_table.html.haml"
|
- 'app/views/projects/jobs/_table.html.haml'
|
||||||
- "app/views/projects/jobs/index.html.haml"
|
- 'app/views/projects/jobs/index.html.haml'
|
||||||
- "app/views/projects/labels/edit.html.haml"
|
- 'app/views/projects/labels/edit.html.haml'
|
||||||
- "app/views/projects/labels/new.html.haml"
|
- 'app/views/projects/labels/new.html.haml'
|
||||||
- "app/views/projects/mattermosts/_no_teams.html.haml"
|
- 'app/views/projects/mattermosts/_no_teams.html.haml'
|
||||||
- "app/views/projects/mattermosts/_team_selection.html.haml"
|
- 'app/views/projects/mattermosts/_team_selection.html.haml'
|
||||||
- "app/views/projects/mattermosts/new.html.haml"
|
- 'app/views/projects/mattermosts/new.html.haml'
|
||||||
- "app/views/projects/merge_requests/_commits.html.haml"
|
- 'app/views/projects/merge_requests/_commits.html.haml'
|
||||||
- "app/views/projects/merge_requests/_discussion.html.haml"
|
- 'app/views/projects/merge_requests/_how_to_merge.html.haml'
|
||||||
- "app/views/projects/merge_requests/_how_to_merge.html.haml"
|
- 'app/views/projects/merge_requests/_mr_title.html.haml'
|
||||||
- "app/views/projects/merge_requests/_mr_title.html.haml"
|
- 'app/views/projects/merge_requests/conflicts/_commit_stats.html.haml'
|
||||||
- "app/views/projects/merge_requests/conflicts/_commit_stats.html.haml"
|
- 'app/views/projects/merge_requests/conflicts/_file_actions.html.haml'
|
||||||
- "app/views/projects/merge_requests/conflicts/_file_actions.html.haml"
|
- 'app/views/projects/merge_requests/conflicts/_submit_form.html.haml'
|
||||||
- "app/views/projects/merge_requests/conflicts/_submit_form.html.haml"
|
- 'app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml'
|
||||||
- "app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml"
|
- 'app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml'
|
||||||
- "app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml"
|
- 'app/views/projects/merge_requests/conflicts/show.html.haml'
|
||||||
- "app/views/projects/merge_requests/conflicts/show.html.haml"
|
- 'app/views/projects/merge_requests/creations/_diffs.html.haml'
|
||||||
- "app/views/projects/merge_requests/creations/_diffs.html.haml"
|
- 'app/views/projects/merge_requests/creations/_new_compare.html.haml'
|
||||||
- "app/views/projects/merge_requests/creations/_new_compare.html.haml"
|
- 'app/views/projects/merge_requests/creations/_new_submit.html.haml'
|
||||||
- "app/views/projects/merge_requests/creations/_new_submit.html.haml"
|
- 'app/views/projects/merge_requests/diffs/_different_base.html.haml'
|
||||||
- "app/views/projects/merge_requests/diffs/_different_base.html.haml"
|
- 'app/views/projects/merge_requests/diffs/_diffs.html.haml'
|
||||||
- "app/views/projects/merge_requests/diffs/_diffs.html.haml"
|
- 'app/views/projects/merge_requests/diffs/_version_controls.html.haml'
|
||||||
- "app/views/projects/merge_requests/diffs/_version_controls.html.haml"
|
- 'app/views/projects/merge_requests/invalid.html.haml'
|
||||||
- "app/views/projects/merge_requests/invalid.html.haml"
|
- 'app/views/projects/merge_requests/widget/open/_error.html.haml'
|
||||||
- "app/views/projects/merge_requests/widget/open/_error.html.haml"
|
- 'app/views/projects/mirrors/_regenerate_public_ssh_key_confirm_modal.html.haml'
|
||||||
- "app/views/projects/mirrors/_regenerate_public_ssh_key_confirm_modal.html.haml"
|
- 'app/views/projects/mirrors/_ssh_host_keys.html.haml'
|
||||||
- "app/views/projects/mirrors/_ssh_host_keys.html.haml"
|
- 'app/views/projects/no_repo.html.haml'
|
||||||
- "app/views/projects/no_repo.html.haml"
|
- 'app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml'
|
||||||
- "app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml"
|
- 'app/views/projects/pipelines/_info.html.haml'
|
||||||
- "app/views/projects/pipelines/_info.html.haml"
|
- 'app/views/projects/protected_branches/shared/_dropdown.html.haml'
|
||||||
- "app/views/projects/protected_branches/shared/_dropdown.html.haml"
|
- 'app/views/projects/protected_branches/shared/_index.html.haml'
|
||||||
- "app/views/projects/protected_branches/shared/_index.html.haml"
|
- 'app/views/projects/protected_branches/shared/_matching_branch.html.haml'
|
||||||
- "app/views/projects/protected_branches/shared/_matching_branch.html.haml"
|
- 'app/views/projects/protected_branches/shared/_protected_branch.html.haml'
|
||||||
- "app/views/projects/protected_branches/shared/_protected_branch.html.haml"
|
- 'app/views/projects/protected_branches/show.html.haml'
|
||||||
- "app/views/projects/protected_branches/show.html.haml"
|
- 'app/views/projects/protected_tags/shared/_create_protected_tag.html.haml'
|
||||||
- "app/views/projects/protected_tags/shared/_create_protected_tag.html.haml"
|
- 'app/views/projects/protected_tags/shared/_dropdown.html.haml'
|
||||||
- "app/views/projects/protected_tags/shared/_dropdown.html.haml"
|
- 'app/views/projects/protected_tags/shared/_index.html.haml'
|
||||||
- "app/views/projects/protected_tags/shared/_index.html.haml"
|
- 'app/views/projects/protected_tags/shared/_matching_tag.html.haml'
|
||||||
- "app/views/projects/protected_tags/shared/_matching_tag.html.haml"
|
- 'app/views/projects/protected_tags/shared/_protected_tag.html.haml'
|
||||||
- "app/views/projects/protected_tags/shared/_protected_tag.html.haml"
|
- 'app/views/projects/protected_tags/shared/_tags_list.html.haml'
|
||||||
- "app/views/projects/protected_tags/shared/_tags_list.html.haml"
|
- 'app/views/projects/protected_tags/show.html.haml'
|
||||||
- "app/views/projects/protected_tags/show.html.haml"
|
- 'app/views/projects/registry/repositories/_tag.html.haml'
|
||||||
- "app/views/projects/registry/repositories/_tag.html.haml"
|
- 'app/views/projects/repositories/_feed.html.haml'
|
||||||
- "app/views/projects/repositories/_feed.html.haml"
|
- 'app/views/projects/runners/_shared_runners.html.haml'
|
||||||
- "app/views/projects/runners/_shared_runners.html.haml"
|
- 'app/views/projects/runners/edit.html.haml'
|
||||||
- "app/views/projects/runners/edit.html.haml"
|
- 'app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml'
|
||||||
- "app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml"
|
- 'app/views/projects/services/mattermost_slash_commands/_help.html.haml'
|
||||||
- "app/views/projects/services/mattermost_slash_commands/_help.html.haml"
|
- 'app/views/projects/services/prometheus/_metrics.html.haml'
|
||||||
- "app/views/projects/services/prometheus/_metrics.html.haml"
|
- 'app/views/projects/services/slack_slash_commands/_help.html.haml'
|
||||||
- "app/views/projects/services/slack_slash_commands/_help.html.haml"
|
- 'app/views/projects/settings/ci_cd/_badge.html.haml'
|
||||||
- "app/views/projects/settings/ci_cd/_badge.html.haml"
|
- 'app/views/projects/settings/ci_cd/_form.html.haml'
|
||||||
- "app/views/projects/settings/ci_cd/_form.html.haml"
|
- 'app/views/projects/tags/index.html.haml'
|
||||||
- "app/views/projects/tags/index.html.haml"
|
- 'app/views/projects/tags/releases/edit.html.haml'
|
||||||
- "app/views/projects/tags/releases/edit.html.haml"
|
- 'app/views/projects/tree/_tree_row.html.haml'
|
||||||
- "app/views/projects/tree/_tree_row.html.haml"
|
- 'app/views/projects/tree/_truncated_notice_tree_row.html.haml'
|
||||||
- "app/views/projects/tree/_truncated_notice_tree_row.html.haml"
|
- 'app/views/projects/triggers/_form.html.haml'
|
||||||
- "app/views/projects/triggers/_form.html.haml"
|
- 'app/views/projects/triggers/_index.html.haml'
|
||||||
- "app/views/projects/triggers/_index.html.haml"
|
- 'app/views/projects/triggers/_trigger.html.haml'
|
||||||
- "app/views/projects/triggers/_trigger.html.haml"
|
- 'app/views/projects/triggers/edit.html.haml'
|
||||||
- "app/views/projects/triggers/edit.html.haml"
|
- 'app/views/search/results/_issue.html.haml'
|
||||||
- "app/views/search/results/_issue.html.haml"
|
- 'app/views/search/results/_note.html.haml'
|
||||||
- "app/views/search/results/_note.html.haml"
|
- 'app/views/search/results/_snippet_blob.html.haml'
|
||||||
- "app/views/search/results/_snippet_blob.html.haml"
|
- 'app/views/search/results/_snippet_title.html.haml'
|
||||||
- "app/views/search/results/_snippet_title.html.haml"
|
- 'app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml'
|
||||||
- "app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml"
|
- 'app/views/shared/_commit_message_container.html.haml'
|
||||||
- "app/views/shared/_commit_message_container.html.haml"
|
- 'app/views/shared/_delete_label_modal.html.haml'
|
||||||
- "app/views/shared/_delete_label_modal.html.haml"
|
- 'app/views/shared/_group_form.html.haml'
|
||||||
- "app/views/shared/_group_form.html.haml"
|
- 'app/views/shared/_group_tips.html.haml'
|
||||||
- "app/views/shared/_group_tips.html.haml"
|
- 'app/views/shared/_md_preview.html.haml'
|
||||||
- "app/views/shared/_md_preview.html.haml"
|
- 'app/views/shared/_milestone_expired.html.haml'
|
||||||
- "app/views/shared/_milestone_expired.html.haml"
|
- '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/_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"
|
- 'app/views/shared/boards/components/sidebar/_milestone.html.haml'
|
||||||
- "app/views/shared/boards/components/sidebar/_milestone.html.haml"
|
- 'app/views/shared/hook_logs/_content.html.haml'
|
||||||
- "app/views/shared/hook_logs/_content.html.haml"
|
- 'app/views/shared/issuable/_assignees.html.haml'
|
||||||
- "app/views/shared/issuable/_assignees.html.haml"
|
- 'app/views/shared/issuable/_board_create_list_dropdown.html.haml'
|
||||||
- "app/views/shared/issuable/_board_create_list_dropdown.html.haml"
|
- 'app/views/shared/issuable/_close_reopen_report_toggle.html.haml'
|
||||||
- "app/views/shared/issuable/_close_reopen_report_toggle.html.haml"
|
- 'app/views/shared/issuable/_form.html.haml'
|
||||||
- "app/views/shared/issuable/_form.html.haml"
|
- 'app/views/shared/issuable/_search_bar.html.haml'
|
||||||
- "app/views/shared/issuable/_search_bar.html.haml"
|
- 'app/views/shared/issuable/_sidebar.html.haml'
|
||||||
- "app/views/shared/issuable/_sidebar.html.haml"
|
- 'app/views/shared/issuable/form/_default_templates.html.haml'
|
||||||
- "app/views/shared/issuable/form/_default_templates.html.haml"
|
- 'app/views/shared/issuable/form/_template_selector.html.haml'
|
||||||
- "app/views/shared/issuable/form/_template_selector.html.haml"
|
- 'app/views/shared/issuable/form/_title.html.haml'
|
||||||
- "app/views/shared/issuable/form/_title.html.haml"
|
- 'app/views/shared/labels/_form.html.haml'
|
||||||
- "app/views/shared/labels/_form.html.haml"
|
- 'app/views/shared/members/_member.html.haml'
|
||||||
- "app/views/shared/members/_member.html.haml"
|
- 'app/views/shared/milestones/_form_dates.html.haml'
|
||||||
- "app/views/shared/milestones/_form_dates.html.haml"
|
- 'app/views/shared/milestones/_issuable.html.haml'
|
||||||
- "app/views/shared/milestones/_issuable.html.haml"
|
- 'app/views/shared/milestones/_milestone.html.haml'
|
||||||
- "app/views/shared/milestones/_milestone.html.haml"
|
- 'app/views/shared/milestones/_sidebar.html.haml'
|
||||||
- "app/views/shared/milestones/_sidebar.html.haml"
|
- 'app/views/shared/milestones/_top.html.haml'
|
||||||
- "app/views/shared/milestones/_top.html.haml"
|
- 'app/views/shared/notes/_hints.html.haml'
|
||||||
- "app/views/shared/notes/_hints.html.haml"
|
- 'app/views/shared/notifications/_button.html.haml'
|
||||||
- "app/views/shared/notifications/_button.html.haml"
|
- 'app/views/shared/notifications/_new_button.html.haml'
|
||||||
- "app/views/shared/notifications/_new_button.html.haml"
|
- 'app/views/shared/runners/_runner_description.html.haml'
|
||||||
- "app/views/shared/runners/_runner_description.html.haml"
|
- 'app/views/shared/runners/show.html.haml'
|
||||||
- "app/views/shared/runners/show.html.haml"
|
- 'app/views/shared/snippets/_header.html.haml'
|
||||||
- "app/views/shared/snippets/_header.html.haml"
|
- 'app/views/shared/snippets/_snippet.html.haml'
|
||||||
- "app/views/shared/snippets/_snippet.html.haml"
|
- 'app/views/shared/web_hooks/_form.html.haml'
|
||||||
- "app/views/shared/web_hooks/_form.html.haml"
|
- 'app/views/shared/web_hooks/_hook.html.haml'
|
||||||
- "app/views/shared/web_hooks/_hook.html.haml"
|
- 'app/views/shared/wikis/_pages_wiki_page.html.haml'
|
||||||
- "app/views/shared/wikis/_pages_wiki_page.html.haml"
|
- 'app/views/users/_deletion_guidance.html.haml'
|
||||||
- "app/views/users/_deletion_guidance.html.haml"
|
- 'ee/app/views/admin/_namespace_plan_info.html.haml'
|
||||||
- "ee/app/views/admin/_namespace_plan_info.html.haml"
|
- 'ee/app/views/admin/application_settings/_templates.html.haml'
|
||||||
- "ee/app/views/admin/application_settings/_templates.html.haml"
|
- 'ee/app/views/admin/audit_logs/index.html.haml'
|
||||||
- "ee/app/views/admin/audit_logs/index.html.haml"
|
- 'ee/app/views/admin/emails/show.html.haml'
|
||||||
- "ee/app/views/admin/emails/show.html.haml"
|
- 'ee/app/views/admin/geo/projects/_registry_failed.html.haml'
|
||||||
- "ee/app/views/admin/geo/projects/_registry_failed.html.haml"
|
- 'ee/app/views/admin/geo/projects/_registry_never.html.haml'
|
||||||
- "ee/app/views/admin/geo/projects/_registry_never.html.haml"
|
- 'ee/app/views/admin/licenses/_upload_trial_license.html.haml'
|
||||||
- "ee/app/views/admin/licenses/_upload_trial_license.html.haml"
|
- 'ee/app/views/admin/licenses/new.html.haml'
|
||||||
- "ee/app/views/admin/licenses/new.html.haml"
|
- 'ee/app/views/admin/monitoring/ee/_nav.html.haml'
|
||||||
- "ee/app/views/admin/monitoring/ee/_nav.html.haml"
|
- 'ee/app/views/admin/projects/_shared_runner_status.html.haml'
|
||||||
- "ee/app/views/admin/projects/_shared_runner_status.html.haml"
|
- 'ee/app/views/admin/users/_auditor_access_level_radio.html.haml'
|
||||||
- "ee/app/views/admin/users/_auditor_access_level_radio.html.haml"
|
- 'ee/app/views/admin/users/_auditor_user_badge.html.haml'
|
||||||
- "ee/app/views/admin/users/_auditor_user_badge.html.haml"
|
- 'ee/app/views/admin/users/_limits.html.haml'
|
||||||
- "ee/app/views/admin/users/_limits.html.haml"
|
- 'ee/app/views/admin/users/_user_detail_note.html.haml'
|
||||||
- "ee/app/views/admin/users/_user_detail_note.html.haml"
|
- 'ee/app/views/dashboard/projects/_blank_state_ee_trial.html.haml'
|
||||||
- "ee/app/views/dashboard/projects/_blank_state_ee_trial.html.haml"
|
- 'ee/app/views/errors/kerberos_denied.html.haml'
|
||||||
- "ee/app/views/errors/kerberos_denied.html.haml"
|
- 'ee/app/views/groups/ee/_settings_nav.html.haml'
|
||||||
- "ee/app/views/groups/ee/_settings_nav.html.haml"
|
- 'ee/app/views/groups/group_members/_ldap_sync.html.haml'
|
||||||
- "ee/app/views/groups/group_members/_ldap_sync.html.haml"
|
- 'ee/app/views/groups/group_members/_sync_button.html.haml'
|
||||||
- "ee/app/views/groups/group_members/_sync_button.html.haml"
|
- 'ee/app/views/groups/hooks/edit.html.haml'
|
||||||
- "ee/app/views/groups/hooks/edit.html.haml"
|
- 'ee/app/views/groups/ldap_group_links/index.html.haml'
|
||||||
- "ee/app/views/groups/ldap_group_links/index.html.haml"
|
- 'ee/app/views/layouts/nav/ee/admin/_new_monitoring_sidebar.html.haml'
|
||||||
- "ee/app/views/layouts/nav/ee/admin/_new_monitoring_sidebar.html.haml"
|
- 'ee/app/views/layouts/service_desk.html.haml'
|
||||||
- "ee/app/views/layouts/service_desk.html.haml"
|
- 'ee/app/views/ldap_group_links/_form.html.haml'
|
||||||
- "ee/app/views/ldap_group_links/_form.html.haml"
|
- 'ee/app/views/ldap_group_links/_ldap_group_link.html.haml'
|
||||||
- "ee/app/views/ldap_group_links/_ldap_group_link.html.haml"
|
- 'ee/app/views/ldap_group_links/_ldap_group_links.html.haml'
|
||||||
- "ee/app/views/ldap_group_links/_ldap_group_links.html.haml"
|
- 'ee/app/views/ldap_group_links/_ldap_group_links_show.html.haml'
|
||||||
- "ee/app/views/ldap_group_links/_ldap_group_links_show.html.haml"
|
- 'ee/app/views/namespaces/_shared_runner_status.html.haml'
|
||||||
- "ee/app/views/ldap_group_links/_ldap_group_links_synchronizations.html.haml"
|
- 'ee/app/views/namespaces/_shared_runners_minutes_setting.html.haml'
|
||||||
- "ee/app/views/namespaces/_shared_runner_status.html.haml"
|
- 'ee/app/views/namespaces/pipelines_quota/_extra_shared_runners_minutes_quota.html.haml'
|
||||||
- "ee/app/views/namespaces/_shared_runners_minutes_setting.html.haml"
|
- 'ee/app/views/namespaces/pipelines_quota/_list.haml'
|
||||||
- "ee/app/views/namespaces/pipelines_quota/_extra_shared_runners_minutes_quota.html.haml"
|
- 'ee/app/views/notify/approved_merge_request_email.html.haml'
|
||||||
- "ee/app/views/namespaces/pipelines_quota/_list.haml"
|
- 'ee/app/views/notify/epic_status_changed_email.html.haml'
|
||||||
- "ee/app/views/notify/approved_merge_request_email.html.haml"
|
- 'ee/app/views/notify/new_review_email.html.haml'
|
||||||
- "ee/app/views/notify/epic_status_changed_email.html.haml"
|
- 'ee/app/views/notify/send_admin_notification.html.haml'
|
||||||
- "ee/app/views/notify/new_review_email.html.haml"
|
- 'ee/app/views/notify/send_unsubscribed_notification.html.haml'
|
||||||
- "ee/app/views/notify/send_admin_notification.html.haml"
|
- 'ee/app/views/notify/unapproved_merge_request_email.html.haml'
|
||||||
- "ee/app/views/notify/send_unsubscribed_notification.html.haml"
|
- 'ee/app/views/oauth/geo_auth/error.html.haml'
|
||||||
- "ee/app/views/notify/unapproved_merge_request_email.html.haml"
|
- 'ee/app/views/projects/commits/_mirror_status.html.haml'
|
||||||
- "ee/app/views/oauth/geo_auth/error.html.haml"
|
- 'ee/app/views/projects/merge_requests/_approvals_count.html.haml'
|
||||||
- "ee/app/views/projects/commits/_mirror_status.html.haml"
|
- 'ee/app/views/projects/merge_requests/widget/open/_geo.html.haml'
|
||||||
- "ee/app/views/projects/merge_requests/_approvals_count.html.haml"
|
- 'ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml'
|
||||||
- "ee/app/views/projects/merge_requests/widget/open/_geo.html.haml"
|
- 'ee/app/views/projects/protected_branches/_update_protected_branch.html.haml'
|
||||||
- "ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml"
|
- 'ee/app/views/projects/protected_branches/ee/_create_protected_branch.html.haml'
|
||||||
- "ee/app/views/projects/protected_branches/_update_protected_branch.html.haml"
|
- 'ee/app/views/projects/protected_branches/ee/_dropdown.html.haml'
|
||||||
- "ee/app/views/projects/protected_branches/ee/_create_protected_branch.html.haml"
|
- 'ee/app/views/projects/protected_tags/_protected_tag_extra_create_access_levels.haml'
|
||||||
- "ee/app/views/projects/protected_branches/ee/_dropdown.html.haml"
|
- 'ee/app/views/projects/protected_tags/ee/_create_protected_tag.html.haml'
|
||||||
- "ee/app/views/projects/protected_tags/_protected_tag_extra_create_access_levels.haml"
|
- 'ee/app/views/projects/push_rules/_index.html.haml'
|
||||||
- "ee/app/views/projects/protected_tags/ee/_create_protected_tag.html.haml"
|
- 'ee/app/views/projects/services/gitlab_slack_application/_help.html.haml'
|
||||||
- "ee/app/views/projects/push_rules/_index.html.haml"
|
- 'ee/app/views/projects/services/gitlab_slack_application/_slack_integration_form.html.haml'
|
||||||
- "ee/app/views/projects/services/gitlab_slack_application/_help.html.haml"
|
- 'ee/app/views/projects/settings/slacks/edit.html.haml'
|
||||||
- "ee/app/views/projects/services/gitlab_slack_application/_slack_integration_form.html.haml"
|
- 'ee/app/views/shared/_mirror_update_button.html.haml'
|
||||||
- "ee/app/views/projects/settings/slacks/edit.html.haml"
|
- 'ee/app/views/shared/epic/_search_bar.html.haml'
|
||||||
- "ee/app/views/shared/_mirror_update_button.html.haml"
|
- 'ee/app/views/shared/issuable/_approvals.html.haml'
|
||||||
- "ee/app/views/shared/epic/_search_bar.html.haml"
|
- 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
|
||||||
- "ee/app/views/shared/issuable/_approvals.html.haml"
|
- 'ee/app/views/shared/issuable/_filter_weight.html.haml'
|
||||||
- "ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml"
|
- 'ee/app/views/shared/members/ee/_ldap_tag.html.haml'
|
||||||
- "ee/app/views/shared/issuable/_filter_weight.html.haml"
|
- 'ee/app/views/shared/members/ee/_override_member_buttons.html.haml'
|
||||||
- "ee/app/views/shared/members/ee/_ldap_tag.html.haml"
|
- 'ee/app/views/shared/members/ee/_sso_badge.html.haml'
|
||||||
- "ee/app/views/shared/members/ee/_override_member_buttons.html.haml"
|
- 'ee/app/views/shared/milestones/_burndown.html.haml'
|
||||||
- "ee/app/views/shared/members/ee/_sso_badge.html.haml"
|
- 'ee/app/views/shared/milestones/_weight.html.haml'
|
||||||
- "ee/app/views/shared/milestones/_burndown.html.haml"
|
- 'ee/app/views/shared/promotions/_promote_issue_weights.html.haml'
|
||||||
- "ee/app/views/shared/milestones/_weight.html.haml"
|
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||||
- "ee/app/views/shared/promotions/_promote_issue_weights.html.haml"
|
- 'ee/app/views/shared/promotions/_promote_servicedesk.html.haml'
|
||||||
- "ee/app/views/shared/promotions/_promote_repository_features.html.haml"
|
- 'ee/app/views/shared/push_rules/_form.html.haml'
|
||||||
- "ee/app/views/shared/promotions/_promote_servicedesk.html.haml"
|
- 'ee/app/views/unsubscribes/show.html.haml'
|
||||||
- "ee/app/views/shared/push_rules/_form.html.haml"
|
|
||||||
- "ee/app/views/unsubscribes/show.html.haml"
|
|
||||||
|
|
33
.rubocop.yml
33
.rubocop.yml
|
@ -293,7 +293,15 @@ Gitlab/AvoidFeatureGet:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
RSpec/TimecopFreeze:
|
RSpec/TimecopFreeze:
|
||||||
Enabled: false
|
Enabled: true
|
||||||
|
AutoCorrect: true
|
||||||
|
Include:
|
||||||
|
- 'spec/**/*.rb'
|
||||||
|
- 'ee/spec/**/*.rb'
|
||||||
|
- 'qa/spec/**/*.rb'
|
||||||
|
|
||||||
|
RSpec/TimecopTravel:
|
||||||
|
Enabled: true
|
||||||
AutoCorrect: true
|
AutoCorrect: true
|
||||||
Include:
|
Include:
|
||||||
- 'spec/**/*.rb'
|
- 'spec/**/*.rb'
|
||||||
|
@ -327,7 +335,7 @@ Gitlab/Union:
|
||||||
- 'spec/**/*'
|
- 'spec/**/*'
|
||||||
- 'ee/spec/**/*'
|
- 'ee/spec/**/*'
|
||||||
|
|
||||||
API/GrapeAPIInstance:
|
API/Base:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Include:
|
Include:
|
||||||
- 'lib/**/api/**/*.rb'
|
- 'lib/**/api/**/*.rb'
|
||||||
|
@ -354,6 +362,21 @@ Graphql/AuthorizeTypes:
|
||||||
- 'spec/**/*.rb'
|
- 'spec/**/*.rb'
|
||||||
- 'ee/spec/**/*.rb'
|
- 'ee/spec/**/*.rb'
|
||||||
|
|
||||||
|
Graphql/GIDExpectedType:
|
||||||
|
Enabled: true
|
||||||
|
Include:
|
||||||
|
- 'app/graphql/**/*'
|
||||||
|
- 'ee/app/graphql/**/*'
|
||||||
|
Exclude:
|
||||||
|
- 'spec/**/*.rb'
|
||||||
|
- 'ee/spec/**/*.rb'
|
||||||
|
|
||||||
|
Graphql/IDType:
|
||||||
|
Enabled: true
|
||||||
|
Include:
|
||||||
|
- 'app/graphql/**/*'
|
||||||
|
- 'ee/app/graphql/**/*'
|
||||||
|
|
||||||
Graphql/JSONType:
|
Graphql/JSONType:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Include:
|
Include:
|
||||||
|
@ -548,3 +571,9 @@ Gitlab/RailsLogger:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'spec/**/*.rb'
|
- 'spec/**/*.rb'
|
||||||
- 'ee/spec/**/*.rb'
|
- 'ee/spec/**/*.rb'
|
||||||
|
|
||||||
|
# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/267606
|
||||||
|
FactoryBot/InlineAssociation:
|
||||||
|
Include:
|
||||||
|
- 'spec/factories/**/*.rb'
|
||||||
|
- 'ee/spec/factories/**/*.rb'
|
||||||
|
|
|
@ -105,14 +105,6 @@ Lint/StructNewOverride:
|
||||||
- 'app/serializers/environment_serializer.rb'
|
- 'app/serializers/environment_serializer.rb'
|
||||||
- 'lib/gitlab/ci/pipeline/duration.rb'
|
- 'lib/gitlab/ci/pipeline/duration.rb'
|
||||||
|
|
||||||
# Offense count: 7
|
|
||||||
Lint/UriEscapeUnescape:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/application_controller.rb'
|
|
||||||
- 'app/models/project_services/drone_ci_service.rb'
|
|
||||||
- 'spec/lib/google_api/auth_spec.rb'
|
|
||||||
- 'spec/requests/api/files_spec.rb'
|
|
||||||
|
|
||||||
# Offense count: 65
|
# Offense count: 65
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Migration/DepartmentName:
|
Migration/DepartmentName:
|
||||||
|
@ -162,8 +154,6 @@ Performance/Count:
|
||||||
- 'app/helpers/groups_helper.rb'
|
- 'app/helpers/groups_helper.rb'
|
||||||
- 'app/services/merge_requests/add_context_service.rb'
|
- 'app/services/merge_requests/add_context_service.rb'
|
||||||
- 'ee/lib/gitlab/graphql/aggregations/epics/epic_node.rb'
|
- 'ee/lib/gitlab/graphql/aggregations/epics/epic_node.rb'
|
||||||
- 'ee/spec/controllers/projects/feature_flags_controller_spec.rb'
|
|
||||||
- 'ee/spec/requests/api/feature_flags_spec.rb'
|
|
||||||
- 'lib/gitlab/sidekiq_status.rb'
|
- 'lib/gitlab/sidekiq_status.rb'
|
||||||
- 'spec/lib/gitlab/conflict/file_spec.rb'
|
- 'spec/lib/gitlab/conflict/file_spec.rb'
|
||||||
- 'spec/lib/gitlab/git/tree_spec.rb'
|
- 'spec/lib/gitlab/git/tree_spec.rb'
|
||||||
|
@ -175,8 +165,6 @@ Performance/Count:
|
||||||
Performance/Detect:
|
Performance/Detect:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'ee/spec/controllers/projects/dependencies_controller_spec.rb'
|
- 'ee/spec/controllers/projects/dependencies_controller_spec.rb'
|
||||||
- 'ee/spec/controllers/projects/feature_flags_controller_spec.rb'
|
|
||||||
- 'ee/spec/requests/api/unleash_spec.rb'
|
|
||||||
- 'spec/lib/gitlab/git/tree_spec.rb'
|
- 'spec/lib/gitlab/git/tree_spec.rb'
|
||||||
- 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
|
- 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
|
||||||
- 'spec/models/event_spec.rb'
|
- 'spec/models/event_spec.rb'
|
||||||
|
@ -195,6 +183,35 @@ RSpec/ContextWording:
|
||||||
RSpec/ExpectChange:
|
RSpec/ExpectChange:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 47
|
||||||
|
RSpec/ExpectGitlabTracking:
|
||||||
|
Exclude:
|
||||||
|
- 'ee/spec/controllers/groups/analytics/coverage_reports_controller_spec.rb'
|
||||||
|
- 'ee/spec/controllers/projects/settings/operations_controller_spec.rb'
|
||||||
|
- 'ee/spec/controllers/registrations_controller_spec.rb'
|
||||||
|
- 'ee/spec/requests/api/visual_review_discussions_spec.rb'
|
||||||
|
- 'ee/spec/services/epics/issue_promote_service_spec.rb'
|
||||||
|
- 'spec/controllers/groups/registry/repositories_controller_spec.rb'
|
||||||
|
- 'spec/controllers/groups_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/registry/repositories_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/registry/tags_controller_spec.rb'
|
||||||
|
- 'spec/controllers/projects/settings/operations_controller_spec.rb'
|
||||||
|
- 'spec/controllers/registrations_controller_spec.rb'
|
||||||
|
- 'spec/lib/api/helpers_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/experimentation_spec.rb'
|
||||||
|
- 'spec/mailers/notify_spec.rb'
|
||||||
|
- 'spec/models/project_services/prometheus_service_spec.rb'
|
||||||
|
- 'spec/requests/api/project_container_repositories_spec.rb'
|
||||||
|
- 'spec/services/clusters/applications/check_installation_progress_service_spec.rb'
|
||||||
|
- 'spec/services/issues/zoom_link_service_spec.rb'
|
||||||
|
- 'spec/support/helpers/snowplow_helpers.rb'
|
||||||
|
- 'spec/support/shared_examples/controllers/trackable_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/discussions_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/packages_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/tracking_shared_examples.rb'
|
||||||
|
- 'spec/support/snowplow.rb'
|
||||||
|
|
||||||
# Offense count: 751
|
# Offense count: 751
|
||||||
RSpec/ExpectInHook:
|
RSpec/ExpectInHook:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -700,13 +717,9 @@ Rails/SaveBang:
|
||||||
- '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_project_rule_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/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/elastic/note_spec.rb'
|
|
||||||
- 'ee/spec/models/ee/appearance_spec.rb'
|
- 'ee/spec/models/ee/appearance_spec.rb'
|
||||||
- 'ee/spec/models/ee/ci/job_artifact_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'
|
||||||
|
@ -954,16 +967,12 @@ Rails/SaveBang:
|
||||||
- '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/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/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/create_note_handler_spec.rb'
|
||||||
- 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb'
|
- 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb'
|
||||||
- 'spec/lib/gitlab/gfm/reference_rewriter_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/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/object_pool_service_spec.rb'
|
||||||
- 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb'
|
- 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb'
|
||||||
|
@ -1042,18 +1051,6 @@ Rails/SaveBang:
|
||||||
- 'spec/models/clusters/applications/helm_spec.rb'
|
- 'spec/models/clusters/applications/helm_spec.rb'
|
||||||
- 'spec/models/commit_spec.rb'
|
- 'spec/models/commit_spec.rb'
|
||||||
- 'spec/models/commit_status_spec.rb'
|
- 'spec/models/commit_status_spec.rb'
|
||||||
- 'spec/models/concerns/avatarable_spec.rb'
|
|
||||||
- 'spec/models/concerns/bulk_insertable_associations_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/issuable_spec.rb'
|
|
||||||
- 'spec/models/concerns/mentionable_spec.rb'
|
|
||||||
- 'spec/models/concerns/milestoneable_spec.rb'
|
|
||||||
- 'spec/models/concerns/milestoneish_spec.rb'
|
|
||||||
- 'spec/models/concerns/routable_spec.rb'
|
|
||||||
- 'spec/models/concerns/subscribable_spec.rb'
|
|
||||||
- 'spec/models/concerns/token_authenticatable_spec.rb'
|
|
||||||
- 'spec/models/container_repository_spec.rb'
|
- 'spec/models/container_repository_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'
|
||||||
|
@ -1085,7 +1082,6 @@ 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/operations/feature_flag_scope_spec.rb'
|
- 'spec/models/operations/feature_flag_scope_spec.rb'
|
||||||
- 'spec/models/operations/feature_flag_spec.rb'
|
|
||||||
- 'spec/models/operations/feature_flags/strategy_spec.rb'
|
- 'spec/models/operations/feature_flags/strategy_spec.rb'
|
||||||
- 'spec/models/operations/feature_flags/user_list_spec.rb'
|
- 'spec/models/operations/feature_flags/user_list_spec.rb'
|
||||||
- 'spec/models/pages_domain_spec.rb'
|
- 'spec/models/pages_domain_spec.rb'
|
||||||
|
@ -1140,31 +1136,11 @@ Rails/SaveBang:
|
||||||
- '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/common_system_notes_service_spec.rb'
|
|
||||||
- 'spec/services/labels/promote_service_spec.rb'
|
- 'spec/services/labels/promote_service_spec.rb'
|
||||||
- 'spec/services/milestones/destroy_service_spec.rb'
|
|
||||||
- 'spec/services/milestones/promote_service_spec.rb'
|
|
||||||
- 'spec/services/milestones/transfer_service_spec.rb'
|
|
||||||
- 'spec/services/notes/create_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/packages/conan/create_package_file_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/destroy_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_project_group_links_service_spec.rb'
|
|
||||||
- 'spec/services/projects/overwrite_project_service_spec.rb'
|
|
||||||
- 'spec/services/projects/propagate_service_template_spec.rb'
|
|
||||||
- 'spec/services/projects/unlink_fork_service_spec.rb'
|
|
||||||
- 'spec/services/projects/update_pages_service_spec.rb'
|
|
||||||
- 'spec/services/projects/update_service_spec.rb'
|
|
||||||
- 'spec/services/quick_actions/interpret_service_spec.rb'
|
|
||||||
- 'spec/services/reset_project_cache_service_spec.rb'
|
- 'spec/services/reset_project_cache_service_spec.rb'
|
||||||
- 'spec/services/resource_events/change_milestone_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'
|
||||||
|
@ -1176,20 +1152,188 @@ Rails/SaveBang:
|
||||||
- '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/services/verify_pages_domain_service_spec.rb'
|
||||||
- 'spec/sidekiq/cron/job_gem_dependency_spec.rb'
|
- 'spec/sidekiq/cron/job_gem_dependency_spec.rb'
|
||||||
- 'spec/support/migrations_helpers/cluster_helpers.rb'
|
|
||||||
- 'spec/support/migrations_helpers/namespaces_helper.rb'
|
# Offense count: 187
|
||||||
- 'spec/support/shared_contexts/email_shared_context.rb'
|
# Cop supports --auto-correct.
|
||||||
- 'spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb'
|
RSpec/TimecopFreeze:
|
||||||
- 'spec/support/shared_contexts/mailers/notify_shared_context.rb'
|
Exclude:
|
||||||
- 'spec/support/shared_examples/controllers/cache_control_shared_examples.rb'
|
- 'ee/spec/controllers/admin/application_settings_controller_spec.rb'
|
||||||
- 'spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb'
|
- 'ee/spec/controllers/projects/security/network_policies_controller_spec.rb'
|
||||||
- 'spec/support/shared_examples/controllers/sessionless_auth_controller_shared_examples.rb'
|
- 'ee/spec/features/admin/admin_reset_pipeline_minutes_spec.rb'
|
||||||
- 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb'
|
- 'ee/spec/features/boards/sidebar_spec.rb'
|
||||||
- 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
|
- 'ee/spec/features/groups/analytics/cycle_analytics/filters_and_data_spec.rb'
|
||||||
- 'spec/support/shared_examples/policies/project_policy_shared_examples.rb'
|
- 'ee/spec/features/groups/iteration_spec.rb'
|
||||||
- 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
|
- 'ee/spec/features/projects/mirror_spec.rb'
|
||||||
- 'spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb'
|
- 'ee/spec/features/projects/services/prometheus_custom_metrics_spec.rb'
|
||||||
- 'spec/support/shared_examples/serializers/note_entity_shared_examples.rb'
|
- 'ee/spec/finders/productivity_analytics_finder_spec.rb'
|
||||||
- 'spec/tasks/gitlab/web_hook_rake_spec.rb'
|
- 'ee/spec/frontend/fixtures/analytics.rb'
|
||||||
- 'spec/uploaders/file_uploader_spec.rb'
|
- 'ee/spec/helpers/vulnerabilities_helper_spec.rb'
|
||||||
- 'spec/uploaders/object_storage_spec.rb'
|
- 'ee/spec/lib/analytics/merge_request_metrics_refresh_spec.rb'
|
||||||
|
- 'ee/spec/lib/analytics/productivity_analytics_request_params_spec.rb'
|
||||||
|
- 'ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_historical_statistics_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/group_stage_time_summary_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_time_summary_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/analytics/type_of_work/tasks_by_type_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/auth/group_saml/sso_enforcer_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/database/load_balancing/host_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/base_request_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_updated_event_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/oauth/login_state_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/insights/reducers/count_per_period_reducer_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/prometheus/queries/cluster_query_spec.rb'
|
||||||
|
- 'ee/spec/migrations/populate_vulnerability_historical_statistics_for_year_spec.rb'
|
||||||
|
- 'ee/spec/migrations/remove_duplicated_cs_findings_spec.rb'
|
||||||
|
- 'ee/spec/migrations/remove_duplicated_cs_findings_without_vulnerability_id_spec.rb'
|
||||||
|
- 'ee/spec/migrations/schedule_fix_orphan_promoted_issues_spec.rb'
|
||||||
|
- 'ee/spec/migrations/schedule_merge_request_any_approval_rule_migration_spec.rb'
|
||||||
|
- 'ee/spec/migrations/schedule_populate_resolved_on_default_branch_column_spec.rb'
|
||||||
|
- 'ee/spec/migrations/schedule_populate_vulnerability_historical_statistics_spec.rb'
|
||||||
|
- 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb'
|
||||||
|
- 'ee/spec/migrations/set_resolved_state_on_vulnerabilities_spec.rb'
|
||||||
|
- 'ee/spec/migrations/20190926180443_schedule_epic_issues_after_epics_move_spec.rb'
|
||||||
|
- 'ee/spec/models/analytics/cycle_analytics/group_level_spec.rb'
|
||||||
|
- 'ee/spec/models/burndown_spec.rb'
|
||||||
|
- 'ee/spec/models/ee/namespace_spec.rb'
|
||||||
|
- 'ee/spec/models/geo/project_registry_spec.rb'
|
||||||
|
- 'ee/spec/models/merge_train_spec.rb'
|
||||||
|
- 'ee/spec/models/productivity_analytics_spec.rb'
|
||||||
|
- 'ee/spec/models/project_spec.rb'
|
||||||
|
- 'ee/spec/models/vulnerabilities/export_spec.rb'
|
||||||
|
- 'ee/spec/requests/api/vulnerabilities_spec.rb'
|
||||||
|
- 'ee/spec/services/geo/file_download_service_spec.rb'
|
||||||
|
- 'ee/spec/services/vulnerabilities/confirm_service_spec.rb'
|
||||||
|
- 'ee/spec/services/vulnerabilities/dismiss_service_spec.rb'
|
||||||
|
- 'ee/spec/services/vulnerabilities/resolve_service_spec.rb'
|
||||||
|
- 'ee/spec/services/vulnerabilities/revert_to_detected_service_spec.rb'
|
||||||
|
- 'ee/spec/services/vulnerability_exports/export_service_spec.rb'
|
||||||
|
- 'ee/spec/support/shared_contexts/lib/gitlab/insights/reducers/reducers_shared_contexts.rb'
|
||||||
|
- 'qa/spec/support/repeater_spec.rb'
|
||||||
|
- 'spec/features/profiles/active_sessions_spec.rb'
|
||||||
|
- 'spec/features/projects/environments/environment_metrics_spec.rb'
|
||||||
|
- 'spec/features/users/active_sessions_spec.rb'
|
||||||
|
- 'spec/lib/atlassian/jira_connect/client_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/anonymous_session_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/auth/unique_ips_limiter_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/checks/timed_logger_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/cycle_analytics/usage_data_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/instrumentation_helper_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/puma_logging/json_formatter_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb'
|
||||||
|
- 'spec/lib/json_web_token/hmac_token_spec.rb'
|
||||||
|
- 'spec/lib/rspec_flaky/flaky_example_spec.rb'
|
||||||
|
- 'spec/lib/rspec_flaky/listener_spec.rb'
|
||||||
|
- 'spec/models/active_session_spec.rb'
|
||||||
|
- 'spec/models/container_repository_spec.rb'
|
||||||
|
- 'spec/models/pages/lookup_path_spec.rb'
|
||||||
|
- 'spec/models/project_feature_usage_spec.rb'
|
||||||
|
- 'spec/requests/api/v3/github_spec.rb'
|
||||||
|
- 'spec/serializers/entity_date_helper_spec.rb'
|
||||||
|
- 'spec/support/cycle_analytics_helpers/test_generation.rb'
|
||||||
|
- 'spec/support/helpers/cycle_analytics_helpers.rb'
|
||||||
|
- 'spec/support/helpers/javascript_fixtures_helpers.rb'
|
||||||
|
- 'spec/support/shared_contexts/rack_attack_shared_context.rb'
|
||||||
|
- 'spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb'
|
||||||
|
- 'spec/workers/concerns/reenqueuer_spec.rb'
|
||||||
|
- 'spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb'
|
||||||
|
|
||||||
|
# Offense count: 54
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
RSpec/TimecopTravel:
|
||||||
|
Exclude:
|
||||||
|
- 'ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb'
|
||||||
|
- 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb'
|
||||||
|
- 'ee/spec/models/broadcast_message_spec.rb'
|
||||||
|
- 'ee/spec/models/burndown_spec.rb'
|
||||||
|
- 'qa/spec/support/repeater_spec.rb'
|
||||||
|
- 'spec/features/users/terms_spec.rb'
|
||||||
|
- 'spec/lib/feature_spec.rb'
|
||||||
|
- 'spec/models/broadcast_message_spec.rb'
|
||||||
|
- 'spec/models/concerns/issuable_spec.rb'
|
||||||
|
- 'spec/requests/api/ci/runner/jobs_trace_spec.rb'
|
||||||
|
- 'spec/requests/api/issues/put_projects_issues_spec.rb'
|
||||||
|
- 'spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb'
|
||||||
|
- 'spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb'
|
||||||
|
- 'spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb'
|
||||||
|
- 'spec/workers/concerns/reenqueuer_spec.rb'
|
||||||
|
- 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb'
|
||||||
|
|
||||||
|
# Offense count: 43
|
||||||
|
Graphql/IDType:
|
||||||
|
Exclude:
|
||||||
|
- 'ee/app/graphql/ee/mutations/issues/update.rb'
|
||||||
|
- 'ee/app/graphql/ee/types/boards/board_issue_input_base_type.rb'
|
||||||
|
- 'ee/app/graphql/mutations/issues/set_epic.rb'
|
||||||
|
- 'ee/app/graphql/mutations/iterations/update.rb'
|
||||||
|
- 'ee/app/graphql/resolvers/iterations_resolver.rb'
|
||||||
|
- 'app/graphql/mutations/boards/create.rb'
|
||||||
|
- 'app/graphql/mutations/boards/issues/issue_move_list.rb'
|
||||||
|
- 'app/graphql/mutations/boards/lists/update.rb'
|
||||||
|
- 'app/graphql/mutations/issues/update.rb'
|
||||||
|
- 'app/graphql/mutations/metrics/dashboard/annotations/delete.rb'
|
||||||
|
- 'app/graphql/mutations/snippets/destroy.rb'
|
||||||
|
- 'app/graphql/mutations/snippets/mark_as_spam.rb'
|
||||||
|
- 'app/graphql/mutations/snippets/update.rb'
|
||||||
|
- 'app/graphql/resolvers/board_lists_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/boards_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/design_at_version_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/design_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/designs_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/version/design_at_version_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/version_in_collection_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/version_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/design_management/versions_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/error_tracking/sentry_error_stack_trace_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/snippets_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/user_merge_requests_resolver.rb'
|
||||||
|
- 'app/graphql/resolvers/user_resolver.rb'
|
||||||
|
|
||||||
|
# Offense count: 86
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
FactoryBot/InlineAssociation:
|
||||||
|
Exclude:
|
||||||
|
- 'ee/spec/factories/analytics/cycle_analytics/group_stages.rb'
|
||||||
|
- 'ee/spec/factories/geo/event_log.rb'
|
||||||
|
- 'ee/spec/factories/groups.rb'
|
||||||
|
- 'ee/spec/factories/merge_request_blocks.rb'
|
||||||
|
- 'ee/spec/factories/resource_iteration_event.rb'
|
||||||
|
- 'ee/spec/factories/resource_weight_events.rb'
|
||||||
|
- 'ee/spec/factories/vulnerabilities/feedback.rb'
|
||||||
|
- 'spec/factories/atlassian_identities.rb'
|
||||||
|
- 'spec/factories/audit_events.rb'
|
||||||
|
- 'spec/factories/design_management/design_at_version.rb'
|
||||||
|
- 'spec/factories/design_management/designs.rb'
|
||||||
|
- 'spec/factories/design_management/versions.rb'
|
||||||
|
- 'spec/factories/events.rb'
|
||||||
|
- 'spec/factories/git_wiki_commit_details.rb'
|
||||||
|
- 'spec/factories/gitaly/commit.rb'
|
||||||
|
- 'spec/factories/go_module_commits.rb'
|
||||||
|
- 'spec/factories/go_module_versions.rb'
|
||||||
|
- 'spec/factories/go_modules.rb'
|
||||||
|
- 'spec/factories/group_group_links.rb'
|
||||||
|
- 'spec/factories/import_export_uploads.rb'
|
||||||
|
- 'spec/factories/merge_requests.rb'
|
||||||
|
- 'spec/factories/notes.rb'
|
||||||
|
- 'spec/factories/packages.rb'
|
||||||
|
- 'spec/factories/packages/package_file.rb'
|
||||||
|
- 'spec/factories/resource_label_events.rb'
|
||||||
|
- 'spec/factories/resource_milestone_event.rb'
|
||||||
|
- 'spec/factories/resource_state_event.rb'
|
||||||
|
- 'spec/factories/sent_notifications.rb'
|
||||||
|
- 'spec/factories/serverless/domain.rb'
|
||||||
|
- 'spec/factories/serverless/domain_cluster.rb'
|
||||||
|
- 'spec/factories/terraform/state.rb'
|
||||||
|
- 'spec/factories/uploads.rb'
|
||||||
|
- 'spec/factories/wiki_pages.rb'
|
||||||
|
|
9
.test_license_encryption_key.pub
Normal file
9
.test_license_encryption_key.pub
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtgemxR8RUJXi3p7G/dkh
|
||||||
|
Yuln1L4lA6GtQsT83X0yTVDbLVsI2C6bepsRjGiLV0R/9JGvTojORx+9F/ZQAiEC
|
||||||
|
g6QXWasAOSmrzr4EjADG6cWcCnOju8hX9yib1HUIBxl+jHkmXP3NPuwyb8p2G149
|
||||||
|
EG1o4apEqE5RtqV/Xyx/u57xTYYZShJ/c7o4iA8xvt6IAKFPFKpQwb5hv4KvUZBP
|
||||||
|
h0xG2qvOjDu430fK8JclPlXHqPjXDkXOZyLd4FvRStdEQU3RVXvUQfuGt/tOMS7J
|
||||||
|
nPQ94fr/xdaEbcEtIlr32+tcgsMWyhqtDCPUWJT1aRPviUgaJKLoVs8tRKwYMV9+
|
||||||
|
1wIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
11
.theia/settings.json
Normal file
11
.theia/settings.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"ruby.codeCompletion": "rcodetools",
|
||||||
|
"ruby.format": "standard",
|
||||||
|
"ruby.intellisense": "rubyLocate",
|
||||||
|
"ruby.useBundler": true,
|
||||||
|
"ruby.useLanguageServer": true,
|
||||||
|
"ruby.lint": {
|
||||||
|
"rubocop": true,
|
||||||
|
"useBundler": true
|
||||||
|
}
|
||||||
|
}
|
661
CHANGELOG.md
661
CHANGELOG.md
|
@ -2,7 +2,7 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
## 13.4.7 (2020-12-07)
|
## 13.5.5 (2020-12-07)
|
||||||
|
|
||||||
### Security (10 changes)
|
### Security (10 changes)
|
||||||
|
|
||||||
|
@ -18,18 +18,30 @@ entry.
|
||||||
- Do not show starred & contributed projects of users with private profile.
|
- Do not show starred & contributed projects of users with private profile.
|
||||||
|
|
||||||
|
|
||||||
## 13.4.6 (2020-11-03)
|
## 13.5.4 (2020-11-13)
|
||||||
|
|
||||||
### Fixed (1 change)
|
### Fixed (4 changes)
|
||||||
|
|
||||||
|
- Fix Vue Labels Select dropdown keyboard scroll. !43874
|
||||||
|
- Hashed Storage: make migration and rollback resilient to exceptions. !46178
|
||||||
|
- Fix compliance framework database migration on CE instances. !46761
|
||||||
|
- Resolve problem when namespace_settings were not created for groups created via admin panel. !46875
|
||||||
|
|
||||||
|
|
||||||
|
## 13.5.3 (2020-11-03)
|
||||||
|
|
||||||
|
### Fixed (3 changes)
|
||||||
|
|
||||||
|
- Fix IDE issues with special characters. !46398
|
||||||
|
- Ensure that copy to clipboard button is visible. !46466
|
||||||
- Auto Deploy: fixes issues for fetching other charts from stable repo. !46531
|
- Auto Deploy: fixes issues for fetching other charts from stable repo. !46531
|
||||||
|
|
||||||
### Other (1 change)
|
### Added (1 change)
|
||||||
|
|
||||||
- GitLab-managed apps: Use GitLab's repo as replacement for the Helm stable repo. !44875
|
- Add environment variables to override backup/restore DB settings. !45855
|
||||||
|
|
||||||
|
|
||||||
## 13.4.5 (2020-11-02)
|
## 13.5.2 (2020-11-02)
|
||||||
|
|
||||||
### Security (9 changes)
|
### Security (9 changes)
|
||||||
|
|
||||||
|
@ -44,6 +56,587 @@ entry.
|
||||||
- Fix unauthorized user is able to access schedule pipeline variables and values.
|
- Fix unauthorized user is able to access schedule pipeline variables and values.
|
||||||
|
|
||||||
|
|
||||||
|
## 13.5.1 (2020-10-22)
|
||||||
|
|
||||||
|
### Other (1 change)
|
||||||
|
|
||||||
|
- Update GitLab Shell to v13.11.0. !45660
|
||||||
|
|
||||||
|
|
||||||
|
## 13.5.0 (2020-10-22)
|
||||||
|
|
||||||
|
### Security (1 change)
|
||||||
|
|
||||||
|
- Update GitLab Runner Helm Chart to 0.21.1.
|
||||||
|
|
||||||
|
### Removed (3 changes, 2 of them are from the community)
|
||||||
|
|
||||||
|
- Drop Iglu registry URL column. !42939
|
||||||
|
- Remove coverage_report_view feature flag. !43711 (David Barr @davebarr)
|
||||||
|
- Remove release_evidence_collection feature flag. !44234 (David Barr @davebarr)
|
||||||
|
|
||||||
|
### Fixed (118 changes, 9 of them are from the community)
|
||||||
|
|
||||||
|
- Include builds from child pipelines in latest sucessful build for ref/sha. !29710
|
||||||
|
- Fix branches_to_be_notified API param for hangouts chat service. !35599
|
||||||
|
- Add empty dependencies value to ECS Deploy job. !36862
|
||||||
|
- Fix issues with optional merge requests approval in CE. !42119 (Pavel Kuznetsov)
|
||||||
|
- Fix type of SentryErrorType global ID. !42185
|
||||||
|
- Remove linux arch only rule for coverage fuzzing. !42316
|
||||||
|
- Do not show retried builds in the MR code coverage. !42402 (Simon Lenz @koala7)
|
||||||
|
- Does not refresh project/snippet statistics on a read-only instance. !42417
|
||||||
|
- Rendering trailing slash in reference links (issue 205151). !42484
|
||||||
|
- Remove retry icon on failed job if merge pipeline. !42495
|
||||||
|
- Designs: return an error if uploading designs with duplicate names. !42514 (Sushil Khanchi)
|
||||||
|
- Unit Test Report: Fix icon for errored status. !42540
|
||||||
|
- Copy designs to issue when an issue with designs is moved. !42548
|
||||||
|
- Fix triggering multiple children pipeline with the same artifact. !42595
|
||||||
|
- Fix caret sizes in navigation. !42605
|
||||||
|
- Revert required encryption on CI runner tokens. !42623
|
||||||
|
- Fix Markdown "Preview" tab on New/Edit Release and New Snippet pages. !42640
|
||||||
|
- Fixed a bug causing 'Missing author note' to be added to notes for mapped users when importing project using GitLab Import. !42648
|
||||||
|
- Hides batch suggestions button if there is only 1 suggestion. !42681
|
||||||
|
- Fix GraphQL token authentication when installed under a relative URL. !42706
|
||||||
|
- Update pipeline failed notification e-mail warning. !42736
|
||||||
|
- Fix clickable width of release asset links. !42757
|
||||||
|
- Fix size of edit button on releases page. !42779
|
||||||
|
- Move before_script into script for CQ template. !42782 (Vicken Simonian @vicken.papaya)
|
||||||
|
- Resolve Error when quickly reordering designs. !42818
|
||||||
|
- Eliminate extra spacing on MR diffs from mobile/tablet screen. !42821 (Takuya Noguchi)
|
||||||
|
- Fix migrating some empty diffs. !42825
|
||||||
|
- Fix filtering epics when sorting by dates. !42827
|
||||||
|
- Fix edge case when updating snippet with no repo. !42964
|
||||||
|
- Fix group deploy tokens permissions for package access. !43007
|
||||||
|
- Empty state Packages UI links to user docs. !43009
|
||||||
|
- Allow Unleash clients to request feature flags when repository is private. !43059
|
||||||
|
- Show incident list for users who can read issues. !43060
|
||||||
|
- Auto-accept TOS if project bot. !43067
|
||||||
|
- Fix checking of task lists when MR description starts with a blank line. !43125
|
||||||
|
- Fix iteration validation not checking parent groups. !43234
|
||||||
|
- Fix theme selector not working immediately for some themes. !43239
|
||||||
|
- Reset labels select search text on Enter. !43285
|
||||||
|
- Ensure JobWaiter keys always expire. !43320
|
||||||
|
- Make git lfs for push mirrors work to GitHub.com. !43321
|
||||||
|
- Fix incorrect HTTP response in deactivate user API for internal user. !43356 (Sashi Kumar)
|
||||||
|
- Fix bug to allow container cleanup policies to properly run. !43359
|
||||||
|
- Delete project bot when token is revoked. !43373
|
||||||
|
- Allow to include project files in parent-child pipelines. !43404
|
||||||
|
- Fix button placement on pipeline graph. !43419
|
||||||
|
- Fix 500 error in block user API for internal user. !43461 (Sashi Kumar)
|
||||||
|
- Fix Web hook deletion not working when many hook logs are present. !43464
|
||||||
|
- Fix copy_indexes migration helper skipping the opclass for indexes with operator classes defined for them. !43471
|
||||||
|
- Add markdown icon to more file extensions. !43479
|
||||||
|
- Fix suggested squashed messages for MR. !43508
|
||||||
|
- Ensure code search results link to searched ref. !43510
|
||||||
|
- Fix broken user avatars in Jira Development Panel. !43563
|
||||||
|
- Update database helpers to set the current_schema. !43568
|
||||||
|
- Remove project bot user membership when project access token expires. !43605
|
||||||
|
- Improve the Commit box on the Merge Request Changs tab when browsing per commit. !43613
|
||||||
|
- GraphQL: No longer allows to omit ID when querying for a single board. !43627
|
||||||
|
- Fix group deploy tokens to return all projects and work with the Maven group endpoint. !43628
|
||||||
|
- Fix GraphQL backward pagination when merge requests are ordered by merged_at. !43701
|
||||||
|
- Fix approvedBy filed in MR GraphQL API. !43705
|
||||||
|
- Customize value of note_target_type for designs. !43727
|
||||||
|
- Fix displaying a message when design copying is in progress. !43749
|
||||||
|
- Fix verifying LFS uploads with GitHub. !43852
|
||||||
|
- Fix Delete User dialog formatted strings. !43871
|
||||||
|
- Add cleanup migration for JobWaiter Redis keys. !43882
|
||||||
|
- Include Design Management git repositories in GitLab Backup. !43947
|
||||||
|
- Add fuzzy search support to labels dropdown. !43969
|
||||||
|
- Fix broken button default class. !43977
|
||||||
|
- Fix full screen comment button on snippets. !44083
|
||||||
|
- Allow unauthenticated users access to public Personal Snippets via the REST API. !44135
|
||||||
|
- Fix the ability to assign labels based on license feature availability. !44171
|
||||||
|
- Recover gracefully when issuable counts are too expensive. !44184
|
||||||
|
- Fix attach file button not working in description fields. !44216
|
||||||
|
- Fix design scale bug when navigating to a design after zooming. !44262
|
||||||
|
- Prefer server-provided authentication for LFS push mirroring. !44284
|
||||||
|
- Return nil when fetching a wiki page with invalid arguments. !44302
|
||||||
|
- Update Design thumbnail after uploading an image with the same filename. !44305
|
||||||
|
- Add tooltip for pipeline actions. !44317
|
||||||
|
- Ensure suggestion works for number text. !44332
|
||||||
|
- Update NuGet version validation to allow for extended versions. !44335
|
||||||
|
- Respect DNT when tracking experiments. !44420
|
||||||
|
- Fix merge conflict button text if "None" code style selected. !44427 (David Barr @davebarr)
|
||||||
|
- Allow unauthenticated users access to public Project Snippets via the REST API. !44446
|
||||||
|
- Fix instance statistics GraphQL query with identifier. !44475
|
||||||
|
- Designs are moved with an Issue that is moved. !44524
|
||||||
|
- Fix Auto Deploy scale subcommand unintentionally recreates legacy PostgreSQL. !44535
|
||||||
|
- Fix emoji rendering in certain edge cases. !44542
|
||||||
|
- Return 422 error rather than 500 when composer.json is missing or malformed. !44587 (David Barr @davebarr)
|
||||||
|
- Use optimistic locking to safely migrate a build trace chunk. !44588
|
||||||
|
- Avoid New Environment button glitching when changing tabs. !44603
|
||||||
|
- Perform git actions with a user with elevated git permissions during a design copy. !44662
|
||||||
|
- Align badge with avatar in MR List. !44671
|
||||||
|
- Fix regression when uploading / viewing binary files in the Web IDE. !44699
|
||||||
|
- Exclude policies with no container repositories when executing them. !44748
|
||||||
|
- Fix unnecessarily escaped merge error text. !44844
|
||||||
|
- Fix button row margin on empty project. !44860
|
||||||
|
- Add note about cross site cookies browser limitaion to Jira App page. !44898
|
||||||
|
- Allow re-sending invite to minimal access user. !44936
|
||||||
|
- Fix dark mode for boards and swimlanes. !44951
|
||||||
|
- Fix dark mode for milestones. !44952
|
||||||
|
- Add missing 90x avatar size for image scaling. !45025
|
||||||
|
- Allow size limit to be available by default in the project pages settings form. !45054
|
||||||
|
- Fixed incorrect parameter in GraphQL startup call. !45115
|
||||||
|
- Fix table border hover for incidents and alerts. !45117
|
||||||
|
- Fix Jira Connect App update webhooks. !45151
|
||||||
|
- Fix scoped label markdown padding. !45153
|
||||||
|
- Fix redirects to issue sidebar JSON when visiting the login page. !45194
|
||||||
|
- Revert of Background migration for setting Jira tracker data deployment type. !45205
|
||||||
|
- Delete any outstanding BackfillJiraTrackerDeploymentType. !45219
|
||||||
|
- Fix mobile view of filtering bar. !45226
|
||||||
|
- Fix the maven md5 upload endpoint. !45271
|
||||||
|
- Redirect when no user is signed in when updating registration. !45276
|
||||||
|
- Class and markup cleanup to prevent SVG header bar overlap in Static Site Editor. !45334
|
||||||
|
- Update to Rack v2.1.4. !45340
|
||||||
|
- Avooid opening 2 modals for enabling review app. !45361
|
||||||
|
- Fix undefined tooltip text flashing on clipboard icon. !45482
|
||||||
|
- Fix error when cleaning up MR with no head ref. !45504
|
||||||
|
- Disable target branch filter option on merge requests dashboard.
|
||||||
|
- Fixed merge request tabs overlapping with system header.
|
||||||
|
|
||||||
|
### Deprecated (2 changes, 1 of them is from the community)
|
||||||
|
|
||||||
|
- Set abuse_notification_email instead of admin_notification_email. !41319 (Hiromi Nozawa)
|
||||||
|
- Drop column instance_statistics_visibility_private. !42969
|
||||||
|
|
||||||
|
### Changed (141 changes, 11 of them are from the community)
|
||||||
|
|
||||||
|
- Set default Referrer-Policy to strict-origin-when-cross-origin and set it in a header rather than HTML. !26065 (nhirokinet)
|
||||||
|
- Background migration for setting Jira tracker data deployment type. !37002
|
||||||
|
- Update clipboard button to use Pajamas. !38421
|
||||||
|
- Parallelize removal of expired artifacts. !39464
|
||||||
|
- Update styling of design comment pins. !39797
|
||||||
|
- Update confidential form buttons to gl-button. !40893
|
||||||
|
- Replace bootstrap alerts in app/views/admin/broadcast_messages/_form.html.haml. !41271 (Gilang Gumilar)
|
||||||
|
- Replace bootstrap alerts in app/views/import/shared/_errors.html.haml. !41288 (Gilang Gumilar)
|
||||||
|
- Replace bootstrap alerts in app/views/projects/diffs/_warning.html.haml. !41295 (Gilang Gumilar)
|
||||||
|
- Replace bootstrap alerts in app/views/profiles/accounts/show.html.haml. !41299 (Gilang Gumilar)
|
||||||
|
- Replace bootstrap alerts in app/views/admin/projects/show.html.haml. !41389 (Gilang Gumilar)
|
||||||
|
- Replace bootstrap alerts in app/views/projects/milestones/show.html.haml. !41396 (Gilang Gumilar)
|
||||||
|
- Update lock form buttons to gl-button. !41454
|
||||||
|
- Updated Discard Changes button in WebIDE. !41899
|
||||||
|
- Migrate DeprecatedModal to GitLab UI Modal. !42113
|
||||||
|
- Migrate custom Tabs to GlTabs. !42236
|
||||||
|
- Revert justified-content-end settings buttons. !42273
|
||||||
|
- Add Web IDE as dropdown item to diff file edit. !42275
|
||||||
|
- Expose the option to use namespace-per-project instead of namespace-per-environment for Kubernetes clusters. !42309
|
||||||
|
- Split name to first and last name for signup. !42346
|
||||||
|
- Move job token specs to core. !42374 (Mathieu Parent)
|
||||||
|
- Resolve Add filter capabilities to Incident list. !42377
|
||||||
|
- Remove angle brackets from empty name in U2F device settings. !42440
|
||||||
|
- Update sidebar operations order. !42493
|
||||||
|
- Add Gitpod enabled instance setting to Usage Data. !42563
|
||||||
|
- Add Gitpod enabled user setting to Usage Data. !42570
|
||||||
|
- Remove accept terms checkbox for signup. !42581
|
||||||
|
- Add user sign in indicator to Jira connect app. !42628
|
||||||
|
- Include monitoring tool from payload in system note for alert creation. !42631
|
||||||
|
- Rename Created to Published in package sort dropdown. !42677
|
||||||
|
- Breadcrumb like UI for project path in packages list. !42684
|
||||||
|
- Allow alerts to open on new tab. !42691
|
||||||
|
- Replace button component. !42716
|
||||||
|
- Add Issue Link to "Issue opened by" Integration Chat Message. !42785 (Kev @KevSlashNull)
|
||||||
|
- Hide instance-level integrations on GitLab.com. !42808
|
||||||
|
- Remove banner that suggests Web IDE for editing gitlab-ci.yml. !42815
|
||||||
|
- Updated the admin and user SSH key delete confirmation to use GlModal. !42824
|
||||||
|
- Add confirmation modal on instance-level integration form. !42840
|
||||||
|
- Use Conan recipe as package name in package API. !42860
|
||||||
|
- Show wiki tree structure in sidebar and pages overview. !42867
|
||||||
|
- Allow member mapping to map importer user on Group/Project Import. !42882
|
||||||
|
- Migrate environments folder tabs to GlTabs. !42894
|
||||||
|
- Update pypi install command to work with external dependencies. !42916
|
||||||
|
- Allow designs to be added, changed, or destroyed on locked and moved issues. !42935
|
||||||
|
- Add a title section to the Package Registry UI. !42963
|
||||||
|
- Allow time tracking in incidents. !42965
|
||||||
|
- Feature flags form: Replace fa-chevron-down with GitLab SVG. !42968
|
||||||
|
- Create a set of models to store the temporary data needed for a bulk import. !42978
|
||||||
|
- Adjusted deactivation threshold from 180 to 90 days. !42989
|
||||||
|
- Fix profile scoped label CSS. !43005
|
||||||
|
- Store pipeline counts by status for instance statistics. !43027
|
||||||
|
- Remove internal fields from alert details table. !43076
|
||||||
|
- Add hosts field to alert detail table. !43087
|
||||||
|
- Update alert GFM reference in highlight bar. !43104
|
||||||
|
- Replace fa-search with GitLab SVG search icon. !43110
|
||||||
|
- Update programming language colors and metadata. !43111
|
||||||
|
- Global Search - Bold Issue's Search Term. !43124
|
||||||
|
- Replace fa-external-link with GitLab SVG in group folder. !43128
|
||||||
|
- Add sort by similarity to getProjects GraphQL call. !43136
|
||||||
|
- Improve two button review submit in merge requests. !43149
|
||||||
|
- Update user feedback to a dedicated page as opposed to solely a button with a loader. !43189
|
||||||
|
- Enable project access tokens on GitLab.com. !43190
|
||||||
|
- VSA: Replace fa-warning with GitLab SVG. !43262
|
||||||
|
- Add assignee usernames to issue resolver. !43294
|
||||||
|
- Create ComplianceManagement::Framework Model. !43301
|
||||||
|
- Add invitation declined page. !43305
|
||||||
|
- Move approval MR filter and quick actions to CE. !43326 (Pavel Kuznetsov)
|
||||||
|
- Always set created_by_id when creating a user. !43342
|
||||||
|
- Description Templates: Replace fontawesome icons with GitLab SVGs. !43379
|
||||||
|
- Improve WebIDE error messages on committing. !43408
|
||||||
|
- Remove bootstrap usage from merge_requests/invalid. !43439
|
||||||
|
- Expose file path from XML Test Report artifact. !43594
|
||||||
|
- Always show the "Clear cluster cache" button among the advanced Kubernetes cluster configuration options. !43619
|
||||||
|
- Deprecate lowercase values for sort enums in GraphQL. !43650
|
||||||
|
- Replace double angle icons with GitLab SVG in issuables sidebar. !43655
|
||||||
|
- Set performance cookie to last for a year. !43692
|
||||||
|
- Add snippets to GitLab backups. !43694
|
||||||
|
- Restore snippet repositories from backups. !43696
|
||||||
|
- Update issue boards modal to gl-tabs. !43740
|
||||||
|
- Update nav icons to chevron-down. !43767
|
||||||
|
- Display alert for partially executed cleanup policies. !43831
|
||||||
|
- Show keep path for expired locked artifacts. !43866
|
||||||
|
- Replace fa-search fontawesome icons with GitLab SVG in Vue components. !43879
|
||||||
|
- Update toggle focus mode icon to gl-icon. !43888
|
||||||
|
- VSA: Replace fa-warning with GitLab SVG icon. !43994
|
||||||
|
- Add spam flag to snippet create/update mutations. !44010
|
||||||
|
- Include cached sql calls in performance bar. !44022
|
||||||
|
- Updated GraphQL mutation input ids to be more type specific. !44073
|
||||||
|
- Remove jquery tooltip API call from stop environment button. !44199
|
||||||
|
- Add filters on Milestone title in the GraphQL API. !44208
|
||||||
|
- Display conan recipe as package name on package detail page. !44294
|
||||||
|
- Respect Group's default branch name when present. !44370
|
||||||
|
- Enable automatic allocation of purchased storage. !44376
|
||||||
|
- Move remove board column button to sidebar. !44380
|
||||||
|
- Reposition wiki title on wiki pages. !44390
|
||||||
|
- Move wiki edit button inline with wiki title. !44391
|
||||||
|
- Allow users to navigate to the incidents show details page wrapper through `/issues/incidents/:id` from the Incident list. !44438
|
||||||
|
- Update delete badge modal to gl-modal. !44495
|
||||||
|
- Remove jquery tooltip from IDE activity bar. !44526
|
||||||
|
- Remove the `store_instance_statistics_measurements` feature flag. !44566
|
||||||
|
- Use GitLab SVG icons in file_type_icon_class helper. !44580
|
||||||
|
- Add pipeline_artifacts_size to RootStorageStatisticsType. !44595
|
||||||
|
- Copy project homepage default view for anonymous users. !44606 (George Tsiolis)
|
||||||
|
- Handle the blacklisted ip error in the Go middleware. !44614
|
||||||
|
- Add limit to number of test cases parsed by JUnit parser. !44615
|
||||||
|
- Track unique wiki page views in Usage Ping. !44622
|
||||||
|
- Automatically expand diffs for merge requests with changes to a single file. !44629
|
||||||
|
- Move feature flags to core. !44642
|
||||||
|
- Indicate on signin page instance is self-managed. !44681
|
||||||
|
- Replace fa icon with GitLab SVG in repository preview. !44696
|
||||||
|
- Replace fa-file-text-o icons with GitLab SVG doc-text icon. !44706
|
||||||
|
- Replace bootstrap alert in app/views/shared/milestones/_top.html.haml. !44731
|
||||||
|
- Back-port free instance review for instances with 50+ users from EE Core to CE. !44770
|
||||||
|
- Search for python packages with normalized name to allow installs of packages with periods and underscores. !44807
|
||||||
|
- Update integration descriptions to not be project-specific. !44893
|
||||||
|
- Projects created from templates inherits integrations. !44932
|
||||||
|
- Update issue and MR sidebar labels to use Vue instead of Haml. !44942
|
||||||
|
- Replaced blob-content-edit with editor-lite compoennt for Snippet edit form. !44994
|
||||||
|
- Replace fa-chevron-down with GitLab SVG in project visibility settings. !45021
|
||||||
|
- Allow more naming conventions for VSA production environment. !45069
|
||||||
|
- GraphQL: Changes fields in detailedStatus to be nullable. !45072
|
||||||
|
- Truncate over-long alert fields instead of return error response. !45099
|
||||||
|
- Raise Puma Worker Killer RAM limits. !45116
|
||||||
|
- Replace fa icons in CI build table. !45123
|
||||||
|
- Replace switcher fa- icons in blob viewer models. !45124
|
||||||
|
- Replace fa-calendar icon with GitLab SVG. !45175
|
||||||
|
- Minor UI improvements to Wiki edit page. !45247
|
||||||
|
- Replace fa-angle-double-left and fa-angle-double-right icons with GitLab SVG. !45251
|
||||||
|
- Remove CSS that ligthens texts in the pipeline. !45253
|
||||||
|
- Support all stackprof profiling modes. !45277
|
||||||
|
- Allow automatically selecting repository storage on move. !45338
|
||||||
|
- Updated GraphQL note mutation input ids to be more type-specific. !45341
|
||||||
|
- Update GraphQL discussionToggleResolve mutation input id to be more type-specific. !45346
|
||||||
|
- Update GitLab-Shell to v13.9.0. !45358
|
||||||
|
- Replace fa-file icons with GitLab SVG document icon. !45380
|
||||||
|
- Migrate '.fa-spinner' to '.spinner' for 'awards_list.vue'. !45393
|
||||||
|
- Update gitlab-shell to v13.10.0. !45408
|
||||||
|
- Replace fa-bitbucket-* icons with GitLab SVG. !45437
|
||||||
|
- Replace fa-google with GitLab SVG. !45506
|
||||||
|
- Replace fa-github with GitLab SVG MERGE_REQUEST_ID. !45533
|
||||||
|
- Move diff header actions into dropdown menu.
|
||||||
|
|
||||||
|
### Performance (21 changes, 1 of them is from the community)
|
||||||
|
|
||||||
|
- Improve n+1 in pipeline serializer for triggered pipelines. !42421
|
||||||
|
- Load issues tab in the milestone page asynchronously. !42473
|
||||||
|
- Add state_id index for merge_requests list. !42481
|
||||||
|
- Cleanup request http method/code metrics. !42618
|
||||||
|
- Optimise cleaning up LFS objects. !42830
|
||||||
|
- Modify time_period for last 28 days to improve batch counting performance. !42972
|
||||||
|
- Less inconsistent Edit links in sidebar. !43106
|
||||||
|
- Performance fix for issue placement. !43315
|
||||||
|
- Reduce cached SQL for JobsController#show. !43559
|
||||||
|
- Add index for project_id and sha to deployments table. !43836
|
||||||
|
- Don't expose http_request_duration_seconds metrics in sidekiq exporter. !43941
|
||||||
|
- Remove index on issues.relative_position. !43991
|
||||||
|
- Loads cropper css only when needed. !44137
|
||||||
|
- Preloading of Fontawesome Icon Font. !44282
|
||||||
|
- Remove duplicate index from the Vulnerabilities table. !44422 (Borivoje Tasovac @borivojetasovac)
|
||||||
|
- Optionally use merge request metrics association for merge request diff stats in GraphQL. !44613
|
||||||
|
- Remove Sentry implementation to investigate performance impact. !44643
|
||||||
|
- Optimize the loading of diffStats in merge request GraphQL API. !44752
|
||||||
|
- Preload `user_notes_count` in MergeRequest GraphQL API. !44894
|
||||||
|
- Remove the commit count from the commits API. !44934
|
||||||
|
- Enable caching of markdown when viewing blob. !45367
|
||||||
|
|
||||||
|
### Added (147 changes, 13 of them are from the community)
|
||||||
|
|
||||||
|
- Add canonical links for moved/duplicated issues. !34604
|
||||||
|
- Change transfer, update and create services for groups and projects to take in consideration shared runners settings. !36080 (Arthur de Lapertosa Lisboa)
|
||||||
|
- Add approval rules with approvers to usage ping. !36737
|
||||||
|
- Add index on ci_builds relation to improve Usage Ping metrics collection performance. !37581
|
||||||
|
- UI to disable shared runners by group. !39249
|
||||||
|
- Report auth events in manage stage usage ping. !39747
|
||||||
|
- Display youtube videos on the Static Site Editor. !39756
|
||||||
|
- Add LSIF to Go Auto DevOps gitlab-ci.yml. !40072
|
||||||
|
- Measure npm request forwarding usage. !40174
|
||||||
|
- Make URL links in job logs clickable. !40175 (Łukasz Groszkowski @falxcerebri)
|
||||||
|
- Add No Access Role for top group members. !40942
|
||||||
|
- Clean up unused LFS objects during repository housekeeping. !40979
|
||||||
|
- Send chat notification when deployment starts. !41214 (Sashi Kumar)
|
||||||
|
- Log failed BatchCount queries. !41552
|
||||||
|
- Add Group Import usage ping. !41663
|
||||||
|
- Add Sample Data. !41699
|
||||||
|
- Add Go(lang) to Packages. !41712 (Ethan Reesor (@firelizzard))
|
||||||
|
- Copy designs to new issue when issue is moved. !41714
|
||||||
|
- Add namespace setting to allow to mark if parent group allow subgroups to require 2FA. !41760
|
||||||
|
- Add cache:when keyword for ci yml config. !41822
|
||||||
|
- Adds package event tracking. !41846
|
||||||
|
- Add notification setting for merge request reviewers. !41851
|
||||||
|
- Track unique number of test cases parsed. !41918
|
||||||
|
- Introduce '.gitlab/static-site-editor.yml' config file, with support for 'static_site_generator' entry. !41957
|
||||||
|
- Migrate u2f registrations to webauthn registrations. !42159 (Jan Beckmann)
|
||||||
|
- Add internal API to download LFS objects. !42161
|
||||||
|
- Add state field to DastSiteValidation. !42198
|
||||||
|
- Pre-Collapsed Sections in CI Job Logs. !42231 (Kev @KevSlashNull)
|
||||||
|
- Improve issuable reaction search. !42321 (Ethan Reesor (@firelizzard))
|
||||||
|
- Show expanded CI config in CI lint API endpoint. !42380
|
||||||
|
- Display cluster list node information. !42396
|
||||||
|
- Validate not null file_store field on packages_package_files to maintain data integrity. !42400
|
||||||
|
- Add API endpoints to manage individual Terraform state versions. !42415
|
||||||
|
- Display Contributor badges on notes. !42576 (Mycroft Kang @TaehyeokKang)
|
||||||
|
- Add expiration policy started at support in container repositories. !42598
|
||||||
|
- Add a REST API endpoint to list group's descendants. !42620
|
||||||
|
- Match against description and unicode character when autocompleting GFM emoji. !42669 (Ethan Reesor (@firelizzard))
|
||||||
|
- Add Debian API skeleton. !42670 (Mathieu Parent)
|
||||||
|
- Use fuzzy matching for issuable awards. !42674 (Ethan Reesor (@firelizzard))
|
||||||
|
- Add Documentation URL to Admin Area. !42702
|
||||||
|
- Add close button to issue, MR, and epic sidebar labels. !42703
|
||||||
|
- Add :default_branch_name column to namespace_settings. !42778
|
||||||
|
- Add severity and published sorting for incident issues. !42800
|
||||||
|
- Replaced ACE with Editor Lite for CI linting. !42814
|
||||||
|
- Include `used_fields` and `used_deprecated_fields` in GraphQL logs. !42820
|
||||||
|
- Validate build traces using CRC32 checksums. !42829
|
||||||
|
- Reference pages_deployments in pages_metadata. !42834
|
||||||
|
- Display user project count on Admin Dashboard. !42871
|
||||||
|
- Add runner setup methods. !42878
|
||||||
|
- Add og:description meta tag to individual "Release" page. !42889
|
||||||
|
- Add validator for IP address/inet columns. !42893
|
||||||
|
- Add buttons in the Search page to clear Group and Project filters. !42897
|
||||||
|
- Update golang version in vendored Dockerfile template. !42917
|
||||||
|
- Strip markdown from og:description meta tags. !42918
|
||||||
|
- Add DesignCollection copyState GraphQL field. !42919
|
||||||
|
- Add projects_creating_incidents to usage ping counts. !42934
|
||||||
|
- Add project scoped CI lint API endpoint. !42998
|
||||||
|
- GrahphQL: Adds status to jobs, stages, and groups. !43069
|
||||||
|
- Destroy issue board list via GraphQL. !43081
|
||||||
|
- JS client for increment_unique_users API. !43084
|
||||||
|
- Add missing fontawesome file icon classes. !43091
|
||||||
|
- Adds button to update merge request draft status on merge request show page. !43098
|
||||||
|
- Sort incidents list by severity and published columns. !43121
|
||||||
|
- Update skeleton loader shape on releases pages. !43138
|
||||||
|
- Add security bot. !43147
|
||||||
|
- Redirect to documentation pages URL when configuration option is set. !43157
|
||||||
|
- Add on-demand DAST scan options (scanType, showDebugMessages, useAjaxSpider) ajax spider and set the scan type. !43240
|
||||||
|
- Enable snippet multiple files. !43246
|
||||||
|
- Add Debian regexps. !43259 (Mathieu Parent)
|
||||||
|
- Add sort parameter to Issue and Merge Request scopes. !43295
|
||||||
|
- Add timeline toggle button for incidents comments. !43302
|
||||||
|
- Add Gitpod Spring Petclinic to Project Templates. !43319
|
||||||
|
- Allow a users public GPG Keys to be API accessible. !43332
|
||||||
|
- Add file name column to CI unit test report. !43338
|
||||||
|
- Add GraphQL endpoint for Terraform state metadata. !43375
|
||||||
|
- Store user mentions to DB. !43393
|
||||||
|
- Upgrade GitLab Pages to 1.26.0. !43416
|
||||||
|
- Remove graphql_lookahead_support feature flag. !43438
|
||||||
|
- Introduce 'image_upload_path' entry support for '.gitlab/static-site-editor.yml' config file. !43481
|
||||||
|
- Introduce 'mounts' entry support for '.gitlab/static-site-editor.yml' config file. !43485
|
||||||
|
- Introduce required_code_owners_sections table. !43573
|
||||||
|
- Adds flexible rollout strategy UX and documentation. !43611
|
||||||
|
- Add table for alert http integrations for project. !43634
|
||||||
|
- Add a database column to enable or disable the setting that puts newly registered users in a pending state, requiring admin approval for their activation. !43661
|
||||||
|
- Seed initial version for non-versioned terraform states. !43665
|
||||||
|
- API support for a specific GPG Key for given user. !43693
|
||||||
|
- Enable design management reference filter. !43731
|
||||||
|
- Add GraphQL mutation to create an issue. !43735
|
||||||
|
- Enable wiki events on git push. !43738
|
||||||
|
- Adds a Terraform.latest.gitlab-ci.yml to support quick development of Terraform related features. !43802
|
||||||
|
- Store pipeline counts by status for instance statistics. !43857
|
||||||
|
- Show labels origin path on project labels page. !43858
|
||||||
|
- Enable querying for merge requests within a group. !43863
|
||||||
|
- Add API Fuzzing plan limits db column. !43934
|
||||||
|
- Enable Gitpod button on file tree view. !43961
|
||||||
|
- Accept issue filters when getting board lists in GraphQL. !43968
|
||||||
|
- Add system note on incident severity change. !43998
|
||||||
|
- Move Tracing usage data ping to Core. !44006
|
||||||
|
- Update Add Members API to accept user_id array. !44051
|
||||||
|
- GraphQL: Adds scheduledAt to CiJob. !44054
|
||||||
|
- IDE editor - Adding syntax highlighting for terraform / hcl. !44056
|
||||||
|
- Allow to update issue state on GraphQL. !44061
|
||||||
|
- Add merge request title and description UI to Static Site Editor submission flow. !44071
|
||||||
|
- GraphQL: Adds action to DetailedStatusType and StatusActioType. !44088
|
||||||
|
- Feature Flags limits UX and documentation. !44089
|
||||||
|
- Add Incident Sla timer columns to DB. !44099
|
||||||
|
- Add the ability to insert a YouTube video. !44102
|
||||||
|
- Include LFS blobs in archives. !44116
|
||||||
|
- Add sorting parameters to Releases API. !44118
|
||||||
|
- Add product analytics for design created and modified events. !44129
|
||||||
|
- Upgrade GitLab Pages to 1.27.0. !44162
|
||||||
|
- Add the Alerts integrations table to Alert integrations settings in the Operations section. !44181
|
||||||
|
- Add Issuable Service Level Agreement (SLA) table. !44253
|
||||||
|
- Use Web IDE to create new files in empty repos. !44287
|
||||||
|
- Create an issue board via GraphQL mutation. !44298
|
||||||
|
- Status icons for alerts integratiosn list. !44318
|
||||||
|
- Added UsageData metrics for issues added/removed from Epics. !44371
|
||||||
|
- Added UsageData metrics for Issue designs' usage. !44373
|
||||||
|
- Add unattended database migration option. !44392
|
||||||
|
- Add feature flag for a phased rollout of cleanup policies. !44444
|
||||||
|
- Sync LFS objects when push mirroring over HTTPS. !44457
|
||||||
|
- Snowplow count of clicks on timeline toggle for incident comments. !44487
|
||||||
|
- Allow to move issues between projects on GraphQL. !44491
|
||||||
|
- Support ci_forward_deployment_enabled in edit API. !44510
|
||||||
|
- Preserve the merge request title and description in the static site editor upon modal close. !44512
|
||||||
|
- Schedule adding "Missed SLA" label to issues. !44546
|
||||||
|
- Add usage ping to count Static Site Editor views. !44573
|
||||||
|
- Move Tracing feature to Core. !44574
|
||||||
|
- Added new editor-lite Vue component. !44577
|
||||||
|
- Add Middleman Logo for Project Templates. !44617
|
||||||
|
- Allow groups to disable 2FA requirement for subgroups. !44712
|
||||||
|
- Editor Lite to saupport extensions in instance constructor. !44723
|
||||||
|
- Enable core_security_mr_widget feature flag by default. !44764
|
||||||
|
- Add apply button when user changes assignees. !44812
|
||||||
|
- Make alerts searchable by assignee username in GraphQL API. !44911
|
||||||
|
- Include PostgreSQL system identifier in usage ping. !44972
|
||||||
|
- Snowplow tracking of Incident details views. !45011
|
||||||
|
- Show origin path of labels on subgroup labels page. !45040
|
||||||
|
- Enable one_dimensional_matrix feature flag by default. !45086
|
||||||
|
- Add support for Generic packages. !45102
|
||||||
|
- Expose `created_at` in Group and Project members API response. !45156 (Rajendra Kadam)
|
||||||
|
- Show all inherited labels in projects and subgroups. !45161
|
||||||
|
- Disallow NULL Bytes (U+0000) in requests. !45223
|
||||||
|
- Introduce 'admin approvals for new user signups' feature. !45233
|
||||||
|
- Upgrade GitLab Pages to 1.28.0. !45257
|
||||||
|
- Add vuex stores for milestone comboxbox. !45287
|
||||||
|
- Add support for manual bridges for CI pipelines. !45368
|
||||||
|
|
||||||
|
### Other (114 changes, 53 of them are from the community)
|
||||||
|
|
||||||
|
- Replace-GIDeprecatedDropdown-in-app/assets/javascripts/alert_management. !41409 (nuwe1)
|
||||||
|
- Replace-GlDeprecatedDropdown-with-GlDropdown-in-app/assets/javascripts/ci_variable_list. !41413 (nuwe1)
|
||||||
|
- Replace deprecated cluster dropdowns with updated dropdowns. !41414 (nuwe1)
|
||||||
|
- Replace-GlDeprecatedDropdown-with-GlDropdown-in-app/assets/javascripts/confidential_merge_request/components/dropdown.vue. !41416 (nuwe1)
|
||||||
|
- Replace-GlDeprecatedDropdown-with-GlDropdown-in-app/assets/javascripts/logs. !41421 (nuwe1)
|
||||||
|
- Replace-GlDeprecatedDropdown-with-GlDropdown-in-app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue. !41423 (nuwe1)
|
||||||
|
- Replace-GlDeprecatedDropdown-with-GlDropdown-in-app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_trigger_author_token.vue. !41424 (nuwe1)
|
||||||
|
- Replace `GlDeprecatedDropdown` with `GlDropdown` in `app/assets/javascripts/repository/components/breadcrumbs.vue`. !41427 (nuwe1)
|
||||||
|
- Replace `GlDeprecatedDropdown` with `GlDropdown` in app/assets/javascripts/vue_shared/components/split_button.vue. !41433 (nuwe1)
|
||||||
|
- Replace GlDeprecatedDropdown with GlDropDown in timezone-dropdown.vue. !41434 (nuwe1)
|
||||||
|
- Replace-GlDeprecatedDropdown-with-GlDropdown-in-ee/app/assets/javascripts/geo_node_form-and-ee/app/assets/javascripts/geo_replicable. !41438 (nuwe1)
|
||||||
|
- Remove bootrap alert from gcp offer. !41814
|
||||||
|
- Update database index on namespaces for type and id. !42128
|
||||||
|
- Populate issues blocking_issues_count. !42277
|
||||||
|
- Move shared logic into utils. !42407
|
||||||
|
- Update button to gl-button on GitLab for Slack page. !42426
|
||||||
|
- Refactor the invites controller member method. !42727
|
||||||
|
- Set hook_log css to gl-button. !42730 (Mike Terhar @mterhar)
|
||||||
|
- Remove an unnecessary element from every page. !42769 (Takuya Noguchi)
|
||||||
|
- Revise tooltip text of note role badge. !42771 (Mycroft Kang @TaehyeokKang)
|
||||||
|
- Fix Rails/SaveBang offenses for spec files in spec/services/milestones/*. !42775 (Rajendra Kadam)
|
||||||
|
- Fix Rails/SaveBang offenses for spec files in spec/services/issuable/*. !42780 (Rajendra Kadam)
|
||||||
|
- Fixes Rails/SaveBang cop for spec files in ee/spec/models/concerns/*. !42839 (Rajendra Kadam)
|
||||||
|
- Update GitLab Runner Helm Chart to 0.21.0. !42844
|
||||||
|
- Notifications icon: Render empty string for custom setting. !42848
|
||||||
|
- Update GitLab Workhorse to v8.47.0. !42855
|
||||||
|
- Remove duplicate index on cluster_agents. !42902
|
||||||
|
- Fixes Rails/SaveBang cop for spec files in spec/models/concerns/*. !42942 (Rajendra Kadam)
|
||||||
|
- Add issue_email_participants table and related model. !42943
|
||||||
|
- Add database view for postgres indexes. !42967
|
||||||
|
- Apply GitLab UI button styles to HAML buttons app/views/projects/blob. !42991 (Andrei Kyrnich @kyrnich)
|
||||||
|
- Fixes Rails/SaveBang cop for spec files in spec/lib/gitlab/git/*. !43013 (Rajendra Kadam)
|
||||||
|
- Migrate Recover hidden stage dropdown. !43032
|
||||||
|
- Remove unused cluster_providers_aws.created_by_user_id column. !43064
|
||||||
|
- Migrate badge list row buttons to new buttons. !43072
|
||||||
|
- Apply GitLab UI button styles to HAML buttons app/views/projects/forks. !43101 (Andrei Kyrnich @kyrnich)
|
||||||
|
- Remove temporary index for fixing broken CS fingerprints. !43126
|
||||||
|
- Track statistics for index rebuilds. !43156
|
||||||
|
- Allow get approvals on merge request by GraphQL in CE. !43325 (Pavel Kuznetsov)
|
||||||
|
- Apply GitLab UI styles to buttons in app/views/shared/labels directory. !43346 (Gary Bell @garybell)
|
||||||
|
- Update IDE compare changes view button to link style. !43403
|
||||||
|
- Remove bootstrap from pages/form. !43442
|
||||||
|
- Update popover to gl-popover on WebIDE commit message. !43499
|
||||||
|
- Update GitLab Workhorse to v8.48.0. !43586
|
||||||
|
- Add gl-button class to import and cancel buttons for project member import page. !43620 (Gary Bell @garybell)
|
||||||
|
- Update Design Management toolbar to use GitLab UI classes. !43682
|
||||||
|
- Remove type column on audit_events table. !43703
|
||||||
|
- Update button in modal_copy_button.vue to use GlButton from GitLab UI. !43714
|
||||||
|
- Migrate deprecated button to GlButton in ingress_modsecurity_settings.vue. !43717
|
||||||
|
- Migrate button in alert_widget_form.vue. !43720
|
||||||
|
- Migrate button in fluentd_output_settings.vue. !43724
|
||||||
|
- Apply GitLab UI button styles to HAML buttons app/views/projects/ci/builds. !43728 (Andrei Kyrnich @kyrnich)
|
||||||
|
- Log CarrierWave::IntegrityError without sending exception. !43750 (gaga5lala)
|
||||||
|
- Update node-sass from 4.12.0 to 4.14.1. !43808 (Takuya Noguchi)
|
||||||
|
- Replace in-repo SVGs with @gitlab/svgs in Cycle Analytics. !43823 (Takuya Noguchi)
|
||||||
|
- Add more issue change events to usage ping. !43828
|
||||||
|
- Limit postgres_indexes to owned schemas. !43834
|
||||||
|
- Add migration to validate design_management_designs.filename text limit constraint. !43952
|
||||||
|
- Enable track_unique_visits feature flag by default. !43989
|
||||||
|
- Update GitLab Workhorse to v8.49.0. !43999
|
||||||
|
- Rate limit documentation for non-configurable limits. !44003
|
||||||
|
- Fix spelling of PyPI. !44058 (Peter Bittner (@bittner))
|
||||||
|
- Apply gl-button class to projects/issues/export_csv directory. !44106 (Lakshit)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/sherlock/file_samples. !44109 (Lakshit)
|
||||||
|
- Remove temporary index for container scanning findings. !44131
|
||||||
|
- Update doc links in app. !44134
|
||||||
|
- Add undo helpers for change_column_type_concurrently and cleanup_concurrent_column_type_change. !44155
|
||||||
|
- Add darkmode support for merge conflict page. !44168
|
||||||
|
- Remove jquery tooltip API call from delete environment button. !44191
|
||||||
|
- Add gl-button class to app/views/projects/deployments. !44203 (Lakshit)
|
||||||
|
- Update Cycle Analytics with Value Stream Analytics in University. !44244 (Takuya Noguchi)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/invites directory. !44289 (Lakshit)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/admin/jobs directory. !44291 (Lakshit)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/projects/services/mattermost_slash_commands. !44293 (Lakshit)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/projects/commits directory. !44331 (Lakshit)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/shared/wikis directory. !44338 (Lakshit)
|
||||||
|
- Apply GitLab UI button styles to buttons in app/views/projects/compare directory. !44342 (Lakshit)
|
||||||
|
- Update buttons to use GitLab button class gl-button. !44361 (Gary Bell @garybell)
|
||||||
|
- Track issue time tracking events in usage ping. !44404
|
||||||
|
- Fix Rails/SaveBang offenses for spec files in spec/support/shared_example/*. !44424 (matthewbried)
|
||||||
|
- Bump mini_magick gem version. !44450
|
||||||
|
- Replace Font Awesome social icons with GitLab SVGs on user profile page. !44599
|
||||||
|
- Migrating deprecated buttons to GlButtons for modals that have not yet been migrated to the new GlModal component. !44611
|
||||||
|
- Add product analytics for group-level integrations. !44726
|
||||||
|
- Add migration helpers for copying check constraints. !44777
|
||||||
|
- Fix Rails/SaveBang offenses in spec/uploaders/* and spec/tasks/. !44820 (matthewbried)
|
||||||
|
- Remove d-md-none/d-sm-none when d-sm-none/d-none exists. !44845 (Takuya Noguchi)
|
||||||
|
- Remove duplicated BS display properties from Admin DevOps report' HAML. !44846 (Takuya Noguchi)
|
||||||
|
- Remove duplicated BS display properties from Commit's HAML. !44847 (Takuya Noguchi)
|
||||||
|
- Remove duplicated BS display properties from Diff's HAML. !44848 (Takuya Noguchi)
|
||||||
|
- Upgrade gitlab-shell to v13.8.0. !44852
|
||||||
|
- Bump kubeclient to 4.9.1 which includes ability to integrate Kubernetes clusters where their API url is on a sub-path. !44856
|
||||||
|
- Remove an outdated comment. !44861 (Robin Dupret)
|
||||||
|
- Migrate collapsed time tracking tooltip. !44874
|
||||||
|
- GitLab-managed apps: Use GitLab's repo as replacement for the Helm stable repo. !44875
|
||||||
|
- Fix Rails/SaveBang offenses in spec/support/*. !44884 (matthewbried)
|
||||||
|
- Track audit event searches via Snowplow. !44888
|
||||||
|
- Remove duplicated BS display property from Commit/Snippet's HAML. !44917 (Takuya Noguchi)
|
||||||
|
- Update the copy in the insert image modal to align with copy guidelines. !44949
|
||||||
|
- Fix Rails/SaveBang offenses in spec/services/projects/*. !44980 (matthewbried)
|
||||||
|
- Enable usage_data_api feature flag by default. !45004
|
||||||
|
- Copy profile route under - scope. !45045
|
||||||
|
- Replacing vue shared tooltip on calendar icon. !45059
|
||||||
|
- Remove duplicated BS display properties from Environments. !45167 (Takuya Noguchi)
|
||||||
|
- Remove duplicated BS display properties from Pipelines. !45171 (Takuya Noguchi)
|
||||||
|
- Populate blocking issues count. !45176
|
||||||
|
- Remove duplicated BS display properties from Issuables. !45177 (Takuya Noguchi)
|
||||||
|
- Migrate auto devops message from bootstrap. !45221
|
||||||
|
- Update Rouge to v3.24. !45225
|
||||||
|
- Update GitLab Workhorse to v8.51.0. !45256
|
||||||
|
- Migrate blocked_by issue links to blocks type by swapping source and target. !45262
|
||||||
|
- Fix documentation link, spacing, and error handling in alert integrations list. !45304
|
||||||
|
- Replace tooltip with GLTooltip in epic sidebar datepicker. !45392
|
||||||
|
- Bump cluster applications CI template. !45472
|
||||||
|
|
||||||
|
|
||||||
## 13.4.4 (2020-10-15)
|
## 13.4.4 (2020-10-15)
|
||||||
|
|
||||||
### Fixed (2 changes)
|
### Fixed (2 changes)
|
||||||
|
@ -65,42 +658,6 @@ entry.
|
||||||
- Fix large backups not working with Azure Blob storage. !44233
|
- Fix large backups not working with Azure Blob storage. !44233
|
||||||
|
|
||||||
|
|
||||||
## 13.4.2 (2020-10-01)
|
|
||||||
|
|
||||||
### Security (14 changes)
|
|
||||||
|
|
||||||
- Do not store session id in Redis.
|
|
||||||
- Fix permission checks when updating confidentiality and milestone on issues or merge requests.
|
|
||||||
- Purge unaccepted member invitations older than 90 days.
|
|
||||||
- Adds feature flags plan limits.
|
|
||||||
- Prevent SVG XSS via Web IDE.
|
|
||||||
- Ensure user has no solo owned groups before triggering account deletion.
|
|
||||||
- Security fix safe params helper.
|
|
||||||
- Do not bypass admin mode when authenticated with deploy token.
|
|
||||||
- Fixes release asset link filepath ReDoS.
|
|
||||||
- Ensure global ID is of Annotation type in GraphQL destroy mutation.
|
|
||||||
- Validate that membership expiry dates are not in the past.
|
|
||||||
- Rate limit adding new email and re-sending email confirmation.
|
|
||||||
- Fix redaction of confidential Todos.
|
|
||||||
- Update GitLab Runner Helm Chart to 0.20.2.
|
|
||||||
|
|
||||||
|
|
||||||
## 13.4.1 (2020-09-24)
|
|
||||||
|
|
||||||
### Fixed (2 changes)
|
|
||||||
|
|
||||||
- Revert required encryption on CI runner tokens. !42623
|
|
||||||
- Allow Unleash clients to request feature flags when repository is private. !43059
|
|
||||||
|
|
||||||
### Added (1 change)
|
|
||||||
|
|
||||||
- Add missing fontawesome file icon classes. !43091
|
|
||||||
|
|
||||||
### Other (1 change)
|
|
||||||
|
|
||||||
- Notifications icon: Render empty string for custom setting. !42848
|
|
||||||
|
|
||||||
|
|
||||||
## 13.4.0 (2020-09-22)
|
## 13.4.0 (2020-09-22)
|
||||||
|
|
||||||
### Security (2 changes, 1 of them is from the community)
|
### Security (2 changes, 1 of them is from the community)
|
||||||
|
@ -1325,6 +1882,26 @@ entry.
|
||||||
- Replace fa-pencil icon with GitLab SVG. !39648
|
- Replace fa-pencil icon with GitLab SVG. !39648
|
||||||
|
|
||||||
|
|
||||||
|
## 13.2.10 (2020-10-01)
|
||||||
|
|
||||||
|
### Security (14 changes)
|
||||||
|
|
||||||
|
- Do not store session id in Redis.
|
||||||
|
- Fix permission checks when updating confidentiality and milestone on issues or merge requests.
|
||||||
|
- Purge unaccepted member invitations older than 90 days.
|
||||||
|
- Adds feature flags plan limits.
|
||||||
|
- Prevent SVG XSS via Web IDE.
|
||||||
|
- Ensure user has no solo owned groups before triggering account deletion.
|
||||||
|
- Security fix safe params helper.
|
||||||
|
- Do not bypass admin mode when authenticated with deploy token.
|
||||||
|
- Fixes release asset link filepath ReDoS.
|
||||||
|
- Ensure global ID is of Annotation type in GraphQL destroy mutation.
|
||||||
|
- Validate that membership expiry dates are not in the past.
|
||||||
|
- Rate limit adding new email and re-sending email confirmation.
|
||||||
|
- Fix redaction of confidential Todos.
|
||||||
|
- Update GitLab Runner Helm Chart to 0.19.4.
|
||||||
|
|
||||||
|
|
||||||
## 13.2.8 (2020-09-02)
|
## 13.2.8 (2020-09-02)
|
||||||
|
|
||||||
### Security (1 change)
|
### Security (1 change)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
13.4.7
|
13.5.5
|
|
@ -1 +1 @@
|
||||||
0.0.5
|
0.0.6
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.25.0
|
1.28.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
13.7.0
|
13.11.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
8.46.0
|
8.51.0
|
||||||
|
|
46
Gemfile
46
Gemfile
|
@ -19,13 +19,15 @@ 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.3'
|
gem 'grape-path-helpers', '~> 1.4'
|
||||||
|
|
||||||
gem 'faraday', '~> 1.0'
|
gem 'faraday', '~> 1.0'
|
||||||
gem 'marginalia', '~> 1.9.0'
|
gem 'marginalia', '~> 1.9.0'
|
||||||
|
|
||||||
# Authentication libraries
|
# Authentication libraries
|
||||||
gem 'devise', '~> 4.6'
|
gem 'devise', '~> 4.7.2'
|
||||||
|
# TODO: verify ARM compile issue on 3.1.13+ version (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18828)
|
||||||
|
gem 'bcrypt', '3.1.12'
|
||||||
gem 'doorkeeper', '~> 5.3.0'
|
gem 'doorkeeper', '~> 5.3.0'
|
||||||
gem 'doorkeeper-openid_connect', '~> 1.7.4'
|
gem 'doorkeeper-openid_connect', '~> 1.7.4'
|
||||||
gem 'omniauth', '~> 1.8'
|
gem 'omniauth', '~> 1.8'
|
||||||
|
@ -97,6 +99,7 @@ gem 'graphiql-rails', '~> 1.4.10'
|
||||||
gem 'apollo_upload_server', '~> 2.0.2'
|
gem 'apollo_upload_server', '~> 2.0.2'
|
||||||
gem 'graphql-docs', '~> 1.6.0', group: [:development, :test]
|
gem 'graphql-docs', '~> 1.6.0', group: [:development, :test]
|
||||||
|
|
||||||
|
gem 'hashie'
|
||||||
# Disable strong_params so that Mash does not respond to :permitted?
|
# Disable strong_params so that Mash does not respond to :permitted?
|
||||||
gem 'hashie-forbidden_attributes'
|
gem 'hashie-forbidden_attributes'
|
||||||
|
|
||||||
|
@ -108,7 +111,7 @@ gem 'hamlit', '~> 2.11.0'
|
||||||
|
|
||||||
# Files attachments
|
# Files attachments
|
||||||
gem 'carrierwave', '~> 1.3'
|
gem 'carrierwave', '~> 1.3'
|
||||||
gem 'mini_magick'
|
gem 'mini_magick', '~> 4.10.1'
|
||||||
|
|
||||||
# for backups
|
# for backups
|
||||||
gem 'fog-aws', '~> 3.5'
|
gem 'fog-aws', '~> 3.5'
|
||||||
|
@ -155,7 +158,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.21.0'
|
gem 'rouge', '~> 3.24.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'
|
||||||
|
@ -169,7 +172,7 @@ gem 'diffy', '~> 3.3'
|
||||||
gem 'diff_match_patch', '~> 0.1.0'
|
gem 'diff_match_patch', '~> 0.1.0'
|
||||||
|
|
||||||
# Application server
|
# Application server
|
||||||
gem 'rack', '~> 2.0.9'
|
gem 'rack', '~> 2.1.4'
|
||||||
# https://github.com/sharpstone/rack-timeout/blob/master/README.md#rails-apps-manually
|
# https://github.com/sharpstone/rack-timeout/blob/master/README.md#rails-apps-manually
|
||||||
gem 'rack-timeout', '~> 0.5.1', require: 'rack/timeout/base'
|
gem 'rack-timeout', '~> 0.5.1', require: 'rack/timeout/base'
|
||||||
|
|
||||||
|
@ -244,7 +247,7 @@ gem 'atlassian-jwt', '~> 0.2.0'
|
||||||
gem 'flowdock', '~> 0.7'
|
gem 'flowdock', '~> 0.7'
|
||||||
|
|
||||||
# Slack integration
|
# Slack integration
|
||||||
gem 'slack-messenger', '~> 2.3.3'
|
gem 'slack-messenger', '~> 2.3.4'
|
||||||
|
|
||||||
# Hangouts Chat integration
|
# Hangouts Chat integration
|
||||||
gem 'hangouts-chat', '~> 0.0.5'
|
gem 'hangouts-chat', '~> 0.0.5'
|
||||||
|
@ -256,7 +259,7 @@ gem 'asana', '0.10.2'
|
||||||
gem 'ruby-fogbugz', '~> 0.2.1'
|
gem 'ruby-fogbugz', '~> 0.2.1'
|
||||||
|
|
||||||
# Kubernetes integration
|
# Kubernetes integration
|
||||||
gem 'kubeclient', '~> 4.6.0'
|
gem 'kubeclient', '~> 4.9.1'
|
||||||
|
|
||||||
# Sanitize user input
|
# Sanitize user input
|
||||||
gem 'sanitize', '~> 5.2.1'
|
gem 'sanitize', '~> 5.2.1'
|
||||||
|
@ -272,7 +275,7 @@ gem 'licensee', '~> 8.9'
|
||||||
gem 'ace-rails-ap', '~> 4.1.0'
|
gem 'ace-rails-ap', '~> 4.1.0'
|
||||||
|
|
||||||
# Detect and convert string character encoding
|
# Detect and convert string character encoding
|
||||||
gem 'charlock_holmes', '~> 0.7.5'
|
gem 'charlock_holmes', '~> 0.7.7'
|
||||||
|
|
||||||
# Detect mime content type from content
|
# Detect mime content type from content
|
||||||
gem 'mimemagic', '~> 0.3.2'
|
gem 'mimemagic', '~> 0.3.2'
|
||||||
|
@ -284,11 +287,10 @@ gem 'fast_blank'
|
||||||
gem 'gitlab-chronic', '~> 0.10.5'
|
gem 'gitlab-chronic', '~> 0.10.5'
|
||||||
gem 'gitlab_chronic_duration', '~> 0.10.6.2'
|
gem 'gitlab_chronic_duration', '~> 0.10.6.2'
|
||||||
|
|
||||||
gem 'webpack-rails', '~> 0.9.10'
|
|
||||||
gem 'rack-proxy', '~> 0.6.0'
|
gem 'rack-proxy', '~> 0.6.0'
|
||||||
|
|
||||||
gem 'sassc-rails', '~> 2.1.0'
|
gem 'sassc-rails', '~> 2.1.0'
|
||||||
gem 'uglifier', '~> 2.7.2'
|
gem 'terser', '1.0.2'
|
||||||
|
|
||||||
gem 'addressable', '~> 2.7'
|
gem 'addressable', '~> 2.7'
|
||||||
gem 'font-awesome-rails', '~> 4.7'
|
gem 'font-awesome-rails', '~> 4.7'
|
||||||
|
@ -308,7 +310,7 @@ gem 'sentry-raven', '~> 3.0'
|
||||||
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.1'
|
gem 'gitlab-labkit', '0.12.2'
|
||||||
|
|
||||||
# I18n
|
# I18n
|
||||||
gem 'ruby_parser', '~> 3.8', require: false
|
gem 'ruby_parser', '~> 3.8', require: false
|
||||||
|
@ -330,13 +332,13 @@ group :metrics do
|
||||||
gem 'method_source', '~> 1.0', require: false
|
gem 'method_source', '~> 1.0', require: false
|
||||||
|
|
||||||
# Prometheus
|
# Prometheus
|
||||||
gem 'prometheus-client-mmap', '~> 0.11.0'
|
gem 'prometheus-client-mmap', '~> 0.12.0'
|
||||||
gem 'raindrops', '~> 0.18'
|
gem 'raindrops', '~> 0.18'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'brakeman', '~> 4.2', require: false
|
gem 'brakeman', '~> 4.2', require: false
|
||||||
gem 'danger', '~> 8.0', require: false
|
gem 'danger', '~> 8.0.6', require: false
|
||||||
|
|
||||||
gem 'letter_opener_web', '~> 1.3.4'
|
gem 'letter_opener_web', '~> 1.3.4'
|
||||||
|
|
||||||
|
@ -375,8 +377,6 @@ 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-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
|
||||||
|
@ -394,9 +394,14 @@ group :development, :test do
|
||||||
gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false
|
gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
group :development, :test, :coverage do
|
||||||
|
gem 'simplecov', '~> 0.18.5', require: false
|
||||||
|
gem 'simplecov-cobertura', '~> 1.3.1', require: false
|
||||||
|
end
|
||||||
|
|
||||||
# Gems required in omnibus-gitlab pipeline
|
# Gems required in omnibus-gitlab pipeline
|
||||||
group :development, :test, :omnibus do
|
group :development, :test, :omnibus do
|
||||||
gem 'license_finder', '~> 5.4', require: false
|
gem 'license_finder', '~> 6.0', require: false
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
@ -411,7 +416,7 @@ group :test do
|
||||||
|
|
||||||
gem 'shoulda-matchers', '~> 4.0.1', require: false
|
gem 'shoulda-matchers', '~> 4.0.1', require: false
|
||||||
gem 'email_spec', '~> 2.2.0'
|
gem 'email_spec', '~> 2.2.0'
|
||||||
gem 'webmock', '~> 3.5.1'
|
gem 'webmock', '~> 3.9.1'
|
||||||
gem 'rails-controller-testing'
|
gem 'rails-controller-testing'
|
||||||
gem 'concurrent-ruby', '~> 1.1'
|
gem 'concurrent-ruby', '~> 1.1'
|
||||||
gem 'test-prof', '~> 0.12.0'
|
gem 'test-prof', '~> 0.12.0'
|
||||||
|
@ -425,7 +430,7 @@ end
|
||||||
gem 'octokit', '~> 4.15'
|
gem 'octokit', '~> 4.15'
|
||||||
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/issues/207207
|
# https://gitlab.com/gitlab-org/gitlab/issues/207207
|
||||||
gem 'gitlab-mail_room', '~> 0.0.6', require: 'mail_room'
|
gem 'gitlab-mail_room', '~> 0.0.7', require: 'mail_room'
|
||||||
|
|
||||||
gem 'email_reply_trimmer', '~> 0.1'
|
gem 'email_reply_trimmer', '~> 0.1'
|
||||||
gem 'html2text'
|
gem 'html2text'
|
||||||
|
@ -461,7 +466,7 @@ group :ed25519 do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gitaly GRPC protocol definitions
|
# Gitaly GRPC protocol definitions
|
||||||
gem 'gitaly', '~> 13.3.0-rc1'
|
gem 'gitaly', '~> 13.5.0-rc2'
|
||||||
|
|
||||||
gem 'grpc', '~> 1.30.2'
|
gem 'grpc', '~> 1.30.2'
|
||||||
|
|
||||||
|
@ -512,3 +517,6 @@ gem 'multi_json', '~> 1.14.1'
|
||||||
gem 'yajl-ruby', '~> 1.4.1', require: 'yajl'
|
gem 'yajl-ruby', '~> 1.4.1', require: 'yajl'
|
||||||
|
|
||||||
gem 'webauthn', '~> 2.3'
|
gem 'webauthn', '~> 2.3'
|
||||||
|
|
||||||
|
# IPAddress utilities
|
||||||
|
gem 'ipaddress', '~> 0.8.3'
|
||||||
|
|
230
Gemfile.lock
230
Gemfile.lock
|
@ -6,59 +6,59 @@ GEM
|
||||||
ace-rails-ap (4.1.2)
|
ace-rails-ap (4.1.2)
|
||||||
acme-client (2.0.6)
|
acme-client (2.0.6)
|
||||||
faraday (>= 0.17, < 2.0.0)
|
faraday (>= 0.17, < 2.0.0)
|
||||||
actioncable (6.0.3.1)
|
actioncable (6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (6.0.3.1)
|
actionmailbox (6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
activejob (= 6.0.3.1)
|
activejob (= 6.0.3.3)
|
||||||
activerecord (= 6.0.3.1)
|
activerecord (= 6.0.3.3)
|
||||||
activestorage (= 6.0.3.1)
|
activestorage (= 6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
actionmailer (6.0.3.1)
|
actionmailer (6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
actionview (= 6.0.3.1)
|
actionview (= 6.0.3.3)
|
||||||
activejob (= 6.0.3.1)
|
activejob (= 6.0.3.3)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (6.0.3.1)
|
actionpack (6.0.3.3)
|
||||||
actionview (= 6.0.3.1)
|
actionview (= 6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
rack (~> 2.0, >= 2.0.8)
|
rack (~> 2.0, >= 2.0.8)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actiontext (6.0.3.1)
|
actiontext (6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
activerecord (= 6.0.3.1)
|
activerecord (= 6.0.3.3)
|
||||||
activestorage (= 6.0.3.1)
|
activestorage (= 6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (6.0.3.1)
|
actionview (6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||||
activejob (6.0.3.1)
|
activejob (6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (6.0.3.1)
|
activemodel (6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
activerecord (6.0.3.1)
|
activerecord (6.0.3.3)
|
||||||
activemodel (= 6.0.3.1)
|
activemodel (= 6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
activerecord-explain-analyze (0.1.0)
|
activerecord-explain-analyze (0.1.0)
|
||||||
activerecord (>= 4)
|
activerecord (>= 4)
|
||||||
pg
|
pg
|
||||||
activestorage (6.0.3.1)
|
activestorage (6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
activejob (= 6.0.3.1)
|
activejob (= 6.0.3.3)
|
||||||
activerecord (= 6.0.3.1)
|
activerecord (= 6.0.3.3)
|
||||||
marcel (~> 0.3.1)
|
marcel (~> 0.3.1)
|
||||||
activesupport (6.0.3.1)
|
activesupport (6.0.3.3)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
|
@ -167,7 +167,7 @@ GEM
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
cbor (0.5.9.6)
|
cbor (0.5.9.6)
|
||||||
character_set (1.4.0)
|
character_set (1.4.0)
|
||||||
charlock_holmes (0.7.6)
|
charlock_holmes (0.7.7)
|
||||||
childprocess (3.0.0)
|
childprocess (3.0.0)
|
||||||
chunky_png (1.3.5)
|
chunky_png (1.3.5)
|
||||||
citrus (3.0.2)
|
citrus (3.0.2)
|
||||||
|
@ -183,7 +183,7 @@ GEM
|
||||||
concord (0.1.5)
|
concord (0.1.5)
|
||||||
adamantium (~> 0.2.0)
|
adamantium (~> 0.2.0)
|
||||||
equalizer (~> 0.0.9)
|
equalizer (~> 0.0.9)
|
||||||
concurrent-ruby (1.1.6)
|
concurrent-ruby (1.1.7)
|
||||||
connection_pool (2.2.2)
|
connection_pool (2.2.2)
|
||||||
contracts (0.11.0)
|
contracts (0.11.0)
|
||||||
cork (0.3.0)
|
cork (0.3.0)
|
||||||
|
@ -202,7 +202,7 @@ GEM
|
||||||
css_parser (1.7.0)
|
css_parser (1.7.0)
|
||||||
addressable
|
addressable
|
||||||
daemons (1.2.6)
|
daemons (1.2.6)
|
||||||
danger (8.0.5)
|
danger (8.0.6)
|
||||||
claide (~> 1.0)
|
claide (~> 1.0)
|
||||||
claide-plugins (>= 0.9.2)
|
claide-plugins (>= 0.9.2)
|
||||||
colored2 (~> 3.1)
|
colored2 (~> 3.1)
|
||||||
|
@ -235,7 +235,7 @@ GEM
|
||||||
thor (>= 0.19, < 2)
|
thor (>= 0.19, < 2)
|
||||||
unicode_plot (>= 0.0.4, < 1.0.0)
|
unicode_plot (>= 0.0.4, < 1.0.0)
|
||||||
device_detector (1.0.0)
|
device_detector (1.0.0)
|
||||||
devise (4.7.1)
|
devise (4.7.3)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0)
|
railties (>= 4.1.0)
|
||||||
|
@ -253,7 +253,7 @@ GEM
|
||||||
discordrb-webhooks-blackst0ne (3.3.0)
|
discordrb-webhooks-blackst0ne (3.3.0)
|
||||||
rest-client (~> 2.0)
|
rest-client (~> 2.0)
|
||||||
docile (1.3.2)
|
docile (1.3.2)
|
||||||
domain_name (0.5.20180417)
|
domain_name (0.5.20190701)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
doorkeeper (5.3.3)
|
doorkeeper (5.3.3)
|
||||||
railties (>= 5)
|
railties (>= 5)
|
||||||
|
@ -312,7 +312,7 @@ GEM
|
||||||
tzinfo
|
tzinfo
|
||||||
eventmachine (1.2.7)
|
eventmachine (1.2.7)
|
||||||
excon (0.71.1)
|
excon (0.71.1)
|
||||||
execjs (2.6.0)
|
execjs (2.7.0)
|
||||||
expression_parser (0.9.0)
|
expression_parser (0.9.0)
|
||||||
extended-markdown-filter (0.6.0)
|
extended-markdown-filter (0.6.0)
|
||||||
html-pipeline (~> 2.0)
|
html-pipeline (~> 2.0)
|
||||||
|
@ -416,7 +416,7 @@ GEM
|
||||||
rails (>= 3.2.0)
|
rails (>= 3.2.0)
|
||||||
git (1.7.0)
|
git (1.7.0)
|
||||||
rchardet (~> 1.8)
|
rchardet (~> 1.8)
|
||||||
gitaly (13.3.0.pre.rc2)
|
gitaly (13.5.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)
|
||||||
|
@ -428,7 +428,7 @@ GEM
|
||||||
fog-json (~> 1.2.0)
|
fog-json (~> 1.2.0)
|
||||||
mime-types
|
mime-types
|
||||||
ms_rest_azure (~> 0.12.0)
|
ms_rest_azure (~> 0.12.0)
|
||||||
gitlab-labkit (0.12.1)
|
gitlab-labkit (0.12.2)
|
||||||
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)
|
||||||
|
@ -436,7 +436,7 @@ GEM
|
||||||
opentracing (~> 0.4)
|
opentracing (~> 0.4)
|
||||||
redis (> 3.0.0, < 5.0.0)
|
redis (> 3.0.0, < 5.0.0)
|
||||||
gitlab-license (1.0.0)
|
gitlab-license (1.0.0)
|
||||||
gitlab-mail_room (0.0.6)
|
gitlab-mail_room (0.0.7)
|
||||||
gitlab-markup (1.7.1)
|
gitlab-markup (1.7.1)
|
||||||
gitlab-net-dns (0.9.1)
|
gitlab-net-dns (0.9.1)
|
||||||
gitlab-puma (4.3.5.gitlab.3)
|
gitlab-puma (4.3.5.gitlab.3)
|
||||||
|
@ -495,7 +495,7 @@ GEM
|
||||||
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.3.0)
|
grape-path-helpers (1.4.0)
|
||||||
activesupport
|
activesupport
|
||||||
grape (~> 1.3)
|
grape (~> 1.3)
|
||||||
rake (~> 12)
|
rake (~> 12)
|
||||||
|
@ -547,7 +547,7 @@ GEM
|
||||||
tilt
|
tilt
|
||||||
hana (1.3.6)
|
hana (1.3.6)
|
||||||
hangouts-chat (0.0.5)
|
hangouts-chat (0.0.5)
|
||||||
hashdiff (0.3.8)
|
hashdiff (1.0.1)
|
||||||
hashie (3.6.0)
|
hashie (3.6.0)
|
||||||
hashie-forbidden_attributes (0.1.1)
|
hashie-forbidden_attributes (0.1.1)
|
||||||
hashie (>= 3.0)
|
hashie (>= 3.0)
|
||||||
|
@ -563,21 +563,22 @@ GEM
|
||||||
html2text (0.2.0)
|
html2text (0.2.0)
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
http (4.2.0)
|
http (4.4.1)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
http-cookie (~> 1.0)
|
http-cookie (~> 1.0)
|
||||||
http-form_data (~> 2.0)
|
http-form_data (~> 2.2)
|
||||||
http-parser (~> 1.2.0)
|
http-parser (~> 1.2.0)
|
||||||
|
http-accept (1.7.0)
|
||||||
http-cookie (1.0.3)
|
http-cookie (1.0.3)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http-form_data (2.1.1)
|
http-form_data (2.3.0)
|
||||||
http-parser (1.2.1)
|
http-parser (1.2.1)
|
||||||
ffi-compiler (>= 1.0, < 2.0)
|
ffi-compiler (>= 1.0, < 2.0)
|
||||||
httparty (0.16.4)
|
httparty (0.16.4)
|
||||||
mime-types (~> 3.0)
|
mime-types (~> 3.0)
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (1.8.3)
|
i18n (1.8.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
i18n_data (0.8.0)
|
i18n_data (0.8.0)
|
||||||
icalendar (2.4.1)
|
icalendar (2.4.1)
|
||||||
|
@ -611,6 +612,9 @@ GEM
|
||||||
hana (~> 1.3)
|
hana (~> 1.3)
|
||||||
regexp_parser (~> 1.5)
|
regexp_parser (~> 1.5)
|
||||||
uri_template (~> 0.7)
|
uri_template (~> 0.7)
|
||||||
|
jsonpath (1.0.5)
|
||||||
|
multi_json
|
||||||
|
to_regexp (~> 0.2.1)
|
||||||
jwt (2.1.0)
|
jwt (2.1.0)
|
||||||
kaminari (1.2.1)
|
kaminari (1.2.1)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
|
@ -631,9 +635,10 @@ GEM
|
||||||
rexml
|
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.9.1)
|
||||||
http (>= 3.0, < 5.0)
|
http (>= 3.0, < 5.0)
|
||||||
recursive-open-struct (~> 1.0, >= 1.0.4)
|
jsonpath (~> 1.0)
|
||||||
|
recursive-open-struct (~> 1.1, >= 1.1.1)
|
||||||
rest-client (~> 2.0)
|
rest-client (~> 2.0)
|
||||||
launchy (2.4.3)
|
launchy (2.4.3)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
|
@ -643,9 +648,9 @@ GEM
|
||||||
actionmailer (>= 3.2)
|
actionmailer (>= 3.2)
|
||||||
letter_opener (~> 1.0)
|
letter_opener (~> 1.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
license_finder (5.4.0)
|
license_finder (6.0.0)
|
||||||
bundler
|
bundler
|
||||||
rubyzip
|
rubyzip (>= 1, < 3)
|
||||||
thor
|
thor
|
||||||
toml (= 0.2.0)
|
toml (= 0.2.0)
|
||||||
with_env (= 1.1.0)
|
with_env (= 1.1.0)
|
||||||
|
@ -662,7 +667,7 @@ GEM
|
||||||
activesupport (>= 4)
|
activesupport (>= 4)
|
||||||
railties (>= 4)
|
railties (>= 4)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
loofah (2.5.0)
|
loofah (2.7.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
lru_redux (1.1.0)
|
lru_redux (1.1.0)
|
||||||
|
@ -684,7 +689,7 @@ GEM
|
||||||
mime-types-data (3.2020.0512)
|
mime-types-data (3.2020.0512)
|
||||||
mimemagic (0.3.5)
|
mimemagic (0.3.5)
|
||||||
mini_histogram (0.1.3)
|
mini_histogram (0.1.3)
|
||||||
mini_magick (4.9.5)
|
mini_magick (4.10.1)
|
||||||
mini_mime (1.0.2)
|
mini_mime (1.0.2)
|
||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
minitest (5.11.3)
|
minitest (5.11.3)
|
||||||
|
@ -713,7 +718,7 @@ GEM
|
||||||
net-ntp (2.1.3)
|
net-ntp (2.1.3)
|
||||||
net-ssh (6.0.0)
|
net-ssh (6.0.0)
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
nio4r (2.5.2)
|
nio4r (2.5.4)
|
||||||
no_proxy_fix (0.1.2)
|
no_proxy_fix (0.1.2)
|
||||||
nokogiri (1.10.10)
|
nokogiri (1.10.10)
|
||||||
mini_portile2 (~> 2.4.0)
|
mini_portile2 (~> 2.4.0)
|
||||||
|
@ -838,7 +843,7 @@ GEM
|
||||||
parser
|
parser
|
||||||
unparser
|
unparser
|
||||||
procto (0.0.3)
|
procto (0.0.3)
|
||||||
prometheus-client-mmap (0.11.0)
|
prometheus-client-mmap (0.12.0)
|
||||||
pry (0.13.1)
|
pry (0.13.1)
|
||||||
coderay (~> 1.1)
|
coderay (~> 1.1)
|
||||||
method_source (~> 1.0)
|
method_source (~> 1.0)
|
||||||
|
@ -847,10 +852,10 @@ GEM
|
||||||
pry (~> 0.13.0)
|
pry (~> 0.13.0)
|
||||||
pry-rails (0.3.9)
|
pry-rails (0.3.9)
|
||||||
pry (>= 0.10.4)
|
pry (>= 0.10.4)
|
||||||
public_suffix (4.0.3)
|
public_suffix (4.0.6)
|
||||||
pyu-ruby-sasl (0.0.3.3)
|
pyu-ruby-sasl (0.0.3.3)
|
||||||
raabro (1.1.6)
|
raabro (1.1.6)
|
||||||
rack (2.0.9)
|
rack (2.1.4)
|
||||||
rack-accept (0.4.5)
|
rack-accept (0.4.5)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
rack-attack (6.3.0)
|
rack-attack (6.3.0)
|
||||||
|
@ -870,25 +875,25 @@ GEM
|
||||||
rack-test (1.1.0)
|
rack-test (1.1.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rack-timeout (0.5.2)
|
rack-timeout (0.5.2)
|
||||||
rails (6.0.3.1)
|
rails (6.0.3.3)
|
||||||
actioncable (= 6.0.3.1)
|
actioncable (= 6.0.3.3)
|
||||||
actionmailbox (= 6.0.3.1)
|
actionmailbox (= 6.0.3.3)
|
||||||
actionmailer (= 6.0.3.1)
|
actionmailer (= 6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
actiontext (= 6.0.3.1)
|
actiontext (= 6.0.3.3)
|
||||||
actionview (= 6.0.3.1)
|
actionview (= 6.0.3.3)
|
||||||
activejob (= 6.0.3.1)
|
activejob (= 6.0.3.3)
|
||||||
activemodel (= 6.0.3.1)
|
activemodel (= 6.0.3.3)
|
||||||
activerecord (= 6.0.3.1)
|
activerecord (= 6.0.3.3)
|
||||||
activestorage (= 6.0.3.1)
|
activestorage (= 6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
bundler (>= 1.3.0)
|
bundler (>= 1.3.0)
|
||||||
railties (= 6.0.3.1)
|
railties (= 6.0.3.3)
|
||||||
sprockets-rails (>= 2.0.0)
|
sprockets-rails (>= 2.0.0)
|
||||||
rails-controller-testing (1.0.4)
|
rails-controller-testing (1.0.5)
|
||||||
actionpack (>= 5.0.1.x)
|
actionpack (>= 5.0.1.rc1)
|
||||||
actionview (>= 5.0.1.x)
|
actionview (>= 5.0.1.rc1)
|
||||||
activesupport (>= 5.0.1.x)
|
activesupport (>= 5.0.1.rc1)
|
||||||
rails-dom-testing (2.0.3)
|
rails-dom-testing (2.0.3)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
|
@ -897,9 +902,9 @@ GEM
|
||||||
rails-i18n (6.0.0)
|
rails-i18n (6.0.0)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 7)
|
railties (>= 6.0.0, < 7)
|
||||||
railties (6.0.3.1)
|
railties (6.0.3.3)
|
||||||
actionpack (= 6.0.3.1)
|
actionpack (= 6.0.3.3)
|
||||||
activesupport (= 6.0.3.1)
|
activesupport (= 6.0.3.3)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.20.3, < 2.0)
|
thor (>= 0.20.3, < 2.0)
|
||||||
|
@ -920,7 +925,7 @@ GEM
|
||||||
re2 (1.2.0)
|
re2 (1.2.0)
|
||||||
recaptcha (4.13.1)
|
recaptcha (4.13.1)
|
||||||
json
|
json
|
||||||
recursive-open-struct (1.1.1)
|
recursive-open-struct (1.1.2)
|
||||||
redis (4.1.3)
|
redis (4.1.3)
|
||||||
redis-actionpack (5.2.0)
|
redis-actionpack (5.2.0)
|
||||||
actionpack (>= 5, < 7)
|
actionpack (>= 5, < 7)
|
||||||
|
@ -951,7 +956,8 @@ GEM
|
||||||
responders (3.0.0)
|
responders (3.0.0)
|
||||||
actionpack (>= 5.0)
|
actionpack (>= 5.0)
|
||||||
railties (>= 5.0)
|
railties (>= 5.0)
|
||||||
rest-client (2.0.2)
|
rest-client (2.1.0)
|
||||||
|
http-accept (>= 1.7.0, < 2.0)
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
mime-types (>= 1.16, < 4.0)
|
mime-types (>= 1.16, < 4.0)
|
||||||
netrc (~> 0.8)
|
netrc (~> 0.8)
|
||||||
|
@ -959,7 +965,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.21.0)
|
rouge (3.24.0)
|
||||||
rqrcode (0.7.0)
|
rqrcode (0.7.0)
|
||||||
chunky_png
|
chunky_png
|
||||||
rqrcode-rails3 (0.1.7)
|
rqrcode-rails3 (0.1.7)
|
||||||
|
@ -1065,7 +1071,7 @@ GEM
|
||||||
seed-fu (2.3.7)
|
seed-fu (2.3.7)
|
||||||
activerecord (>= 3.1)
|
activerecord (>= 3.1)
|
||||||
activesupport (>= 3.1)
|
activesupport (>= 3.1)
|
||||||
selenium-webdriver (3.142.6)
|
selenium-webdriver (3.142.7)
|
||||||
childprocess (>= 0.5, < 4.0)
|
childprocess (>= 0.5, < 4.0)
|
||||||
rubyzip (>= 1.2.2)
|
rubyzip (>= 1.2.2)
|
||||||
sentry-raven (3.0.4)
|
sentry-raven (3.0.4)
|
||||||
|
@ -1096,7 +1102,7 @@ GEM
|
||||||
simplecov (~> 0.8)
|
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.4)
|
||||||
snowplow-tracker (0.6.1)
|
snowplow-tracker (0.6.1)
|
||||||
contracts (~> 0.7, <= 0.11)
|
contracts (~> 0.7, <= 0.11)
|
||||||
spring (2.0.2)
|
spring (2.0.2)
|
||||||
|
@ -1106,7 +1112,7 @@ GEM
|
||||||
sprockets (3.7.2)
|
sprockets (3.7.2)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
rack (> 1, < 3)
|
rack (> 1, < 3)
|
||||||
sprockets-rails (3.2.1)
|
sprockets-rails (3.2.2)
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
|
@ -1130,6 +1136,8 @@ GEM
|
||||||
temple (0.8.2)
|
temple (0.8.2)
|
||||||
terminal-table (1.8.0)
|
terminal-table (1.8.0)
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||||
|
terser (1.0.2)
|
||||||
|
execjs (>= 0.3.0, < 3)
|
||||||
test-prof (0.12.0)
|
test-prof (0.12.0)
|
||||||
text (1.3.1)
|
text (1.3.1)
|
||||||
thin (1.7.2)
|
thin (1.7.2)
|
||||||
|
@ -1143,6 +1151,7 @@ GEM
|
||||||
timecop (0.9.1)
|
timecop (0.9.1)
|
||||||
timeliness (0.3.10)
|
timeliness (0.3.10)
|
||||||
timfel-krb5-auth (0.8.3)
|
timfel-krb5-auth (0.8.3)
|
||||||
|
to_regexp (0.2.1)
|
||||||
toml (0.2.0)
|
toml (0.2.0)
|
||||||
parslet (~> 1.8.0)
|
parslet (~> 1.8.0)
|
||||||
toml-rb (1.0.0)
|
toml-rb (1.0.0)
|
||||||
|
@ -1157,12 +1166,9 @@ GEM
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
u2f (0.2.1)
|
u2f (0.2.1)
|
||||||
uber (0.1.0)
|
uber (0.1.0)
|
||||||
uglifier (2.7.2)
|
|
||||||
execjs (>= 0.3.0)
|
|
||||||
json (>= 1.8.0)
|
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.5)
|
unf_ext (0.0.7.7)
|
||||||
unicode-display_width (1.7.0)
|
unicode-display_width (1.7.0)
|
||||||
unicode_plot (0.0.4)
|
unicode_plot (0.0.4)
|
||||||
enumerable-statistics (>= 2.0.1)
|
enumerable-statistics (>= 2.0.1)
|
||||||
|
@ -1214,13 +1220,11 @@ GEM
|
||||||
webfinger (1.1.0)
|
webfinger (1.1.0)
|
||||||
activesupport
|
activesupport
|
||||||
httpclient (>= 2.4)
|
httpclient (>= 2.4)
|
||||||
webmock (3.5.1)
|
webmock (3.9.1)
|
||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
hashdiff
|
hashdiff (>= 0.4.0, < 2.0.0)
|
||||||
webpack-rails (0.9.11)
|
websocket-driver (0.7.3)
|
||||||
railties (>= 3.2.0)
|
|
||||||
websocket-driver (0.7.1)
|
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
wikicloth (0.8.1)
|
wikicloth (0.8.1)
|
||||||
|
@ -1232,7 +1236,7 @@ GEM
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
yajl-ruby (1.4.1)
|
yajl-ruby (1.4.1)
|
||||||
zeitwerk (2.3.0)
|
zeitwerk (2.4.0)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
@ -1259,6 +1263,7 @@ DEPENDENCIES
|
||||||
babosa (~> 1.0.2)
|
babosa (~> 1.0.2)
|
||||||
base32 (~> 0.3.0)
|
base32 (~> 0.3.0)
|
||||||
batch-loader (~> 1.4.0)
|
batch-loader (~> 1.4.0)
|
||||||
|
bcrypt (= 3.1.12)
|
||||||
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)
|
||||||
|
@ -1272,19 +1277,19 @@ DEPENDENCIES
|
||||||
capybara (~> 3.33.0)
|
capybara (~> 3.33.0)
|
||||||
capybara-screenshot (~> 1.0.22)
|
capybara-screenshot (~> 1.0.22)
|
||||||
carrierwave (~> 1.3)
|
carrierwave (~> 1.3)
|
||||||
charlock_holmes (~> 0.7.5)
|
charlock_holmes (~> 0.7.7)
|
||||||
commonmarker (~> 0.20)
|
commonmarker (~> 0.20)
|
||||||
concurrent-ruby (~> 1.1)
|
concurrent-ruby (~> 1.1)
|
||||||
connection_pool (~> 2.0)
|
connection_pool (~> 2.0)
|
||||||
countries (~> 3.0)
|
countries (~> 3.0)
|
||||||
creole (~> 0.5.0)
|
creole (~> 0.5.0)
|
||||||
danger (~> 8.0)
|
danger (~> 8.0.6)
|
||||||
database_cleaner (~> 1.7.0)
|
database_cleaner (~> 1.7.0)
|
||||||
deckar01-task_list (= 2.3.1)
|
deckar01-task_list (= 2.3.1)
|
||||||
default_value_for (~> 3.3.0)
|
default_value_for (~> 3.3.0)
|
||||||
derailed_benchmarks
|
derailed_benchmarks
|
||||||
device_detector
|
device_detector
|
||||||
devise (~> 4.6)
|
devise (~> 4.7.2)
|
||||||
devise-two-factor (~> 3.1.0)
|
devise-two-factor (~> 3.1.0)
|
||||||
diff_match_patch (~> 0.1.0)
|
diff_match_patch (~> 0.1.0)
|
||||||
diffy (~> 3.3)
|
diffy (~> 3.3)
|
||||||
|
@ -1322,13 +1327,13 @@ DEPENDENCIES
|
||||||
gettext (~> 3.3)
|
gettext (~> 3.3)
|
||||||
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.3.0.pre.rc1)
|
gitaly (~> 13.5.0.pre.rc2)
|
||||||
github-markup (~> 1.7.0)
|
github-markup (~> 1.7.0)
|
||||||
gitlab-chronic (~> 0.10.5)
|
gitlab-chronic (~> 0.10.5)
|
||||||
gitlab-fog-azure-rm (~> 1.0)
|
gitlab-fog-azure-rm (~> 1.0)
|
||||||
gitlab-labkit (= 0.12.1)
|
gitlab-labkit (= 0.12.2)
|
||||||
gitlab-license (~> 1.0)
|
gitlab-license (~> 1.0)
|
||||||
gitlab-mail_room (~> 0.0.6)
|
gitlab-mail_room (~> 0.0.7)
|
||||||
gitlab-markup (~> 1.7.1)
|
gitlab-markup (~> 1.7.1)
|
||||||
gitlab-net-dns (~> 0.9.1)
|
gitlab-net-dns (~> 0.9.1)
|
||||||
gitlab-puma (~> 4.3.3.gitlab.2)
|
gitlab-puma (~> 4.3.3.gitlab.2)
|
||||||
|
@ -1343,7 +1348,7 @@ DEPENDENCIES
|
||||||
gpgme (~> 2.0.19)
|
gpgme (~> 2.0.19)
|
||||||
grape (= 1.4.0)
|
grape (= 1.4.0)
|
||||||
grape-entity (~> 0.7.1)
|
grape-entity (~> 0.7.1)
|
||||||
grape-path-helpers (~> 1.3)
|
grape-path-helpers (~> 1.4)
|
||||||
grape_logging (~> 1.7)
|
grape_logging (~> 1.7)
|
||||||
graphiql-rails (~> 1.4.10)
|
graphiql-rails (~> 1.4.10)
|
||||||
graphql (~> 1.11.4)
|
graphql (~> 1.11.4)
|
||||||
|
@ -1354,6 +1359,7 @@ DEPENDENCIES
|
||||||
haml_lint (~> 0.34.0)
|
haml_lint (~> 0.34.0)
|
||||||
hamlit (~> 2.11.0)
|
hamlit (~> 2.11.0)
|
||||||
hangouts-chat (~> 0.0.5)
|
hangouts-chat (~> 0.0.5)
|
||||||
|
hashie
|
||||||
hashie-forbidden_attributes
|
hashie-forbidden_attributes
|
||||||
health_check (~> 3.0)
|
health_check (~> 3.0)
|
||||||
hipchat (~> 1.5.0)
|
hipchat (~> 1.5.0)
|
||||||
|
@ -1362,6 +1368,7 @@ DEPENDENCIES
|
||||||
httparty (~> 0.16.4)
|
httparty (~> 0.16.4)
|
||||||
icalendar
|
icalendar
|
||||||
invisible_captcha (~> 0.12.1)
|
invisible_captcha (~> 0.12.1)
|
||||||
|
ipaddress (~> 0.8.3)
|
||||||
jira-ruby (~> 2.0.0)
|
jira-ruby (~> 2.0.0)
|
||||||
js_regex (~> 3.4)
|
js_regex (~> 3.4)
|
||||||
json (~> 2.3.0)
|
json (~> 2.3.0)
|
||||||
|
@ -1371,9 +1378,9 @@ DEPENDENCIES
|
||||||
kaminari (~> 1.0)
|
kaminari (~> 1.0)
|
||||||
knapsack (~> 1.17)
|
knapsack (~> 1.17)
|
||||||
kramdown (~> 2.3.0)
|
kramdown (~> 2.3.0)
|
||||||
kubeclient (~> 4.6.0)
|
kubeclient (~> 4.9.1)
|
||||||
letter_opener_web (~> 1.3.4)
|
letter_opener_web (~> 1.3.4)
|
||||||
license_finder (~> 5.4)
|
license_finder (~> 6.0)
|
||||||
licensee (~> 8.9)
|
licensee (~> 8.9)
|
||||||
lockbox (~> 0.3.3)
|
lockbox (~> 0.3.3)
|
||||||
lograge (~> 0.5)
|
lograge (~> 0.5)
|
||||||
|
@ -1384,7 +1391,7 @@ DEPENDENCIES
|
||||||
memory_profiler (~> 0.9)
|
memory_profiler (~> 0.9)
|
||||||
method_source (~> 1.0)
|
method_source (~> 1.0)
|
||||||
mimemagic (~> 0.3.2)
|
mimemagic (~> 0.3.2)
|
||||||
mini_magick
|
mini_magick (~> 4.10.1)
|
||||||
minitest (~> 5.11.0)
|
minitest (~> 5.11.0)
|
||||||
multi_json (~> 1.14.1)
|
multi_json (~> 1.14.1)
|
||||||
nakayoshi_fork (~> 0.0.4)
|
nakayoshi_fork (~> 0.0.4)
|
||||||
|
@ -1419,10 +1426,10 @@ DEPENDENCIES
|
||||||
pg (~> 1.1)
|
pg (~> 1.1)
|
||||||
png_quantizator (~> 0.2.1)
|
png_quantizator (~> 0.2.1)
|
||||||
premailer-rails (~> 1.10.3)
|
premailer-rails (~> 1.10.3)
|
||||||
prometheus-client-mmap (~> 0.11.0)
|
prometheus-client-mmap (~> 0.12.0)
|
||||||
pry-byebug (~> 3.9.0)
|
pry-byebug (~> 3.9.0)
|
||||||
pry-rails (~> 0.3.9)
|
pry-rails (~> 0.3.9)
|
||||||
rack (~> 2.0.9)
|
rack (~> 2.1.4)
|
||||||
rack-attack (~> 6.3.0)
|
rack-attack (~> 6.3.0)
|
||||||
rack-cors (~> 1.0.6)
|
rack-cors (~> 1.0.6)
|
||||||
rack-oauth2 (~> 1.9.3)
|
rack-oauth2 (~> 1.9.3)
|
||||||
|
@ -1444,7 +1451,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.21.0)
|
rouge (~> 3.24.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)
|
||||||
|
@ -1473,7 +1480,7 @@ DEPENDENCIES
|
||||||
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)
|
simplecov-cobertura (~> 1.3.1)
|
||||||
slack-messenger (~> 2.3.3)
|
slack-messenger (~> 2.3.4)
|
||||||
snowplow-tracker (~> 0.6.1)
|
snowplow-tracker (~> 0.6.1)
|
||||||
spring (~> 2.0.0)
|
spring (~> 2.0.0)
|
||||||
spring-commands-rspec (~> 1.0.4)
|
spring-commands-rspec (~> 1.0.4)
|
||||||
|
@ -1482,13 +1489,13 @@ DEPENDENCIES
|
||||||
stackprof (~> 0.2.15)
|
stackprof (~> 0.2.15)
|
||||||
state_machines-activerecord (~> 0.6.0)
|
state_machines-activerecord (~> 0.6.0)
|
||||||
sys-filesystem (~> 1.1.6)
|
sys-filesystem (~> 1.1.6)
|
||||||
|
terser (= 1.0.2)
|
||||||
test-prof (~> 0.12.0)
|
test-prof (~> 0.12.0)
|
||||||
thin (~> 1.7.0)
|
thin (~> 1.7.0)
|
||||||
timecop (~> 0.9.1)
|
timecop (~> 0.9.1)
|
||||||
toml-rb (~> 1.0.0)
|
toml-rb (~> 1.0.0)
|
||||||
truncato (~> 0.7.11)
|
truncato (~> 0.7.11)
|
||||||
u2f (~> 0.2.1)
|
u2f (~> 0.2.1)
|
||||||
uglifier (~> 2.7.2)
|
|
||||||
unf (~> 0.1.4)
|
unf (~> 0.1.4)
|
||||||
unicorn (~> 5.5)
|
unicorn (~> 5.5)
|
||||||
unicorn-worker-killer (~> 0.4.4)
|
unicorn-worker-killer (~> 0.4.4)
|
||||||
|
@ -1498,8 +1505,7 @@ DEPENDENCIES
|
||||||
version_sorter (~> 2.2.4)
|
version_sorter (~> 2.2.4)
|
||||||
vmstat (~> 2.3.0)
|
vmstat (~> 2.3.0)
|
||||||
webauthn (~> 2.3)
|
webauthn (~> 2.3)
|
||||||
webmock (~> 3.5.1)
|
webmock (~> 3.9.1)
|
||||||
webpack-rails (~> 0.9.10)
|
|
||||||
wikicloth (= 0.8.1)
|
wikicloth (= 0.8.1)
|
||||||
yajl-ruby (~> 1.4.1)
|
yajl-ruby (~> 1.4.1)
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ sensitive as to how you word things. Use Emoji to express your feelings (heart,
|
||||||
star, smile, etc.). Some good tips about code reviews can be found in our
|
star, smile, etc.). Some good tips about code reviews can be found in our
|
||||||
[Code Review Guidelines].
|
[Code Review Guidelines].
|
||||||
|
|
||||||
[Code Review Guidelines]: https://docs.gitlab.com/ce/development/code_review.html
|
[Code Review Guidelines]: https://docs.gitlab.com/ee/development/code_review.html
|
||||||
|
|
||||||
## Feature flags
|
## Feature flags
|
||||||
|
|
||||||
|
@ -217,5 +217,5 @@ rebase with master to see if that solves the issue.
|
||||||
|
|
||||||
[team]: https://about.gitlab.com/team/
|
[team]: https://about.gitlab.com/team/
|
||||||
[done]: https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#definition-of-done
|
[done]: https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#definition-of-done
|
||||||
[automatic_ce_ee_merge]: https://docs.gitlab.com/ce/development/automatic_ce_ee_merge.html
|
[automatic_ce_ee_merge]: https://docs.gitlab.com/ee/development/automatic_ce_ee_merge.html
|
||||||
[ee_features]: https://docs.gitlab.com/ce/development/ee_features.html
|
[ee_features]: https://docs.gitlab.com/ee/development/ee_features.html
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
13.4.7
|
13.5.5
|
|
@ -9,13 +9,13 @@ export default {
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
svgPath: {
|
svgPath: {
|
||||||
type: String,
|
default: '',
|
||||||
},
|
},
|
||||||
docsLink: {
|
docsLink: {
|
||||||
type: String,
|
default: '',
|
||||||
},
|
},
|
||||||
primaryButtonPath: {
|
primaryButtonPath: {
|
||||||
type: String,
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,16 +10,16 @@ export default {
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
isAdmin: {
|
isAdmin: {
|
||||||
type: Boolean,
|
default: false,
|
||||||
},
|
},
|
||||||
svgPath: {
|
svgPath: {
|
||||||
type: String,
|
default: '',
|
||||||
},
|
},
|
||||||
docsLink: {
|
docsLink: {
|
||||||
type: String,
|
default: '',
|
||||||
},
|
},
|
||||||
primaryButtonPath: {
|
primaryButtonPath: {
|
||||||
type: String,
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
// This allows us to dismiss alerts that we've migrated from bootstrap
|
// This allows us to dismiss alerts and banners that we've migrated from bootstrap
|
||||||
// Note: This ONLY works on alerts that are created on page load
|
// Note: This ONLY works on elements that are created on page load
|
||||||
// You can follow this effort in the following epic
|
// You can follow this effort in the following epic
|
||||||
// https://gitlab.com/groups/gitlab-org/-/epics/4070
|
// https://gitlab.com/groups/gitlab-org/-/epics/4070
|
||||||
|
|
||||||
export default function initAlertHandler() {
|
export default function initAlertHandler() {
|
||||||
const ALERT_SELECTOR = '.gl-alert';
|
const DISMISSIBLE_SELECTORS = ['.gl-alert', '.gl-banner'];
|
||||||
const CLOSE_SELECTOR = '.gl-alert-dismiss';
|
const DISMISS_LABEL = '[aria-label="Dismiss"]';
|
||||||
|
const DISMISS_CLASS = '.gl-alert-dismiss';
|
||||||
|
|
||||||
const dismissAlert = ({ target }) => target.closest(ALERT_SELECTOR).remove();
|
DISMISSIBLE_SELECTORS.forEach(selector => {
|
||||||
const closeButtons = document.querySelectorAll(`${ALERT_SELECTOR} ${CLOSE_SELECTOR}`);
|
const elements = document.querySelectorAll(selector);
|
||||||
closeButtons.forEach(alert => alert.addEventListener('click', dismissAlert));
|
elements.forEach(element => {
|
||||||
|
const button = element.querySelector(DISMISS_LABEL) || element.querySelector(DISMISS_CLASS);
|
||||||
|
if (!button) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
button.addEventListener('click', () => element.remove());
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable vue/no-v-html */
|
|
||||||
import * as Sentry from '@sentry/browser';
|
|
||||||
import {
|
import {
|
||||||
GlAlert,
|
GlAlert,
|
||||||
GlBadge,
|
GlBadge,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
|
GlLink,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
GlTabs,
|
GlTabs,
|
||||||
GlTab,
|
GlTab,
|
||||||
GlButton,
|
GlButton,
|
||||||
|
GlSafeHtmlDirective,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
|
import * as Sentry from '~/sentry/wrapper';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import alertQuery from '../graphql/queries/details.query.graphql';
|
import alertQuery from '../graphql/queries/details.query.graphql';
|
||||||
import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql';
|
import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql';
|
||||||
|
@ -28,6 +29,8 @@ 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';
|
import AlertMetrics from './alert_metrics.vue';
|
||||||
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
|
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
|
||||||
|
import AlertSummaryRow from './alert_summary_row.vue';
|
||||||
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
|
|
||||||
const containerEl = document.querySelector('.page-with-contextual-sidebar');
|
const containerEl = document.querySelector('.page-with-contextual-sidebar');
|
||||||
|
|
||||||
|
@ -39,6 +42,9 @@ export default {
|
||||||
reportedAt: s__('AlertManagement|Reported %{when}'),
|
reportedAt: s__('AlertManagement|Reported %{when}'),
|
||||||
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
|
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
|
||||||
},
|
},
|
||||||
|
directives: {
|
||||||
|
SafeHtml: GlSafeHtmlDirective,
|
||||||
|
},
|
||||||
severityLabels: ALERTS_SEVERITY_LABELS,
|
severityLabels: ALERTS_SEVERITY_LABELS,
|
||||||
tabsConfig: [
|
tabsConfig: [
|
||||||
{
|
{
|
||||||
|
@ -56,9 +62,11 @@ export default {
|
||||||
],
|
],
|
||||||
components: {
|
components: {
|
||||||
AlertDetailsTable,
|
AlertDetailsTable,
|
||||||
|
AlertSummaryRow,
|
||||||
GlBadge,
|
GlBadge,
|
||||||
GlAlert,
|
GlAlert,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
|
GlLink,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
GlTab,
|
GlTab,
|
||||||
|
@ -69,20 +77,18 @@ export default {
|
||||||
SystemNote,
|
SystemNote,
|
||||||
AlertMetrics,
|
AlertMetrics,
|
||||||
},
|
},
|
||||||
|
mixins: [glFeatureFlagsMixin()],
|
||||||
inject: {
|
inject: {
|
||||||
projectPath: {
|
projectPath: {
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
alertId: {
|
alertId: {
|
||||||
type: String,
|
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
projectId: {
|
projectId: {
|
||||||
type: String,
|
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
projectIssuesPath: {
|
projectIssuesPath: {
|
||||||
type: String,
|
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -143,6 +149,15 @@ export default {
|
||||||
this.$router.replace({ name: 'tab', params: { tabId } });
|
this.$router.replace({ name: 'tab', params: { tabId } });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
environmentName() {
|
||||||
|
return this.shouldDisplayEnvironment && this.alert?.environment?.name;
|
||||||
|
},
|
||||||
|
environmentPath() {
|
||||||
|
return this.shouldDisplayEnvironment && this.alert?.environment?.path;
|
||||||
|
},
|
||||||
|
shouldDisplayEnvironment() {
|
||||||
|
return this.glFeatures.exposeEnvironmentPathInAlertDetails;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.trackPageViews();
|
this.trackPageViews();
|
||||||
|
@ -211,7 +226,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">
|
||||||
<p v-html="sidebarErrorMessage || $options.i18n.errorMsg"></p>
|
<p v-safe-html="sidebarErrorMessage || $options.i18n.errorMsg"></p>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
<gl-alert
|
<gl-alert
|
||||||
v-if="createIncidentError"
|
v-if="createIncidentError"
|
||||||
|
@ -270,10 +285,9 @@ export default {
|
||||||
variant="default"
|
variant="default"
|
||||||
class="d-sm-none gl-absolute toggle-sidebar-mobile-button"
|
class="d-sm-none gl-absolute toggle-sidebar-mobile-button"
|
||||||
type="button"
|
type="button"
|
||||||
|
icon="chevron-double-lg-left"
|
||||||
@click="toggleSidebar"
|
@click="toggleSidebar"
|
||||||
>
|
/>
|
||||||
<i class="fa fa-angle-double-left"></i>
|
|
||||||
</gl-button>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="alert"
|
v-if="alert"
|
||||||
|
@ -283,54 +297,65 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<gl-tabs v-if="alert" v-model="currentTabIndex" data-testid="alertDetailsTabs">
|
<gl-tabs v-if="alert" v-model="currentTabIndex" data-testid="alertDetailsTabs">
|
||||||
<gl-tab :data-testid="$options.tabsConfig[0].id" :title="$options.tabsConfig[0].title">
|
<gl-tab :data-testid="$options.tabsConfig[0].id" :title="$options.tabsConfig[0].title">
|
||||||
<div v-if="alert.severity" class="gl-mt-3 gl-mb-5 gl-display-flex">
|
<alert-summary-row v-if="alert.severity" :label="`${s__('AlertManagement|Severity')}:`">
|
||||||
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
|
<span data-testid="severity">
|
||||||
{{ s__('AlertManagement|Severity') }}:
|
|
||||||
</div>
|
|
||||||
<div class="gl-pl-2" data-testid="severity">
|
|
||||||
<span>
|
|
||||||
<gl-icon
|
<gl-icon
|
||||||
class="gl-vertical-align-middle"
|
class="gl-vertical-align-middle"
|
||||||
:size="12"
|
:size="12"
|
||||||
:name="`severity-${alert.severity.toLowerCase()}`"
|
:name="`severity-${alert.severity.toLowerCase()}`"
|
||||||
:class="`icon-${alert.severity.toLowerCase()}`"
|
:class="`icon-${alert.severity.toLowerCase()}`"
|
||||||
/>
|
/>
|
||||||
</span>
|
|
||||||
{{ $options.severityLabels[alert.severity] }}
|
{{ $options.severityLabels[alert.severity] }}
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</alert-summary-row>
|
||||||
<div v-if="alert.startedAt" class="gl-my-5 gl-display-flex">
|
<alert-summary-row
|
||||||
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
|
v-if="environmentName"
|
||||||
{{ s__('AlertManagement|Start time') }}:
|
:label="`${s__('AlertManagement|Environment')}:`"
|
||||||
</div>
|
>
|
||||||
<div class="gl-pl-2">
|
<gl-link
|
||||||
|
v-if="environmentPath"
|
||||||
|
class="gl-display-inline-block"
|
||||||
|
data-testid="environmentPath"
|
||||||
|
:href="environmentPath"
|
||||||
|
>
|
||||||
|
{{ environmentName }}
|
||||||
|
</gl-link>
|
||||||
|
<span v-else data-testid="environmentName">{{ environmentName }}</span>
|
||||||
|
</alert-summary-row>
|
||||||
|
<alert-summary-row
|
||||||
|
v-if="alert.startedAt"
|
||||||
|
:label="`${s__('AlertManagement|Start time')}:`"
|
||||||
|
>
|
||||||
<time-ago-tooltip data-testid="startTimeItem" :time="alert.startedAt" />
|
<time-ago-tooltip data-testid="startTimeItem" :time="alert.startedAt" />
|
||||||
</div>
|
</alert-summary-row>
|
||||||
</div>
|
<alert-summary-row
|
||||||
<div v-if="alert.eventCount" class="gl-my-5 gl-display-flex">
|
v-if="alert.eventCount"
|
||||||
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
|
:label="`${s__('AlertManagement|Events')}:`"
|
||||||
{{ s__('AlertManagement|Events') }}:
|
data-testid="eventCount"
|
||||||
</div>
|
>
|
||||||
<div class="gl-pl-2" data-testid="eventCount">{{ alert.eventCount }}</div>
|
{{ alert.eventCount }}
|
||||||
</div>
|
</alert-summary-row>
|
||||||
<div v-if="alert.monitoringTool" class="gl-my-5 gl-display-flex">
|
<alert-summary-row
|
||||||
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
|
v-if="alert.monitoringTool"
|
||||||
{{ s__('AlertManagement|Tool') }}:
|
:label="`${s__('AlertManagement|Tool')}:`"
|
||||||
</div>
|
data-testid="monitoringTool"
|
||||||
<div class="gl-pl-2" data-testid="monitoringTool">{{ alert.monitoringTool }}</div>
|
>
|
||||||
</div>
|
{{ alert.monitoringTool }}
|
||||||
<div v-if="alert.service" class="gl-my-5 gl-display-flex">
|
</alert-summary-row>
|
||||||
<div class="bold gl-w-13 gl-text-right gl-pr-3">
|
<alert-summary-row
|
||||||
{{ s__('AlertManagement|Service') }}:
|
v-if="alert.service"
|
||||||
</div>
|
:label="`${s__('AlertManagement|Service')}:`"
|
||||||
<div class="gl-pl-2" data-testid="service">{{ alert.service }}</div>
|
data-testid="service"
|
||||||
</div>
|
>
|
||||||
<div v-if="alert.runbook" class="gl-my-5 gl-display-flex">
|
{{ alert.service }}
|
||||||
<div class="bold gl-w-13 gl-text-right gl-pr-3">
|
</alert-summary-row>
|
||||||
{{ s__('AlertManagement|Runbook') }}:
|
<alert-summary-row
|
||||||
</div>
|
v-if="alert.runbook"
|
||||||
<div class="gl-pl-2" data-testid="runbook">{{ alert.runbook }}</div>
|
:label="`${s__('AlertManagement|Runbook')}:`"
|
||||||
</div>
|
data-testid="runbook"
|
||||||
|
>
|
||||||
|
{{ alert.runbook }}
|
||||||
|
</alert-summary-row>
|
||||||
<alert-details-table :alert="alert" :loading="loading" />
|
<alert-details-table :alert="alert" :loading="loading" />
|
||||||
</gl-tab>
|
</gl-tab>
|
||||||
<gl-tab :data-testid="$options.tabsConfig[1].id" :title="$options.tabsConfig[1].title">
|
<gl-tab :data-testid="$options.tabsConfig[1].id" :title="$options.tabsConfig[1].title">
|
||||||
|
|
|
@ -33,30 +33,13 @@ export default {
|
||||||
query: alertsHelpUrlQuery,
|
query: alertsHelpUrlQuery,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
props: {
|
inject: [
|
||||||
enableAlertManagementPath: {
|
'enableAlertManagementPath',
|
||||||
type: String,
|
'userCanEnableAlertManagement',
|
||||||
required: true,
|
'emptyAlertSvgPath',
|
||||||
},
|
'opsgenieMvcEnabled',
|
||||||
userCanEnableAlertManagement: {
|
'opsgenieMvcTargetUrl',
|
||||||
type: Boolean,
|
],
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
emptyAlertSvgPath: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
opsgenieMvcEnabled: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
opsgenieMvcTargetUrl: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
alertsHelpUrl: '',
|
alertsHelpUrl: '',
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<script>
|
<script>
|
||||||
import Tracking from '~/tracking';
|
|
||||||
import { trackAlertListViewsOptions } from '../constants';
|
|
||||||
import AlertManagementEmptyState from './alert_management_empty_state.vue';
|
import AlertManagementEmptyState from './alert_management_empty_state.vue';
|
||||||
import AlertManagementTable from './alert_management_table.vue';
|
import AlertManagementTable from './alert_management_table.vue';
|
||||||
|
|
||||||
|
@ -9,67 +7,12 @@ export default {
|
||||||
AlertManagementEmptyState,
|
AlertManagementEmptyState,
|
||||||
AlertManagementTable,
|
AlertManagementTable,
|
||||||
},
|
},
|
||||||
props: {
|
inject: ['alertManagementEnabled'],
|
||||||
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>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<alert-management-table
|
<alert-management-table v-if="alertManagementEnabled" />
|
||||||
v-if="alertManagementEnabled"
|
<alert-management-empty-state v-else />
|
||||||
: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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,58 +1,43 @@
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable vue/no-v-html */
|
|
||||||
import {
|
import {
|
||||||
|
GlAlert,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTable,
|
GlTable,
|
||||||
GlAlert,
|
|
||||||
GlAvatarsInline,
|
GlAvatarsInline,
|
||||||
GlAvatarLink,
|
GlAvatarLink,
|
||||||
GlAvatar,
|
GlAvatar,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlLink,
|
GlLink,
|
||||||
GlTabs,
|
|
||||||
GlTab,
|
|
||||||
GlBadge,
|
|
||||||
GlPagination,
|
|
||||||
GlSearchBoxByType,
|
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
GlTooltipDirective,
|
GlTooltipDirective,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import { debounce, trim } from 'lodash';
|
import { s__, __ } from '~/locale';
|
||||||
import { __, s__ } from '~/locale';
|
|
||||||
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
|
|
||||||
import { fetchPolicies } from '~/lib/graphql';
|
import { fetchPolicies } from '~/lib/graphql';
|
||||||
|
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
|
||||||
|
import PaginatedTableWithSearchAndTabs from '~/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue';
|
||||||
|
import {
|
||||||
|
tdClass,
|
||||||
|
thClass,
|
||||||
|
bodyTrClass,
|
||||||
|
initialPaginationState,
|
||||||
|
} from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants';
|
||||||
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 { 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 {
|
||||||
ALERTS_STATUS_TABS,
|
ALERTS_STATUS_TABS,
|
||||||
ALERTS_SEVERITY_LABELS,
|
ALERTS_SEVERITY_LABELS,
|
||||||
DEFAULT_PAGE_SIZE,
|
|
||||||
trackAlertListViewsOptions,
|
trackAlertListViewsOptions,
|
||||||
trackAlertStatusUpdateOptions,
|
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import AlertStatus from './alert_status.vue';
|
import AlertStatus from './alert_status.vue';
|
||||||
|
|
||||||
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 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';
|
|
||||||
const TH_TEST_ID = { 'data-testid': 'alert-management-severity-sort' };
|
const TH_TEST_ID = { 'data-testid': 'alert-management-severity-sort' };
|
||||||
|
|
||||||
const initialPaginationState = {
|
|
||||||
currentPage: 1,
|
|
||||||
prevPageCursor: '',
|
|
||||||
nextPageCursor: '',
|
|
||||||
firstPageSize: DEFAULT_PAGE_SIZE,
|
|
||||||
lastPageSize: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const TWELVE_HOURS_IN_MS = 12 * 60 * 60 * 1000;
|
const TWELVE_HOURS_IN_MS = 12 * 60 * 60 * 1000;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
trackAlertListViewsOptions,
|
||||||
i18n: {
|
i18n: {
|
||||||
noAlertsMsg: s__(
|
noAlertsMsg: s__(
|
||||||
'AlertManagement|No alerts available to display. See %{linkStart}enabling alert management%{linkEnd} for more information on adding alerts to the list.',
|
'AlertManagement|No alerts available to display. See %{linkStart}enabling alert management%{linkEnd} for more information on adding alerts to the list.',
|
||||||
|
@ -60,7 +45,6 @@ export default {
|
||||||
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...'),
|
|
||||||
unassigned: __('Unassigned'),
|
unassigned: __('Unassigned'),
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -94,7 +78,7 @@ export default {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'issue',
|
key: 'issue',
|
||||||
label: s__('AlertManagement|Issue'),
|
label: s__('AlertManagement|Incident'),
|
||||||
thClass: 'gl-w-12 gl-pointer-events-none',
|
thClass: 'gl-w-12 gl-pointer-events-none',
|
||||||
tdClass,
|
tdClass,
|
||||||
},
|
},
|
||||||
|
@ -115,36 +99,23 @@ export default {
|
||||||
severityLabels: ALERTS_SEVERITY_LABELS,
|
severityLabels: ALERTS_SEVERITY_LABELS,
|
||||||
statusTabs: ALERTS_STATUS_TABS,
|
statusTabs: ALERTS_STATUS_TABS,
|
||||||
components: {
|
components: {
|
||||||
|
GlAlert,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTable,
|
GlTable,
|
||||||
GlAlert,
|
|
||||||
GlAvatarsInline,
|
GlAvatarsInline,
|
||||||
GlAvatarLink,
|
GlAvatarLink,
|
||||||
GlAvatar,
|
GlAvatar,
|
||||||
TimeAgo,
|
TimeAgo,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlLink,
|
GlLink,
|
||||||
GlTabs,
|
|
||||||
GlTab,
|
|
||||||
GlBadge,
|
|
||||||
GlPagination,
|
|
||||||
GlSearchBoxByType,
|
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
AlertStatus,
|
AlertStatus,
|
||||||
|
PaginatedTableWithSearchAndTabs,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
GlTooltip: GlTooltipDirective,
|
GlTooltip: GlTooltipDirective,
|
||||||
},
|
},
|
||||||
props: {
|
inject: ['projectPath', 'textQuery', 'assigneeUsernameQuery', 'populatingAlertsHelpUrl'],
|
||||||
projectPath: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
populatingAlertsHelpUrl: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
apollo: {
|
apollo: {
|
||||||
alerts: {
|
alerts: {
|
||||||
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
||||||
|
@ -152,6 +123,7 @@ export default {
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
searchTerm: this.searchTerm,
|
searchTerm: this.searchTerm,
|
||||||
|
assigneeUsername: this.assigneeUsername,
|
||||||
projectPath: this.projectPath,
|
projectPath: this.projectPath,
|
||||||
statuses: this.statusFilter,
|
statuses: this.statusFilter,
|
||||||
sort: this.sort,
|
sort: this.sort,
|
||||||
|
@ -182,14 +154,16 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
error() {
|
error() {
|
||||||
this.hasError = true;
|
this.errored = true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
alertsCount: {
|
alertsCount: {
|
||||||
|
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
||||||
query: getAlertsCountByStatus,
|
query: getAlertsCountByStatus,
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
searchTerm: this.searchTerm,
|
searchTerm: this.searchTerm,
|
||||||
|
assigneeUsername: this.assigneeUsername,
|
||||||
projectPath: this.projectPath,
|
projectPath: this.projectPath,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -200,83 +174,53 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchTerm: '',
|
errored: false,
|
||||||
hasError: false,
|
serverErrorMessage: '',
|
||||||
errorMessage: '',
|
isErrorAlertDismissed: false,
|
||||||
isAlertDismissed: false,
|
|
||||||
sort: 'STARTED_AT_DESC',
|
sort: 'STARTED_AT_DESC',
|
||||||
statusFilter: [],
|
statusFilter: [],
|
||||||
filteredByStatus: '',
|
filteredByStatus: '',
|
||||||
pagination: initialPaginationState,
|
alerts: {},
|
||||||
|
alertsCount: {},
|
||||||
sortBy: 'startedAt',
|
sortBy: 'startedAt',
|
||||||
sortDesc: true,
|
sortDesc: true,
|
||||||
sortDirection: 'desc',
|
sortDirection: 'desc',
|
||||||
|
searchTerm: this.textQuery,
|
||||||
|
assigneeUsername: this.assigneeUsernameQuery,
|
||||||
|
pagination: initialPaginationState,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
showErrorMsg() {
|
||||||
|
return this.errored && !this.isErrorAlertDismissed;
|
||||||
|
},
|
||||||
showNoAlertsMsg() {
|
showNoAlertsMsg() {
|
||||||
return (
|
return (
|
||||||
!this.hasError &&
|
!this.errored &&
|
||||||
!this.loading &&
|
!this.loading &&
|
||||||
this.alertsCount?.all === 0 &&
|
this.alertsCount?.all === 0 &&
|
||||||
!this.searchTerm &&
|
!this.searchTerm &&
|
||||||
!this.isAlertDismissed
|
!this.assigneeUsername &&
|
||||||
|
!this.isErrorAlertDismissed
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading() {
|
loading() {
|
||||||
return this.$apollo.queries.alerts.loading;
|
return this.$apollo.queries.alerts.loading;
|
||||||
},
|
},
|
||||||
hasAlerts() {
|
isEmpty() {
|
||||||
return this.alerts?.list?.length;
|
return !this.alerts?.list?.length;
|
||||||
},
|
},
|
||||||
showPaginationControls() {
|
|
||||||
return Boolean(this.prevPage || this.nextPage);
|
|
||||||
},
|
|
||||||
alertsForCurrentTab() {
|
|
||||||
return this.alertsCount ? this.alertsCount[this.filteredByStatus.toLowerCase()] : 0;
|
|
||||||
},
|
|
||||||
prevPage() {
|
|
||||||
return Math.max(this.pagination.currentPage - 1, 0);
|
|
||||||
},
|
|
||||||
nextPage() {
|
|
||||||
const nextPage = this.pagination.currentPage + 1;
|
|
||||||
return nextPage > Math.ceil(this.alertsForCurrentTab / DEFAULT_PAGE_SIZE) ? null : nextPage;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.trackPageViews();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
filterAlertsByStatus(tabIndex) {
|
|
||||||
this.resetPagination();
|
|
||||||
const { filters, status } = this.$options.statusTabs[tabIndex];
|
|
||||||
this.statusFilter = filters;
|
|
||||||
this.filteredByStatus = status;
|
|
||||||
},
|
|
||||||
fetchSortedData({ sortBy, sortDesc }) {
|
fetchSortedData({ sortBy, sortDesc }) {
|
||||||
const sortingDirection = sortDesc ? 'DESC' : 'ASC';
|
const sortingDirection = sortDesc ? 'DESC' : 'ASC';
|
||||||
const sortingColumn = convertToSnakeCase(sortBy).toUpperCase();
|
const sortingColumn = convertToSnakeCase(sortBy).toUpperCase();
|
||||||
|
|
||||||
this.resetPagination();
|
this.pagination = initialPaginationState;
|
||||||
this.sort = `${sortingColumn}_${sortingDirection}`;
|
this.sort = `${sortingColumn}_${sortingDirection}`;
|
||||||
},
|
},
|
||||||
onInputChange: debounce(function debounceSearch(input) {
|
navigateToAlertDetails({ iid }, index, { metaKey }) {
|
||||||
const trimmedInput = trim(input);
|
return visitUrl(joinPaths(window.location.pathname, iid, 'details'), metaKey);
|
||||||
if (trimmedInput !== this.searchTerm) {
|
|
||||||
this.resetPagination();
|
|
||||||
this.searchTerm = trimmedInput;
|
|
||||||
}
|
|
||||||
}, 500),
|
|
||||||
navigateToAlertDetails({ iid }) {
|
|
||||||
return visitUrl(joinPaths(window.location.pathname, iid, 'details'));
|
|
||||||
},
|
|
||||||
trackPageViews() {
|
|
||||||
const { category, action } = trackAlertListViewsOptions;
|
|
||||||
Tracking.event(category, action);
|
|
||||||
},
|
|
||||||
trackStatusUpdate(status) {
|
|
||||||
const { category, action, label } = trackAlertStatusUpdateOptions;
|
|
||||||
Tracking.event(category, action, { label, property: status });
|
|
||||||
},
|
},
|
||||||
hasAssignees(assignees) {
|
hasAssignees(assignees) {
|
||||||
return Boolean(assignees.nodes?.length);
|
return Boolean(assignees.nodes?.length);
|
||||||
|
@ -284,90 +228,74 @@ export default {
|
||||||
getIssueLink(item) {
|
getIssueLink(item) {
|
||||||
return joinPaths('/', this.projectPath, '-', 'issues', item.issueIid);
|
return joinPaths('/', this.projectPath, '-', 'issues', item.issueIid);
|
||||||
},
|
},
|
||||||
handlePageChange(page) {
|
|
||||||
const { startCursor, endCursor } = this.alerts.pageInfo;
|
|
||||||
|
|
||||||
if (page > this.pagination.currentPage) {
|
|
||||||
this.pagination = {
|
|
||||||
...initialPaginationState,
|
|
||||||
nextPageCursor: endCursor,
|
|
||||||
currentPage: page,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
this.pagination = {
|
|
||||||
lastPageSize: DEFAULT_PAGE_SIZE,
|
|
||||||
firstPageSize: null,
|
|
||||||
prevPageCursor: startCursor,
|
|
||||||
nextPageCursor: '',
|
|
||||||
currentPage: page,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
resetPagination() {
|
|
||||||
this.pagination = initialPaginationState;
|
|
||||||
},
|
|
||||||
tbodyTrClass(item) {
|
tbodyTrClass(item) {
|
||||||
return {
|
return {
|
||||||
[bodyTrClass]: !this.loading && this.hasAlerts,
|
[bodyTrClass]: !this.loading && !this.isEmpty,
|
||||||
'new-alert': item?.isNew,
|
'new-alert': item?.isNew,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleAlertError(errorMessage) {
|
handleAlertError(errorMessage) {
|
||||||
this.hasError = true;
|
this.errored = true;
|
||||||
this.errorMessage = errorMessage;
|
this.serverErrorMessage = errorMessage;
|
||||||
},
|
},
|
||||||
dismissError() {
|
handleStatusUpdate() {
|
||||||
this.hasError = false;
|
this.$apollo.queries.alerts.refetch();
|
||||||
this.errorMessage = '';
|
this.$apollo.queries.alertsCount.refetch();
|
||||||
|
},
|
||||||
|
pageChanged(pagination) {
|
||||||
|
this.pagination = pagination;
|
||||||
|
},
|
||||||
|
statusChanged({ filters, status }) {
|
||||||
|
this.statusFilter = filters;
|
||||||
|
this.filteredByStatus = status;
|
||||||
|
},
|
||||||
|
filtersChanged({ searchTerm, assigneeUsername }) {
|
||||||
|
this.searchTerm = searchTerm;
|
||||||
|
this.assigneeUsername = assigneeUsername;
|
||||||
|
},
|
||||||
|
errorAlertDismissed() {
|
||||||
|
this.errored = false;
|
||||||
|
this.serverErrorMessage = '';
|
||||||
|
this.isErrorAlertDismissed = true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="incident-management-list">
|
<gl-alert v-if="showNoAlertsMsg" @dismiss="errorAlertDismissed">
|
||||||
<gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true">
|
|
||||||
<gl-sprintf :message="$options.i18n.noAlertsMsg">
|
<gl-sprintf :message="$options.i18n.noAlertsMsg">
|
||||||
<template #link="{ content }">
|
<template #link="{ content }">
|
||||||
<gl-link
|
<gl-link class="gl-display-inline-block" :href="populatingAlertsHelpUrl" target="_blank">
|
||||||
class="gl-display-inline-block"
|
|
||||||
:href="populatingAlertsHelpUrl"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</gl-link>
|
</gl-link>
|
||||||
</template>
|
</template>
|
||||||
</gl-sprintf>
|
</gl-sprintf>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
<gl-alert v-if="hasError" variant="danger" data-testid="alert-error" @dismiss="dismissError">
|
|
||||||
<p v-html="errorMessage || $options.i18n.errorMsg"></p>
|
|
||||||
</gl-alert>
|
|
||||||
|
|
||||||
<gl-tabs
|
<paginated-table-with-search-and-tabs
|
||||||
content-class="gl-p-0 gl-border-b-solid gl-border-b-1 gl-border-gray-100"
|
:show-error-msg="showErrorMsg"
|
||||||
@input="filterAlertsByStatus"
|
:i18n="$options.i18n"
|
||||||
|
:items="alerts.list || []"
|
||||||
|
:page-info="alerts.pageInfo"
|
||||||
|
:items-count="alertsCount"
|
||||||
|
:status-tabs="$options.statusTabs"
|
||||||
|
:track-views-options="$options.trackAlertListViewsOptions"
|
||||||
|
:server-error-message="serverErrorMessage"
|
||||||
|
:filter-search-tokens="['assignee_username']"
|
||||||
|
filter-search-key="alerts"
|
||||||
|
@page-changed="pageChanged"
|
||||||
|
@tabs-changed="statusChanged"
|
||||||
|
@filters-changed="filtersChanged"
|
||||||
|
@error-alert-dismissed="errorAlertDismissed"
|
||||||
>
|
>
|
||||||
<gl-tab v-for="tab in $options.statusTabs" :key="tab.status">
|
<template #header-actions></template>
|
||||||
<template slot="title">
|
|
||||||
<span>{{ tab.title }}</span>
|
|
||||||
<gl-badge v-if="alertsCount" pill size="sm" class="gl-tab-counter-badge">
|
|
||||||
{{ alertsCount[tab.status.toLowerCase()] }}
|
|
||||||
</gl-badge>
|
|
||||||
</template>
|
|
||||||
</gl-tab>
|
|
||||||
</gl-tabs>
|
|
||||||
|
|
||||||
<div class="gl-bg-gray-10 gl-p-5 gl-border-b-solid gl-border-b-1 gl-border-gray-100">
|
<template #title>
|
||||||
<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">
|
|
||||||
{{ s__('AlertManagement|Alerts') }}
|
{{ s__('AlertManagement|Alerts') }}
|
||||||
</h4>
|
</template>
|
||||||
|
|
||||||
|
<template #table>
|
||||||
<gl-table
|
<gl-table
|
||||||
class="alert-management-table"
|
class="alert-management-table"
|
||||||
:items="alerts ? alerts.list : []"
|
:items="alerts ? alerts.list : []"
|
||||||
|
@ -461,6 +389,7 @@ export default {
|
||||||
:project-path="projectPath"
|
:project-path="projectPath"
|
||||||
:is-sidebar="false"
|
:is-sidebar="false"
|
||||||
@alert-error="handleAlertError"
|
@alert-error="handleAlertError"
|
||||||
|
@hide-dropdown="handleStatusUpdate"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -472,16 +401,7 @@ export default {
|
||||||
<gl-loading-icon size="lg" color="dark" class="mt-3" />
|
<gl-loading-icon size="lg" color="dark" class="mt-3" />
|
||||||
</template>
|
</template>
|
||||||
</gl-table>
|
</gl-table>
|
||||||
|
</template>
|
||||||
<gl-pagination
|
</paginated-table-with-search-and-tabs>
|
||||||
v-if="showPaginationControls"
|
|
||||||
:value="pagination.currentPage"
|
|
||||||
:prev-page="prevPage"
|
|
||||||
:next-page="nextPage"
|
|
||||||
align="center"
|
|
||||||
class="gl-pagination gl-mt-3"
|
|
||||||
@input="handlePageChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
import * as Sentry from '@sentry/browser';
|
import * as Sentry from '~/sentry/wrapper';
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ export default {
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
projectId: {
|
projectId: {
|
||||||
type: String,
|
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlDeprecatedDropdown, GlDeprecatedDropdownItem, GlButton } from '@gitlab/ui';
|
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
import { trackAlertStatusUpdateOptions } from '../constants';
|
import { trackAlertStatusUpdateOptions } from '../constants';
|
||||||
import updateAlertStatus from '../graphql/mutations/update_alert_status.mutation.graphql';
|
import updateAlertStatusMutation from '../graphql/mutations/update_alert_status.mutation.graphql';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
i18n: {
|
i18n: {
|
||||||
|
@ -18,9 +18,8 @@ export default {
|
||||||
RESOLVED: s__('AlertManagement|Resolved'),
|
RESOLVED: s__('AlertManagement|Resolved'),
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
GlDeprecatedDropdown,
|
GlDropdown,
|
||||||
GlDeprecatedDropdownItem,
|
GlDropdownItem,
|
||||||
GlButton,
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
projectPath: {
|
projectPath: {
|
||||||
|
@ -51,7 +50,7 @@ export default {
|
||||||
this.$emit('handle-updating', true);
|
this.$emit('handle-updating', true);
|
||||||
this.$apollo
|
this.$apollo
|
||||||
.mutate({
|
.mutate({
|
||||||
mutation: updateAlertStatus,
|
mutation: updateAlertStatusMutation,
|
||||||
variables: {
|
variables: {
|
||||||
iid: this.alert.iid,
|
iid: this.alert.iid,
|
||||||
status: status.toUpperCase(),
|
status: status.toUpperCase(),
|
||||||
|
@ -60,8 +59,6 @@ export default {
|
||||||
})
|
})
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
this.trackStatusUpdate(status);
|
this.trackStatusUpdate(status);
|
||||||
this.$emit('hide-dropdown');
|
|
||||||
|
|
||||||
const errors = resp.data?.updateAlertStatus?.errors || [];
|
const errors = resp.data?.updateAlertStatus?.errors || [];
|
||||||
|
|
||||||
if (errors[0]) {
|
if (errors[0]) {
|
||||||
|
@ -70,6 +67,8 @@ export default {
|
||||||
`${this.$options.i18n.UPDATE_ALERT_STATUS_ERROR} ${errors[0]}`,
|
`${this.$options.i18n.UPDATE_ALERT_STATUS_ERROR} ${errors[0]}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$emit('hide-dropdown');
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.$emit(
|
this.$emit(
|
||||||
|
@ -91,39 +90,30 @@ export default {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
|
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
|
||||||
<gl-deprecated-dropdown
|
<gl-dropdown
|
||||||
ref="dropdown"
|
ref="dropdown"
|
||||||
right
|
right
|
||||||
:text="$options.statuses[alert.status]"
|
:text="$options.statuses[alert.status]"
|
||||||
class="w-100"
|
class="w-100"
|
||||||
toggle-class="dropdown-menu-toggle"
|
toggle-class="dropdown-menu-toggle"
|
||||||
variant="outline-default"
|
|
||||||
@keydown.esc.native="$emit('hide-dropdown')"
|
@keydown.esc.native="$emit('hide-dropdown')"
|
||||||
@hide="$emit('hide-dropdown')"
|
@hide="$emit('hide-dropdown')"
|
||||||
>
|
>
|
||||||
<div v-if="isSidebar" class="dropdown-title gl-display-flex">
|
<p v-if="isSidebar" class="gl-new-dropdown-header-top" data-testid="dropdown-header">
|
||||||
<span class="alert-title gl-ml-auto">{{ s__('AlertManagement|Assign status') }}</span>
|
{{ s__('AlertManagement|Assign status') }}
|
||||||
<gl-button
|
</p>
|
||||||
:aria-label="__('Close')"
|
|
||||||
variant="link"
|
|
||||||
class="dropdown-title-button dropdown-menu-close gl-ml-auto gl-text-black-normal!"
|
|
||||||
icon="close"
|
|
||||||
@click="$emit('hide-dropdown')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-content dropdown-body">
|
<div class="dropdown-content dropdown-body">
|
||||||
<gl-deprecated-dropdown-item
|
<gl-dropdown-item
|
||||||
v-for="(label, field) in $options.statuses"
|
v-for="(label, field) in $options.statuses"
|
||||||
:key="field"
|
:key="field"
|
||||||
data-testid="statusDropdownItem"
|
data-testid="statusDropdownItem"
|
||||||
class="gl-vertical-align-middle"
|
|
||||||
:active="label.toUpperCase() === alert.status"
|
:active="label.toUpperCase() === alert.status"
|
||||||
:active-class="'is-active'"
|
:active-class="'is-active'"
|
||||||
@click="updateAlertStatus(label)"
|
@click="updateAlertStatus(label)"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</gl-deprecated-dropdown-item>
|
</gl-dropdown-item>
|
||||||
</div>
|
</div>
|
||||||
</gl-deprecated-dropdown>
|
</gl-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="gl-my-5 gl-display-flex">
|
||||||
|
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">{{ label }}</div>
|
||||||
|
<div class="gl-pl-2">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,9 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlDeprecatedDropdownItem } from '@gitlab/ui';
|
import { GlDropdownItem } from '@gitlab/ui';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlDeprecatedDropdownItem,
|
GlDropdownItem,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
user: {
|
user: {
|
||||||
|
@ -24,7 +24,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<gl-deprecated-dropdown-item
|
<gl-dropdown-item
|
||||||
:key="user.username"
|
:key="user.username"
|
||||||
data-testid="assigneeDropdownItem"
|
data-testid="assigneeDropdownItem"
|
||||||
class="assignee-dropdown-item gl-vertical-align-middle"
|
class="assignee-dropdown-item gl-vertical-align-middle"
|
||||||
|
@ -47,5 +47,5 @@ export default {
|
||||||
</strong>
|
</strong>
|
||||||
<span class="dropdown-menu-user-username"> {{ user.username }}</span>
|
<span class="dropdown-menu-user-username"> {{ user.username }}</span>
|
||||||
</span>
|
</span>
|
||||||
</gl-deprecated-dropdown-item>
|
</gl-dropdown-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlDeprecatedDropdown,
|
GlDropdown,
|
||||||
GlDeprecatedDropdownDivider,
|
GlDropdownDivider,
|
||||||
GlDeprecatedDropdownHeader,
|
GlDropdownSectionHeader,
|
||||||
GlDeprecatedDropdownItem,
|
GlDropdownItem,
|
||||||
|
GlSearchBoxByType,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTooltip,
|
GlTooltip,
|
||||||
GlButton,
|
GlButton,
|
||||||
|
@ -33,10 +34,11 @@ export default {
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlDeprecatedDropdown,
|
GlDropdown,
|
||||||
GlDeprecatedDropdownItem,
|
GlDropdownItem,
|
||||||
GlDeprecatedDropdownDivider,
|
GlDropdownDivider,
|
||||||
GlDeprecatedDropdownHeader,
|
GlDropdownSectionHeader,
|
||||||
|
GlSearchBoxByType,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
GlTooltip,
|
GlTooltip,
|
||||||
GlButton,
|
GlButton,
|
||||||
|
@ -216,48 +218,32 @@ export default {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
|
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
|
||||||
<gl-deprecated-dropdown
|
<gl-dropdown
|
||||||
ref="dropdown"
|
ref="dropdown"
|
||||||
:text="userName"
|
:text="userName"
|
||||||
class="w-100"
|
class="w-100"
|
||||||
toggle-class="dropdown-menu-toggle"
|
toggle-class="dropdown-menu-toggle"
|
||||||
variant="outline-default"
|
|
||||||
@keydown.esc.native="hideDropdown"
|
@keydown.esc.native="hideDropdown"
|
||||||
@hide="hideDropdown"
|
@hide="hideDropdown"
|
||||||
>
|
>
|
||||||
<div class="dropdown-title gl-display-flex">
|
<p class="gl-new-dropdown-header-top">
|
||||||
<span class="alert-title gl-ml-auto">{{ __('Assign To') }}</span>
|
{{ __('Assign To') }}
|
||||||
<gl-button
|
</p>
|
||||||
:aria-label="__('Close')"
|
<gl-search-box-by-type v-model.trim="search" :placeholder="__('Search users')" />
|
||||||
variant="link"
|
|
||||||
class="dropdown-title-button dropdown-menu-close gl-ml-auto gl-text-black-normal!"
|
|
||||||
icon="close"
|
|
||||||
@click="hideDropdown"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-input">
|
|
||||||
<input
|
|
||||||
v-model.trim="search"
|
|
||||||
class="dropdown-input-field"
|
|
||||||
type="search"
|
|
||||||
:placeholder="__('Search users')"
|
|
||||||
/>
|
|
||||||
<gl-icon name="search" class="dropdown-input-search ic-search" data-hidden="true" />
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-content dropdown-body">
|
<div class="dropdown-content dropdown-body">
|
||||||
<template v-if="userListValid">
|
<template v-if="userListValid">
|
||||||
<gl-deprecated-dropdown-item
|
<gl-dropdown-item
|
||||||
:active="!userName"
|
:active="!userName"
|
||||||
active-class="is-active"
|
active-class="is-active"
|
||||||
@click="updateAlertAssignees('')"
|
@click="updateAlertAssignees('')"
|
||||||
>
|
>
|
||||||
{{ __('Unassigned') }}
|
{{ __('Unassigned') }}
|
||||||
</gl-deprecated-dropdown-item>
|
</gl-dropdown-item>
|
||||||
<gl-deprecated-dropdown-divider />
|
<gl-dropdown-divider />
|
||||||
|
|
||||||
<gl-deprecated-dropdown-header class="mt-0">
|
<gl-dropdown-section-header>
|
||||||
{{ __('Assignee') }}
|
{{ __('Assignee') }}
|
||||||
</gl-deprecated-dropdown-header>
|
</gl-dropdown-section-header>
|
||||||
<sidebar-assignee
|
<sidebar-assignee
|
||||||
v-for="user in sortedUsers"
|
v-for="user in sortedUsers"
|
||||||
:key="user.username"
|
:key="user.username"
|
||||||
|
@ -266,12 +252,12 @@ export default {
|
||||||
@update-alert-assignees="updateAlertAssignees"
|
@update-alert-assignees="updateAlertAssignees"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<gl-deprecated-dropdown-item v-else-if="userListEmpty">
|
<p v-else-if="userListEmpty" class="mx-3 my-2">
|
||||||
{{ __('No Matching Results') }}
|
{{ __('No Matching Results') }}
|
||||||
</gl-deprecated-dropdown-item>
|
</p>
|
||||||
<gl-loading-icon v-else />
|
<gl-loading-icon v-else />
|
||||||
</div>
|
</div>
|
||||||
</gl-deprecated-dropdown>
|
</gl-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<gl-loading-icon v-if="isUpdating" :inline="true" />
|
<gl-loading-icon v-if="isUpdating" :inline="true" />
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable vue/no-v-html */
|
/* eslint-disable vue/no-v-html */
|
||||||
|
import { GlIcon } from '@gitlab/ui';
|
||||||
import NoteHeader from '~/notes/components/note_header.vue';
|
import NoteHeader from '~/notes/components/note_header.vue';
|
||||||
import { spriteIcon } from '~/lib/utils/common_utils';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
NoteHeader,
|
NoteHeader,
|
||||||
|
GlIcon,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
note: {
|
note: {
|
||||||
|
@ -24,24 +25,24 @@ export default {
|
||||||
} = this.note;
|
} = this.note;
|
||||||
return { ...author, id: id?.split('/').pop() };
|
return { ...author, id: id?.split('/').pop() };
|
||||||
},
|
},
|
||||||
iconHtml() {
|
|
||||||
return spriteIcon(this.note?.systemNoteIconName);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<li :id="noteAnchorId" class="timeline-entry note system-note note-wrapper gl-px-0!">
|
<li :id="noteAnchorId" class="timeline-entry note system-note note-wrapper gl-p-0!">
|
||||||
<div class="timeline-entry-inner">
|
<div class="gl-display-inline-flex gl-align-items-center">
|
||||||
<div class="timeline-icon" v-html="iconHtml"></div>
|
<div
|
||||||
<div class="timeline-content">
|
class="gl-display-inline gl-bg-white gl-text-gray-200 gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-full gl-box-sizing-content-box gl-p-3 gl-mt-n2 gl-mr-6"
|
||||||
|
>
|
||||||
|
<gl-icon :name="note.systemNoteIconName" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="note-header">
|
<div class="note-header">
|
||||||
<note-header :author="noteAuthor" :created-at="note.createdAt" :note-id="note.id">
|
<note-header :author="noteAuthor" :created-at="note.createdAt" :note-id="note.id">
|
||||||
<span v-html="note.bodyHtml"></span>
|
<span v-html="note.bodyHtml"></span>
|
||||||
</note-header>
|
</note-header>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -63,5 +63,3 @@ export const trackAlertStatusUpdateOptions = {
|
||||||
action: 'update_alert_status',
|
action: 'update_alert_status',
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_PAGE_SIZE = 20;
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
|
||||||
|
import produce from 'immer';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import VueApollo from 'vue-apollo';
|
import VueApollo from 'vue-apollo';
|
||||||
import produce from 'immer';
|
|
||||||
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
|
|
||||||
import createDefaultClient from '~/lib/graphql';
|
import createDefaultClient from '~/lib/graphql';
|
||||||
import createRouter from './router';
|
|
||||||
import AlertDetails from './components/alert_details.vue';
|
import AlertDetails from './components/alert_details.vue';
|
||||||
import sidebarStatusQuery from './graphql/queries/sidebar_status.query.graphql';
|
import sidebarStatusQuery from './graphql/queries/sidebar_status.query.graphql';
|
||||||
|
import createRouter from './router';
|
||||||
|
|
||||||
Vue.use(VueApollo);
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,11 @@ fragment AlertDetailItem on AlertManagementAlert {
|
||||||
description
|
description
|
||||||
updatedAt
|
updatedAt
|
||||||
endedAt
|
endedAt
|
||||||
|
hosts
|
||||||
|
environment {
|
||||||
|
name
|
||||||
|
path
|
||||||
|
}
|
||||||
details
|
details
|
||||||
runbook
|
runbook
|
||||||
todos {
|
todos {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#import "../fragments/list_item.fragment.graphql"
|
#import "../fragments/list_item.fragment.graphql"
|
||||||
|
|
||||||
query getAlerts(
|
query getAlerts(
|
||||||
$searchTerm: String
|
|
||||||
$projectPath: ID!
|
$projectPath: ID!
|
||||||
$statuses: [AlertManagementStatus!]
|
$statuses: [AlertManagementStatus!]
|
||||||
$sort: AlertManagementAlertSort
|
$sort: AlertManagementAlertSort
|
||||||
|
@ -9,10 +8,13 @@ query getAlerts(
|
||||||
$lastPageSize: Int
|
$lastPageSize: Int
|
||||||
$prevPageCursor: String = ""
|
$prevPageCursor: String = ""
|
||||||
$nextPageCursor: String = ""
|
$nextPageCursor: String = ""
|
||||||
|
$searchTerm: String = ""
|
||||||
|
$assigneeUsername: String = ""
|
||||||
) {
|
) {
|
||||||
project(fullPath: $projectPath) {
|
project(fullPath: $projectPath) {
|
||||||
alertManagementAlerts(
|
alertManagementAlerts(
|
||||||
search: $searchTerm
|
search: $searchTerm
|
||||||
|
assigneeUsername: $assigneeUsername
|
||||||
statuses: $statuses
|
statuses: $statuses
|
||||||
sort: $sort
|
sort: $sort
|
||||||
first: $firstPageSize
|
first: $firstPageSize
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
query getAlertsCount($searchTerm: String, $projectPath: ID!) {
|
query getAlertsCount($searchTerm: String, $projectPath: ID!, $assigneeUsername: String = "") {
|
||||||
project(fullPath: $projectPath) {
|
project(fullPath: $projectPath) {
|
||||||
alertManagementAlertStatusCounts(search: $searchTerm) {
|
alertManagementAlertStatusCounts(search: $searchTerm, assigneeUsername: $assigneeUsername) {
|
||||||
all
|
all
|
||||||
open
|
open
|
||||||
acknowledged
|
acknowledged
|
||||||
|
|
|
@ -18,12 +18,12 @@ export default () => {
|
||||||
populatingAlertsHelpUrl,
|
populatingAlertsHelpUrl,
|
||||||
alertsHelpUrl,
|
alertsHelpUrl,
|
||||||
opsgenieMvcTargetUrl,
|
opsgenieMvcTargetUrl,
|
||||||
|
textQuery,
|
||||||
|
assigneeUsernameQuery,
|
||||||
|
alertManagementEnabled,
|
||||||
|
userCanEnableAlertManagement,
|
||||||
|
opsgenieMvcEnabled,
|
||||||
} = domEl.dataset;
|
} = domEl.dataset;
|
||||||
let { alertManagementEnabled, userCanEnableAlertManagement, opsgenieMvcEnabled } = domEl.dataset;
|
|
||||||
|
|
||||||
alertManagementEnabled = parseBoolean(alertManagementEnabled);
|
|
||||||
userCanEnableAlertManagement = parseBoolean(userCanEnableAlertManagement);
|
|
||||||
opsgenieMvcEnabled = parseBoolean(opsgenieMvcEnabled);
|
|
||||||
|
|
||||||
const apolloProvider = new VueApollo({
|
const apolloProvider = new VueApollo({
|
||||||
defaultClient: createDefaultClient(
|
defaultClient: createDefaultClient(
|
||||||
|
@ -50,23 +50,24 @@ export default () => {
|
||||||
|
|
||||||
return new Vue({
|
return new Vue({
|
||||||
el: selector,
|
el: selector,
|
||||||
|
provide: {
|
||||||
|
projectPath,
|
||||||
|
textQuery,
|
||||||
|
assigneeUsernameQuery,
|
||||||
|
enableAlertManagementPath,
|
||||||
|
populatingAlertsHelpUrl,
|
||||||
|
emptyAlertSvgPath,
|
||||||
|
opsgenieMvcTargetUrl,
|
||||||
|
alertManagementEnabled: parseBoolean(alertManagementEnabled),
|
||||||
|
userCanEnableAlertManagement: parseBoolean(userCanEnableAlertManagement),
|
||||||
|
opsgenieMvcEnabled: parseBoolean(opsgenieMvcEnabled),
|
||||||
|
},
|
||||||
apolloProvider,
|
apolloProvider,
|
||||||
components: {
|
components: {
|
||||||
AlertManagementList,
|
AlertManagementList,
|
||||||
},
|
},
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
return createElement('alert-management-list', {
|
return createElement('alert-management-list');
|
||||||
props: {
|
|
||||||
projectPath,
|
|
||||||
enableAlertManagementPath,
|
|
||||||
populatingAlertsHelpUrl,
|
|
||||||
emptyAlertSvgPath,
|
|
||||||
alertManagementEnabled,
|
|
||||||
userCanEnableAlertManagement,
|
|
||||||
opsgenieMvcTargetUrl,
|
|
||||||
opsgenieMvcEnabled,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -180,11 +180,9 @@ export default {
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="gl-display-flex gl-justify-content-end">
|
|
||||||
<gl-button v-gl-modal.authKeyModal class="gl-mt-2" :disabled="isDisabled">{{
|
<gl-button v-gl-modal.authKeyModal class="gl-mt-2" :disabled="isDisabled">{{
|
||||||
$options.RESET_KEY
|
$options.RESET_KEY
|
||||||
}}</gl-button>
|
}}</gl-button>
|
||||||
</span>
|
|
||||||
<gl-modal
|
<gl-modal
|
||||||
modal-id="authKeyModal"
|
modal-id="authKeyModal"
|
||||||
:title="$options.RESET_KEY"
|
:title="$options.RESET_KEY"
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
<script>
|
||||||
|
import { GlTable, GlIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||||
|
import { s__, __ } from '~/locale';
|
||||||
|
import Tracking from '~/tracking';
|
||||||
|
import { trackAlertIntergrationsViewsOptions } from '../constants';
|
||||||
|
|
||||||
|
export const i18n = {
|
||||||
|
title: s__('AlertsIntegrations|Current integrations'),
|
||||||
|
emptyState: s__('AlertsIntegrations|No integrations have been added yet'),
|
||||||
|
status: {
|
||||||
|
enabled: {
|
||||||
|
name: __('Enabled'),
|
||||||
|
tooltip: s__('AlertsIntegrations|Alerts will be created through this integration'),
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
name: __('Disabled'),
|
||||||
|
tooltip: s__('AlertsIntegrations|Alerts will not be created through this integration'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const bodyTrClass =
|
||||||
|
'gl-border-1 gl-border-t-solid gl-border-b-solid gl-border-gray-100 gl-hover-cursor-pointer gl-hover-bg-blue-50 gl-hover-border-blue-200';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
i18n,
|
||||||
|
components: {
|
||||||
|
GlTable,
|
||||||
|
GlIcon,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
integrations: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
key: 'activated',
|
||||||
|
label: __('Status'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'name',
|
||||||
|
label: s__('AlertsIntegrations|Integration Name'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'type',
|
||||||
|
label: __('Type'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
computed: {
|
||||||
|
tbodyTrClass() {
|
||||||
|
return {
|
||||||
|
[bodyTrClass]: this.integrations.length,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.trackPageViews();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
trackPageViews() {
|
||||||
|
const { category, action } = trackAlertIntergrationsViewsOptions;
|
||||||
|
Tracking.event(category, action);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="incident-management-list">
|
||||||
|
<h5 class="gl-font-lg">{{ $options.i18n.title }}</h5>
|
||||||
|
<gl-table
|
||||||
|
:empty-text="$options.i18n.emptyState"
|
||||||
|
:items="integrations"
|
||||||
|
:fields="$options.fields"
|
||||||
|
stacked="md"
|
||||||
|
:tbody-tr-class="tbodyTrClass"
|
||||||
|
show-empty
|
||||||
|
>
|
||||||
|
<template #cell(activated)="{ item }">
|
||||||
|
<span v-if="item.activated" data-testid="integration-activated-status">
|
||||||
|
<gl-icon
|
||||||
|
v-gl-tooltip
|
||||||
|
name="check-circle-filled"
|
||||||
|
:size="16"
|
||||||
|
class="gl-text-green-500 gl-hover-cursor-pointer gl-mr-3"
|
||||||
|
:title="$options.i18n.status.enabled.tooltip"
|
||||||
|
/>
|
||||||
|
{{ $options.i18n.status.enabled.name }}
|
||||||
|
</span>
|
||||||
|
<span v-else data-testid="integration-activated-status">
|
||||||
|
<gl-icon
|
||||||
|
v-gl-tooltip
|
||||||
|
name="warning-solid"
|
||||||
|
:size="16"
|
||||||
|
class="gl-text-red-600 gl-hover-cursor-pointer gl-mr-3"
|
||||||
|
:title="$options.i18n.status.disabled.tooltip"
|
||||||
|
/>
|
||||||
|
{{ $options.i18n.status.disabled.name }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</gl-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -14,9 +14,11 @@ import {
|
||||||
GlFormSelect,
|
GlFormSelect,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
import { s__ } from '~/locale';
|
||||||
|
import { doesHashExistInUrl } from '~/lib/utils/url_utility';
|
||||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||||
import ToggleButton from '~/vue_shared/components/toggle_button.vue';
|
import ToggleButton from '~/vue_shared/components/toggle_button.vue';
|
||||||
|
import IntegrationsList from './alerts_integrations_list.vue';
|
||||||
import csrf from '~/lib/utils/csrf';
|
import csrf from '~/lib/utils/csrf';
|
||||||
import service from '../services';
|
import service from '../services';
|
||||||
import {
|
import {
|
||||||
|
@ -25,7 +27,9 @@ import {
|
||||||
JSON_VALIDATE_DELAY,
|
JSON_VALIDATE_DELAY,
|
||||||
targetPrometheusUrlPlaceholder,
|
targetPrometheusUrlPlaceholder,
|
||||||
targetOpsgenieUrlPlaceholder,
|
targetOpsgenieUrlPlaceholder,
|
||||||
|
sectionHash,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
import createFlash, { FLASH_TYPES } from '~/flash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
i18n,
|
i18n,
|
||||||
|
@ -46,11 +50,11 @@ export default {
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
ClipboardButton,
|
ClipboardButton,
|
||||||
ToggleButton,
|
ToggleButton,
|
||||||
|
IntegrationsList,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'gl-modal': GlModalDirective,
|
'gl-modal': GlModalDirective,
|
||||||
},
|
},
|
||||||
mixins: [glFeatureFlagsMixin()],
|
|
||||||
inject: ['prometheus', 'generic', 'opsgenie'],
|
inject: ['prometheus', 'generic', 'opsgenie'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -148,6 +152,20 @@ export default {
|
||||||
? this.$options.targetOpsgenieUrlPlaceholder
|
? this.$options.targetOpsgenieUrlPlaceholder
|
||||||
: this.$options.targetPrometheusUrlPlaceholder;
|
: this.$options.targetPrometheusUrlPlaceholder;
|
||||||
},
|
},
|
||||||
|
integrations() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: s__('AlertSettings|HTTP endpoint'),
|
||||||
|
type: s__('AlertsIntegrations|HTTP endpoint'),
|
||||||
|
activated: this.generic.activated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: s__('AlertSettings|External Prometheus'),
|
||||||
|
type: s__('AlertsIntegrations|Prometheus'),
|
||||||
|
activated: this.prometheus.activated,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'testAlert.json': debounce(function debouncedJsonValidate() {
|
'testAlert.json': debounce(function debouncedJsonValidate() {
|
||||||
|
@ -173,9 +191,12 @@ export default {
|
||||||
this.authKey = this.selectedService.authKey ?? '';
|
this.authKey = this.selectedService.authKey ?? '';
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createUserErrorMessage(errors = { error: [''] }) {
|
createUserErrorMessage(errors = {}) {
|
||||||
// eslint-disable-next-line prefer-destructuring
|
const error = Object.entries(errors)?.[0];
|
||||||
this.serverError = errors.error[0];
|
if (error) {
|
||||||
|
const [field, [msg]] = error;
|
||||||
|
this.serverError = `${field} ${msg}`;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setOpsgenieAsDefault() {
|
setOpsgenieAsDefault() {
|
||||||
this.options = this.options.map(el => {
|
this.options = this.options.map(el => {
|
||||||
|
@ -245,29 +266,11 @@ export default {
|
||||||
? { service: { opsgenie_mvc_target_url: this.targetUrl, opsgenie_mvc_enabled: value } }
|
? { service: { opsgenie_mvc_target_url: this.targetUrl, opsgenie_mvc_enabled: value } }
|
||||||
: { service: { active: value } },
|
: { service: { active: value } },
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => this.notifySuccessAndReload())
|
||||||
this.active = 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 } = {} } = {} }) => {
|
.catch(({ response: { data: { errors } = {} } = {} }) => {
|
||||||
this.createUserErrorMessage(errors);
|
this.createUserErrorMessage(errors);
|
||||||
this.setFeedback({
|
this.setFeedback({
|
||||||
feedbackMessage: `${this.$options.i18n.errorMsg}.`,
|
feedbackMessage: this.$options.i18n.errorMsg,
|
||||||
variant: 'danger',
|
variant: 'danger',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -276,6 +279,12 @@ export default {
|
||||||
this.canSaveForm = false;
|
this.canSaveForm = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
reload() {
|
||||||
|
if (!doesHashExistInUrl(sectionHash)) {
|
||||||
|
window.location.hash = sectionHash;
|
||||||
|
}
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
togglePrometheusActive(value) {
|
togglePrometheusActive(value) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
return service
|
return service
|
||||||
|
@ -288,15 +297,11 @@ export default {
|
||||||
redirect: window.location,
|
redirect: window.location,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => this.notifySuccessAndReload())
|
||||||
this.active = value;
|
|
||||||
this.toggleSuccess(value);
|
|
||||||
this.removeOpsGenieOption();
|
|
||||||
})
|
|
||||||
.catch(({ response: { data: { errors } = {} } = {} }) => {
|
.catch(({ response: { data: { errors } = {} } = {} }) => {
|
||||||
this.createUserErrorMessage(errors);
|
this.createUserErrorMessage(errors);
|
||||||
this.setFeedback({
|
this.setFeedback({
|
||||||
feedbackMessage: `${this.$options.i18n.errorMsg}.`,
|
feedbackMessage: this.$options.i18n.errorMsg,
|
||||||
variant: 'danger',
|
variant: 'danger',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -305,18 +310,9 @@ export default {
|
||||||
this.canSaveForm = false;
|
this.canSaveForm = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toggleSuccess(value) {
|
notifySuccessAndReload() {
|
||||||
if (value) {
|
createFlash({ message: this.$options.i18n.changesSaved, type: FLASH_TYPES.NOTICE });
|
||||||
this.setFeedback({
|
setTimeout(() => this.reload(), 1000);
|
||||||
feedbackMessage: this.$options.i18n.endPointActivated,
|
|
||||||
variant: 'info',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setFeedback({
|
|
||||||
feedbackMessage: this.$options.i18n.changesSaved,
|
|
||||||
variant: 'info',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setFeedback({ feedbackMessage, variant }) {
|
setFeedback({ feedbackMessage, variant }) {
|
||||||
this.feedback = { feedbackMessage, variant };
|
this.feedback = { feedbackMessage, variant };
|
||||||
|
@ -375,6 +371,11 @@ export default {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<integrations-list :integrations="integrations" />
|
||||||
|
|
||||||
|
<gl-form @submit.prevent="onSubmit" @reset.prevent="onReset">
|
||||||
|
<h5 class="gl-font-lg gl-my-5">{{ $options.i18n.integrationsLabel }}</h5>
|
||||||
|
|
||||||
<gl-alert v-if="showFeedbackMsg" :variant="feedback.variant" @dismiss="dismissFeedback">
|
<gl-alert v-if="showFeedbackMsg" :variant="feedback.variant" @dismiss="dismissFeedback">
|
||||||
{{ feedback.feedbackMessage }}
|
{{ feedback.feedbackMessage }}
|
||||||
<br />
|
<br />
|
||||||
|
@ -389,7 +390,8 @@ export default {
|
||||||
{{ __('Save anyway') }}
|
{{ __('Save anyway') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
<div data-testid="alert-settings-description" class="gl-mt-5">
|
|
||||||
|
<div data-testid="alert-settings-description">
|
||||||
<p v-for="section in sections" :key="section.text">
|
<p v-for="section in sections" :key="section.text">
|
||||||
<gl-sprintf :message="section.text">
|
<gl-sprintf :message="section.text">
|
||||||
<template #link="{ content }">
|
<template #link="{ content }">
|
||||||
|
@ -398,24 +400,21 @@ export default {
|
||||||
</gl-sprintf>
|
</gl-sprintf>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<gl-form @submit.prevent="onSubmit" @reset.prevent="onReset">
|
|
||||||
<gl-form-group
|
<gl-form-group label-for="integration-type" :label="$options.i18n.integration">
|
||||||
:label="$options.i18n.integrationsLabel"
|
|
||||||
label-for="integrations"
|
|
||||||
label-class="label-bold"
|
|
||||||
>
|
|
||||||
<gl-form-select
|
<gl-form-select
|
||||||
|
id="integration-type"
|
||||||
v-model="selectedEndpoint"
|
v-model="selectedEndpoint"
|
||||||
:options="options"
|
:options="options"
|
||||||
data-testid="alert-settings-select"
|
data-testid="alert-settings-select"
|
||||||
@change="resetFormValues"
|
@change="resetFormValues"
|
||||||
/>
|
/>
|
||||||
<span class="gl-text-gray-200">
|
<span class="gl-text-gray-500">
|
||||||
<gl-sprintf :message="$options.i18n.integrationsInfo">
|
<gl-sprintf :message="$options.i18n.integrationsInfo">
|
||||||
<template #link="{ content }">
|
<template #link="{ content }">
|
||||||
<gl-link
|
<gl-link
|
||||||
class="gl-display-inline-block"
|
class="gl-display-inline-block"
|
||||||
href="https://gitlab.com/groups/gitlab-org/-/epics/3362"
|
href="https://gitlab.com/groups/gitlab-org/-/epics/4390"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ content }}</gl-link
|
>{{ content }}</gl-link
|
||||||
>
|
>
|
||||||
|
@ -423,11 +422,7 @@ export default {
|
||||||
</gl-sprintf>
|
</gl-sprintf>
|
||||||
</span>
|
</span>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
<gl-form-group
|
<gl-form-group :label="$options.i18n.activeLabel" label-for="activated">
|
||||||
:label="$options.i18n.activeLabel"
|
|
||||||
label-for="activated"
|
|
||||||
label-class="label-bold"
|
|
||||||
>
|
|
||||||
<toggle-button
|
<toggle-button
|
||||||
id="activated"
|
id="activated"
|
||||||
:disabled-input="loading"
|
:disabled-input="loading"
|
||||||
|
@ -440,7 +435,6 @@ export default {
|
||||||
v-if="isOpsgenie || isPrometheus"
|
v-if="isOpsgenie || isPrometheus"
|
||||||
:label="$options.i18n.apiBaseUrlLabel"
|
:label="$options.i18n.apiBaseUrlLabel"
|
||||||
label-for="api-url"
|
label-for="api-url"
|
||||||
label-class="label-bold"
|
|
||||||
>
|
>
|
||||||
<gl-form-input
|
<gl-form-input
|
||||||
id="api-url"
|
id="api-url"
|
||||||
|
@ -449,12 +443,12 @@ export default {
|
||||||
:placeholder="baseUrlPlaceholder"
|
:placeholder="baseUrlPlaceholder"
|
||||||
:disabled="!active"
|
:disabled="!active"
|
||||||
/>
|
/>
|
||||||
<span class="gl-text-gray-200">
|
<span class="gl-text-gray-500">
|
||||||
{{ $options.i18n.apiBaseUrlHelpText }}
|
{{ $options.i18n.apiBaseUrlHelpText }}
|
||||||
</span>
|
</span>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
<template v-if="!isOpsgenie">
|
<template v-if="!isOpsgenie">
|
||||||
<gl-form-group :label="$options.i18n.urlLabel" label-for="url" label-class="label-bold">
|
<gl-form-group :label="$options.i18n.urlLabel" label-for="url">
|
||||||
<gl-form-input-group id="url" readonly :value="selectedService.url">
|
<gl-form-input-group id="url" readonly :value="selectedService.url">
|
||||||
<template #append>
|
<template #append>
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
|
@ -464,15 +458,11 @@ export default {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</gl-form-input-group>
|
</gl-form-input-group>
|
||||||
<span class="gl-text-gray-200">
|
<span class="gl-text-gray-500">
|
||||||
{{ prometheusInfo }}
|
{{ prometheusInfo }}
|
||||||
</span>
|
</span>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
<gl-form-group
|
<gl-form-group :label="$options.i18n.authKeyLabel" label-for="authorization-key">
|
||||||
: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="authKey">
|
<gl-form-input-group id="authorization-key" class="gl-mb-2" readonly :value="authKey">
|
||||||
<template #append>
|
<template #append>
|
||||||
<clipboard-button
|
<clipboard-button
|
||||||
|
@ -498,7 +488,6 @@ export default {
|
||||||
<gl-form-group
|
<gl-form-group
|
||||||
:label="$options.i18n.alertJson"
|
:label="$options.i18n.alertJson"
|
||||||
label-for="alert-json"
|
label-for="alert-json"
|
||||||
label-class="label-bold"
|
|
||||||
:invalid-feedback="testAlert.error"
|
:invalid-feedback="testAlert.error"
|
||||||
>
|
>
|
||||||
<gl-form-textarea
|
<gl-form-textarea
|
||||||
|
@ -511,16 +500,11 @@ export default {
|
||||||
max-rows="10"
|
max-rows="10"
|
||||||
/>
|
/>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
<div class="gl-display-flex gl-justify-content-end">
|
|
||||||
<gl-button :disabled="!canTestAlert" @click="validateTestAlert">{{
|
<gl-button :disabled="!canTestAlert" @click="validateTestAlert">{{
|
||||||
$options.i18n.testAlertInfo
|
$options.i18n.testAlertInfo
|
||||||
}}</gl-button>
|
}}</gl-button>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<div class="footer-block row-content-block gl-display-flex gl-justify-content-space-between">
|
<div class="footer-block row-content-block gl-display-flex gl-justify-content-space-between">
|
||||||
<gl-button category="primary" :disabled="!canSaveConfig" @click="onReset">
|
|
||||||
{{ __('Cancel') }}
|
|
||||||
</gl-button>
|
|
||||||
<gl-button
|
<gl-button
|
||||||
variant="success"
|
variant="success"
|
||||||
category="primary"
|
category="primary"
|
||||||
|
@ -529,6 +513,9 @@ export default {
|
||||||
>
|
>
|
||||||
{{ __('Save changes') }}
|
{{ __('Save changes') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
|
<gl-button category="primary" :disabled="!canSaveConfig" @click="onReset">
|
||||||
|
{{ __('Cancel') }}
|
||||||
|
</gl-button>
|
||||||
</div>
|
</div>
|
||||||
</gl-form>
|
</gl-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,22 +7,21 @@ export const i18n = {
|
||||||
setupSection: s__(
|
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.",
|
"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'),
|
errorMsg: s__('AlertSettings|There was an error updating the alert settings.'),
|
||||||
errorKeyMsg: s__(
|
errorKeyMsg: s__(
|
||||||
'AlertSettings|There was an error while trying to reset the key. Please refresh the page to try again.',
|
'AlertSettings|There was an error while trying to reset the key. Please refresh the page to try again.',
|
||||||
),
|
),
|
||||||
restKeyInfo: s__(
|
restKeyInfo: s__(
|
||||||
'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.',
|
'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 integration was successfully updated.'),
|
||||||
changesSaved: s__('AlertSettings|Your changes were successfully updated.'),
|
|
||||||
prometheusInfo: s__('AlertSettings|Add URL and auth key to your Prometheus config file'),
|
prometheusInfo: s__('AlertSettings|Add URL and auth key to your Prometheus config file'),
|
||||||
integrationsInfo: s__(
|
integrationsInfo: s__(
|
||||||
'AlertSettings|Learn more about our %{linkStart}upcoming integrations%{linkEnd}',
|
'AlertSettings|Learn more about our improvements for %{linkStart}integrations%{linkEnd}',
|
||||||
),
|
),
|
||||||
resetKey: s__('AlertSettings|Reset key'),
|
resetKey: s__('AlertSettings|Reset key'),
|
||||||
copyToClipboard: s__('AlertSettings|Copy'),
|
copyToClipboard: s__('AlertSettings|Copy'),
|
||||||
integrationsLabel: s__('AlertSettings|Integrations'),
|
integrationsLabel: s__('AlertSettings|Add new integrations'),
|
||||||
apiBaseUrlLabel: s__('AlertSettings|API URL'),
|
apiBaseUrlLabel: s__('AlertSettings|API URL'),
|
||||||
authKeyLabel: s__('AlertSettings|Authorization key'),
|
authKeyLabel: s__('AlertSettings|Authorization key'),
|
||||||
urlLabel: s__('AlertSettings|Webhook URL'),
|
urlLabel: s__('AlertSettings|Webhook URL'),
|
||||||
|
@ -38,10 +37,11 @@ export const i18n = {
|
||||||
authKeyRest: s__(
|
authKeyRest: s__(
|
||||||
'AlertSettings|Authorization key has been successfully reset. Please save your changes now.',
|
'AlertSettings|Authorization key has been successfully reset. Please save your changes now.',
|
||||||
),
|
),
|
||||||
|
integration: s__('AlertSettings|Integration'),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const serviceOptions = [
|
export const serviceOptions = [
|
||||||
{ value: 'generic', text: s__('AlertSettings|Generic') },
|
{ value: 'generic', text: s__('AlertSettings|HTTP Endpoint') },
|
||||||
{ value: 'prometheus', text: s__('AlertSettings|External Prometheus') },
|
{ value: 'prometheus', text: s__('AlertSettings|External Prometheus') },
|
||||||
{ value: 'opsgenie', text: s__('AlertSettings|Opsgenie') },
|
{ value: 'opsgenie', text: s__('AlertSettings|Opsgenie') },
|
||||||
];
|
];
|
||||||
|
@ -50,3 +50,15 @@ export const JSON_VALIDATE_DELAY = 250;
|
||||||
|
|
||||||
export const targetPrometheusUrlPlaceholder = 'http://prometheus.example.com/';
|
export const targetPrometheusUrlPlaceholder = 'http://prometheus.example.com/';
|
||||||
export const targetOpsgenieUrlPlaceholder = 'https://app.opsgenie.com/alert/list/';
|
export const targetOpsgenieUrlPlaceholder = 'https://app.opsgenie.com/alert/list/';
|
||||||
|
|
||||||
|
export const sectionHash = 'js-alert-management-settings';
|
||||||
|
|
||||||
|
/* eslint-disable @gitlab/require-i18n-strings */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks snowplow event when user views alerts intergration list
|
||||||
|
*/
|
||||||
|
export const trackAlertIntergrationsViewsOptions = {
|
||||||
|
category: 'Alert Intergrations',
|
||||||
|
action: 'view_alert_integrations_list',
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<script>
|
||||||
|
import InstanceCounts from './instance_counts.vue';
|
||||||
|
import PipelinesChart from './pipelines_chart.vue';
|
||||||
|
import UsersChart from './users_chart.vue';
|
||||||
|
import { TODAY, TOTAL_DAYS_TO_SHOW, START_DATE } from '../constants';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'InstanceStatisticsApp',
|
||||||
|
components: {
|
||||||
|
InstanceCounts,
|
||||||
|
PipelinesChart,
|
||||||
|
UsersChart,
|
||||||
|
},
|
||||||
|
TOTAL_DAYS_TO_SHOW,
|
||||||
|
START_DATE,
|
||||||
|
TODAY,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<instance-counts />
|
||||||
|
<users-chart
|
||||||
|
:start-date="$options.START_DATE"
|
||||||
|
:end-date="$options.TODAY"
|
||||||
|
:total-data-points="$options.TOTAL_DAYS_TO_SHOW"
|
||||||
|
/>
|
||||||
|
<pipelines-chart />
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,64 @@
|
||||||
|
<script>
|
||||||
|
import * as Sentry from '~/sentry/wrapper';
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
import { deprecatedCreateFlash as createFlash } from '~/flash';
|
||||||
|
import { SUPPORTED_FORMATS, getFormatter } from '~/lib/utils/unit_format';
|
||||||
|
import MetricCard from '~/analytics/shared/components/metric_card.vue';
|
||||||
|
import instanceStatisticsCountQuery from '../graphql/queries/instance_statistics_count.query.graphql';
|
||||||
|
|
||||||
|
const defaultPrecision = 0;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'InstanceCounts',
|
||||||
|
components: {
|
||||||
|
MetricCard,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
counts: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
apollo: {
|
||||||
|
counts: {
|
||||||
|
query: instanceStatisticsCountQuery,
|
||||||
|
update(data) {
|
||||||
|
return Object.entries(data).map(([key, obj]) => {
|
||||||
|
const label = this.$options.i18n.labels[key];
|
||||||
|
const formatter = getFormatter(SUPPORTED_FORMATS.number);
|
||||||
|
const value = obj.nodes?.length ? formatter(obj.nodes[0].count, defaultPrecision) : null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error(error) {
|
||||||
|
createFlash(this.$options.i18n.loadCountsError);
|
||||||
|
Sentry.captureException(error);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
labels: {
|
||||||
|
users: s__('InstanceStatistics|Users'),
|
||||||
|
projects: s__('InstanceStatistics|Projects'),
|
||||||
|
groups: s__('InstanceStatistics|Groups'),
|
||||||
|
issues: s__('InstanceStatistics|Issues'),
|
||||||
|
mergeRequests: s__('InstanceStatistics|Merge Requests'),
|
||||||
|
pipelines: s__('InstanceStatistics|Pipelines'),
|
||||||
|
},
|
||||||
|
loadCountsError: s__('Could not load instance counts. Please refresh the page to try again.'),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<metric-card
|
||||||
|
:title="__('Instance Statistics')"
|
||||||
|
:metrics="counts"
|
||||||
|
:is-loading="$apollo.queries.counts.loading"
|
||||||
|
class="gl-mt-4"
|
||||||
|
/>
|
||||||
|
</template>
|
|
@ -0,0 +1,215 @@
|
||||||
|
<script>
|
||||||
|
import { GlLineChart } from '@gitlab/ui/dist/charts';
|
||||||
|
import { GlAlert } from '@gitlab/ui';
|
||||||
|
import { mapKeys, mapValues, pick, some, sum } from 'lodash';
|
||||||
|
import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
import {
|
||||||
|
differenceInMonths,
|
||||||
|
formatDateAsMonth,
|
||||||
|
getDayDifference,
|
||||||
|
} from '~/lib/utils/datetime_utility';
|
||||||
|
import { getAverageByMonth, sortByDate, extractValues } from '../utils';
|
||||||
|
import pipelineStatsQuery from '../graphql/queries/pipeline_stats.query.graphql';
|
||||||
|
import { TODAY, START_DATE } from '../constants';
|
||||||
|
|
||||||
|
const DATA_KEYS = [
|
||||||
|
'pipelinesTotal',
|
||||||
|
'pipelinesSucceeded',
|
||||||
|
'pipelinesFailed',
|
||||||
|
'pipelinesCanceled',
|
||||||
|
'pipelinesSkipped',
|
||||||
|
];
|
||||||
|
const PREFIX = 'pipelines';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'PipelinesChart',
|
||||||
|
components: {
|
||||||
|
GlLineChart,
|
||||||
|
GlAlert,
|
||||||
|
ChartSkeletonLoader,
|
||||||
|
},
|
||||||
|
startDate: START_DATE,
|
||||||
|
endDate: TODAY,
|
||||||
|
i18n: {
|
||||||
|
loadPipelineChartError: s__(
|
||||||
|
'InstanceAnalytics|Could not load the pipelines chart. Please refresh the page to try again.',
|
||||||
|
),
|
||||||
|
noDataMessage: s__('InstanceAnalytics|There is no data available.'),
|
||||||
|
total: s__('InstanceAnalytics|Total'),
|
||||||
|
succeeded: s__('InstanceAnalytics|Succeeded'),
|
||||||
|
failed: s__('InstanceAnalytics|Failed'),
|
||||||
|
canceled: s__('InstanceAnalytics|Canceled'),
|
||||||
|
skipped: s__('InstanceAnalytics|Skipped'),
|
||||||
|
chartTitle: s__('InstanceAnalytics|Pipelines'),
|
||||||
|
yAxisTitle: s__('InstanceAnalytics|Items'),
|
||||||
|
xAxisTitle: s__('InstanceAnalytics|Month'),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: true,
|
||||||
|
loadingError: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
apollo: {
|
||||||
|
pipelineStats: {
|
||||||
|
query: pipelineStatsQuery,
|
||||||
|
variables() {
|
||||||
|
return {
|
||||||
|
firstTotal: this.totalDaysToShow,
|
||||||
|
firstSucceeded: this.totalDaysToShow,
|
||||||
|
firstFailed: this.totalDaysToShow,
|
||||||
|
firstCanceled: this.totalDaysToShow,
|
||||||
|
firstSkipped: this.totalDaysToShow,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
update(data) {
|
||||||
|
const allData = extractValues(data, DATA_KEYS, PREFIX, 'nodes');
|
||||||
|
const allPageInfo = extractValues(data, DATA_KEYS, PREFIX, 'pageInfo');
|
||||||
|
|
||||||
|
return {
|
||||||
|
...mapValues(allData, sortByDate),
|
||||||
|
...allPageInfo,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
result() {
|
||||||
|
if (this.hasNextPage) {
|
||||||
|
this.fetchNextPage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error() {
|
||||||
|
this.handleError();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isLoading() {
|
||||||
|
return this.$apollo.queries.pipelineStats.loading;
|
||||||
|
},
|
||||||
|
totalDaysToShow() {
|
||||||
|
return getDayDifference(this.$options.startDate, this.$options.endDate);
|
||||||
|
},
|
||||||
|
firstVariables() {
|
||||||
|
const allData = pick(this.pipelineStats, [
|
||||||
|
'nodesTotal',
|
||||||
|
'nodesSucceeded',
|
||||||
|
'nodesFailed',
|
||||||
|
'nodesCanceled',
|
||||||
|
'nodesSkipped',
|
||||||
|
]);
|
||||||
|
const allDayDiffs = mapValues(allData, data => {
|
||||||
|
const firstdataPoint = data[0];
|
||||||
|
if (!firstdataPoint) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(
|
||||||
|
0,
|
||||||
|
getDayDifference(this.$options.startDate, new Date(firstdataPoint.recordedAt)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return mapKeys(allDayDiffs, (value, key) => key.replace('nodes', 'first'));
|
||||||
|
},
|
||||||
|
cursorVariables() {
|
||||||
|
const pageInfoKeys = [
|
||||||
|
'pageInfoTotal',
|
||||||
|
'pageInfoSucceeded',
|
||||||
|
'pageInfoFailed',
|
||||||
|
'pageInfoCanceled',
|
||||||
|
'pageInfoSkipped',
|
||||||
|
];
|
||||||
|
|
||||||
|
return extractValues(this.pipelineStats, pageInfoKeys, 'pageInfo', 'endCursor');
|
||||||
|
},
|
||||||
|
hasNextPage() {
|
||||||
|
return (
|
||||||
|
sum(Object.values(this.firstVariables)) > 0 &&
|
||||||
|
some(this.pipelineStats, ({ hasNextPage }) => hasNextPage)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
hasEmptyDataSet() {
|
||||||
|
return this.chartData.every(({ data }) => data.length === 0);
|
||||||
|
},
|
||||||
|
chartData() {
|
||||||
|
const allData = pick(this.pipelineStats, [
|
||||||
|
'nodesTotal',
|
||||||
|
'nodesSucceeded',
|
||||||
|
'nodesFailed',
|
||||||
|
'nodesCanceled',
|
||||||
|
'nodesSkipped',
|
||||||
|
]);
|
||||||
|
const options = { shouldRound: true };
|
||||||
|
return Object.keys(allData).map(key => {
|
||||||
|
const i18nName = key.slice('nodes'.length).toLowerCase();
|
||||||
|
return {
|
||||||
|
name: this.$options.i18n[i18nName],
|
||||||
|
data: getAverageByMonth(allData[key], options),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
range() {
|
||||||
|
return {
|
||||||
|
min: this.$options.startDate,
|
||||||
|
max: this.$options.endDate,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
chartOptions() {
|
||||||
|
const { endDate, startDate, i18n } = this.$options;
|
||||||
|
return {
|
||||||
|
xAxis: {
|
||||||
|
...this.range,
|
||||||
|
name: i18n.xAxisTitle,
|
||||||
|
type: 'time',
|
||||||
|
splitNumber: differenceInMonths(startDate, endDate) + 1,
|
||||||
|
axisLabel: {
|
||||||
|
interval: 0,
|
||||||
|
showMinLabel: false,
|
||||||
|
showMaxLabel: false,
|
||||||
|
align: 'right',
|
||||||
|
formatter: formatDateAsMonth,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
name: i18n.yAxisTitle,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleError() {
|
||||||
|
this.loadingError = true;
|
||||||
|
},
|
||||||
|
fetchNextPage() {
|
||||||
|
this.$apollo.queries.pipelineStats
|
||||||
|
.fetchMore({
|
||||||
|
variables: {
|
||||||
|
...this.firstVariables,
|
||||||
|
...this.cursorVariables,
|
||||||
|
},
|
||||||
|
updateQuery: (previousResult, { fetchMoreResult }) => {
|
||||||
|
return Object.keys(fetchMoreResult).reduce((memo, key) => {
|
||||||
|
const { nodes, ...rest } = fetchMoreResult[key];
|
||||||
|
const previousNodes = previousResult[key].nodes;
|
||||||
|
return { ...memo, [key]: { ...rest, nodes: [...previousNodes, ...nodes] } };
|
||||||
|
}, {});
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(this.handleError);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>{{ $options.i18n.chartTitle }}</h3>
|
||||||
|
<gl-alert v-if="loadingError" variant="danger" :dismissible="false" class="gl-mt-3">
|
||||||
|
{{ this.$options.i18n.loadPipelineChartError }}
|
||||||
|
</gl-alert>
|
||||||
|
<chart-skeleton-loader v-else-if="isLoading" />
|
||||||
|
<gl-alert v-else-if="hasEmptyDataSet" variant="info" :dismissible="false" class="gl-mt-3">
|
||||||
|
{{ $options.i18n.noDataMessage }}
|
||||||
|
</gl-alert>
|
||||||
|
<gl-line-chart v-else :option="chartOptions" :include-legend-avg-max="true" :data="chartData" />
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,143 @@
|
||||||
|
<script>
|
||||||
|
import { GlAlert } from '@gitlab/ui';
|
||||||
|
import { GlAreaChart } from '@gitlab/ui/dist/charts';
|
||||||
|
import produce from 'immer';
|
||||||
|
import { sortBy } from 'lodash';
|
||||||
|
import * as Sentry from '~/sentry/wrapper';
|
||||||
|
import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
|
||||||
|
import { __ } from '~/locale';
|
||||||
|
import { formatDateAsMonth } from '~/lib/utils/datetime_utility';
|
||||||
|
import usersQuery from '../graphql/queries/users.query.graphql';
|
||||||
|
import { getAverageByMonth } from '../utils';
|
||||||
|
|
||||||
|
const sortByDate = data => sortBy(data, item => new Date(item[0]).getTime());
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UsersChart',
|
||||||
|
components: { GlAlert, GlAreaChart, ChartSkeletonLoader },
|
||||||
|
props: {
|
||||||
|
startDate: {
|
||||||
|
type: Date,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
endDate: {
|
||||||
|
type: Date,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
totalDataPoints: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loadingError: null,
|
||||||
|
users: [],
|
||||||
|
pageInfo: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
apollo: {
|
||||||
|
users: {
|
||||||
|
query: usersQuery,
|
||||||
|
variables() {
|
||||||
|
return {
|
||||||
|
first: this.totalDataPoints,
|
||||||
|
after: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
update(data) {
|
||||||
|
return data.users?.nodes || [];
|
||||||
|
},
|
||||||
|
result({ data }) {
|
||||||
|
const {
|
||||||
|
users: { pageInfo },
|
||||||
|
} = data;
|
||||||
|
this.pageInfo = pageInfo;
|
||||||
|
this.fetchNextPage();
|
||||||
|
},
|
||||||
|
error(error) {
|
||||||
|
this.handleError(error);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
yAxisTitle: __('Total users'),
|
||||||
|
xAxisTitle: __('Month'),
|
||||||
|
loadUserChartError: __('Could not load the user chart. Please refresh the page to try again.'),
|
||||||
|
noDataMessage: __('There is no data available.'),
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isLoading() {
|
||||||
|
return this.$apollo.queries.users.loading || this.pageInfo?.hasNextPage;
|
||||||
|
},
|
||||||
|
chartUserData() {
|
||||||
|
const averaged = getAverageByMonth(
|
||||||
|
this.users.length > this.totalDataPoints
|
||||||
|
? this.users.slice(0, this.totalDataPoints)
|
||||||
|
: this.users,
|
||||||
|
{ shouldRound: true },
|
||||||
|
);
|
||||||
|
return sortByDate(averaged);
|
||||||
|
},
|
||||||
|
options() {
|
||||||
|
return {
|
||||||
|
xAxis: {
|
||||||
|
name: this.$options.i18n.xAxisTitle,
|
||||||
|
type: 'category',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: formatDateAsMonth,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
name: this.$options.i18n.yAxisTitle,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleError(error) {
|
||||||
|
this.loadingError = true;
|
||||||
|
this.users = [];
|
||||||
|
Sentry.captureException(error);
|
||||||
|
},
|
||||||
|
fetchNextPage() {
|
||||||
|
if (this.pageInfo?.hasNextPage) {
|
||||||
|
this.$apollo.queries.users
|
||||||
|
.fetchMore({
|
||||||
|
variables: { first: this.totalDataPoints, after: this.pageInfo.endCursor },
|
||||||
|
updateQuery: (previousResult, { fetchMoreResult }) => {
|
||||||
|
return produce(fetchMoreResult, newUsers => {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
newUsers.users.nodes = [...previousResult.users.nodes, ...newUsers.users.nodes];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(this.handleError);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>{{ $options.i18n.yAxisTitle }}</h3>
|
||||||
|
<gl-alert v-if="loadingError" variant="danger" :dismissible="false" class="gl-mt-3">
|
||||||
|
{{ this.$options.i18n.loadUserChartError }}
|
||||||
|
</gl-alert>
|
||||||
|
<chart-skeleton-loader v-else-if="isLoading" />
|
||||||
|
<gl-alert v-else-if="!chartUserData.length" variant="info" :dismissible="false" class="gl-mt-3">
|
||||||
|
{{ $options.i18n.noDataMessage }}
|
||||||
|
</gl-alert>
|
||||||
|
<gl-area-chart
|
||||||
|
v-else
|
||||||
|
:option="options"
|
||||||
|
:include-legend-avg-max="true"
|
||||||
|
:data="[
|
||||||
|
{
|
||||||
|
name: $options.i18n.yAxisTitle,
|
||||||
|
data: chartUserData,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { getDateInPast } from '~/lib/utils/datetime_utility';
|
||||||
|
|
||||||
|
export const TOTAL_DAYS_TO_SHOW = 365;
|
||||||
|
export const TODAY = new Date();
|
||||||
|
export const START_DATE = getDateInPast(TODAY, TOTAL_DAYS_TO_SHOW);
|
|
@ -0,0 +1,4 @@
|
||||||
|
fragment Count on InstanceStatisticsMeasurement {
|
||||||
|
count
|
||||||
|
recordedAt
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
fragment Count on InstanceStatisticsMeasurement {
|
||||||
|
count
|
||||||
|
recordedAt
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#import "../fragments/count.fragment.graphql"
|
||||||
|
|
||||||
|
query getInstanceCounts {
|
||||||
|
projects: instanceStatisticsMeasurements(identifier: PROJECTS, first: 1) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groups: instanceStatisticsMeasurements(identifier: GROUPS, first: 1) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
users: instanceStatisticsMeasurements(identifier: USERS, first: 1) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
issues: instanceStatisticsMeasurements(identifier: ISSUES, first: 1) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mergeRequests: instanceStatisticsMeasurements(identifier: MERGE_REQUESTS, first: 1) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipelines: instanceStatisticsMeasurements(identifier: PIPELINES, first: 1) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
|
||||||
|
#import "./count.fragment.graphql"
|
||||||
|
|
||||||
|
query pipelineStats(
|
||||||
|
$firstTotal: Int
|
||||||
|
$firstSucceeded: Int
|
||||||
|
$firstFailed: Int
|
||||||
|
$firstCanceled: Int
|
||||||
|
$firstSkipped: Int
|
||||||
|
$endCursorTotal: String
|
||||||
|
$endCursorSucceeded: String
|
||||||
|
$endCursorFailed: String
|
||||||
|
$endCursorCanceled: String
|
||||||
|
$endCursorSkipped: String
|
||||||
|
) {
|
||||||
|
pipelinesTotal: instanceStatisticsMeasurements(
|
||||||
|
identifier: PIPELINES
|
||||||
|
first: $firstTotal
|
||||||
|
after: $endCursorTotal
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PageInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipelinesSucceeded: instanceStatisticsMeasurements(
|
||||||
|
identifier: PIPELINES_SUCCEEDED
|
||||||
|
first: $firstSucceeded
|
||||||
|
after: $endCursorSucceeded
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PageInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipelinesFailed: instanceStatisticsMeasurements(
|
||||||
|
identifier: PIPELINES_FAILED
|
||||||
|
first: $firstFailed
|
||||||
|
after: $endCursorFailed
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PageInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipelinesCanceled: instanceStatisticsMeasurements(
|
||||||
|
identifier: PIPELINES_CANCELED
|
||||||
|
first: $firstCanceled
|
||||||
|
after: $endCursorCanceled
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PageInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipelinesSkipped: instanceStatisticsMeasurements(
|
||||||
|
identifier: PIPELINES_SKIPPED
|
||||||
|
first: $firstSkipped
|
||||||
|
after: $endCursorSkipped
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PageInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
|
||||||
|
#import "../fragments/count.fragment.graphql"
|
||||||
|
|
||||||
|
query getUsersCount($first: Int, $after: String) {
|
||||||
|
users: instanceStatisticsMeasurements(identifier: USERS, first: $first, after: $after) {
|
||||||
|
nodes {
|
||||||
|
...Count
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PageInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import VueApollo from 'vue-apollo';
|
||||||
|
import createDefaultClient from '~/lib/graphql';
|
||||||
|
import InstanceStatisticsApp from './components/app.vue';
|
||||||
|
|
||||||
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
|
const apolloProvider = new VueApollo({
|
||||||
|
defaultClient: createDefaultClient(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const el = document.getElementById('js-instance-statistics-app');
|
||||||
|
|
||||||
|
if (!el) return false;
|
||||||
|
|
||||||
|
return new Vue({
|
||||||
|
el,
|
||||||
|
apolloProvider,
|
||||||
|
render(h) {
|
||||||
|
return h(InstanceStatisticsApp);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { masks } from 'dateformat';
|
||||||
|
import { mapKeys, mapValues, pick, sortBy } from 'lodash';
|
||||||
|
import { formatDate } from '~/lib/utils/datetime_utility';
|
||||||
|
|
||||||
|
const { isoDate } = masks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of items and returns one item per month with the average of the `count`s from that month
|
||||||
|
* @param {Array} items
|
||||||
|
* @param {Number} items[index].count value to be averaged
|
||||||
|
* @param {String} items[index].recordedAt item dateTime time stamp to be collected into a month
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {Object} options.shouldRound an option to specify whether the retuned averages should be rounded
|
||||||
|
* @return {Array} items collected into [month, average],
|
||||||
|
* where month is a dateTime string representing the first of the given month
|
||||||
|
* and average is the average of the count
|
||||||
|
*/
|
||||||
|
export function getAverageByMonth(items = [], options = {}) {
|
||||||
|
const { shouldRound = false } = options;
|
||||||
|
const itemsMap = items.reduce((memo, item) => {
|
||||||
|
const { count, recordedAt } = item;
|
||||||
|
const date = new Date(recordedAt);
|
||||||
|
const month = formatDate(new Date(date.getFullYear(), date.getMonth(), 1), isoDate);
|
||||||
|
if (memo[month]) {
|
||||||
|
const { sum, recordCount } = memo[month];
|
||||||
|
return { ...memo, [month]: { sum: sum + count, recordCount: recordCount + 1 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...memo, [month]: { sum: count, recordCount: 1 } };
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return Object.keys(itemsMap).map(month => {
|
||||||
|
const { sum, recordCount } = itemsMap[month];
|
||||||
|
const avg = sum / recordCount;
|
||||||
|
if (shouldRound) {
|
||||||
|
return [month, Math.round(avg)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [month, avg];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts values given a data set and a set of keys
|
||||||
|
* @example
|
||||||
|
* const data = { fooBar: { baz: 'quis' }, ignored: 'ignored' };
|
||||||
|
* extractValues(data, ['fooBar'], 'foo', 'baz') => { bazBar: 'quis' }
|
||||||
|
* @param {Object} data set to extract values from
|
||||||
|
* @param {Array} dataKeys keys describing where to look for values in the data set
|
||||||
|
* @param {String} replaceKey name key to be replaced in the data set
|
||||||
|
* @param {String} nestedKey key nested in the data set to be extracted,
|
||||||
|
* this is also used to rename the newly created data set
|
||||||
|
* @return {Object} the newly created data set with the extracted values
|
||||||
|
*/
|
||||||
|
export function extractValues(data, dataKeys = [], replaceKey, nestedKey) {
|
||||||
|
return mapKeys(pick(mapValues(data, nestedKey), dataKeys), (value, key) =>
|
||||||
|
key.replace(replaceKey, nestedKey),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new array of items sorted by the date string of each item
|
||||||
|
* @param {Array} items [description]
|
||||||
|
* @param {String} items[0] date string
|
||||||
|
* @return {Array} the new sorted array.
|
||||||
|
*/
|
||||||
|
export function sortByDate(items = []) {
|
||||||
|
return sortBy(items, ({ recordedAt }) => new Date(recordedAt).getTime());
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
GlCard,
|
||||||
|
GlDeprecatedSkeletonLoading as GlSkeletonLoading,
|
||||||
|
GlLink,
|
||||||
|
GlIcon,
|
||||||
|
GlTooltipDirective,
|
||||||
|
} from '@gitlab/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MetricCard',
|
||||||
|
components: {
|
||||||
|
GlCard,
|
||||||
|
GlSkeletonLoading,
|
||||||
|
GlLink,
|
||||||
|
GlIcon,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
metrics: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
isLoading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
valueText(metric) {
|
||||||
|
const { value = null, unit = null } = metric;
|
||||||
|
if (!value || value === '-') return '-';
|
||||||
|
return unit && value ? `${value} ${unit}` : value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<gl-card>
|
||||||
|
<template #header>
|
||||||
|
<strong ref="title">{{ title }}</strong>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<gl-skeleton-loading v-if="isLoading" class="gl-h-auto gl-py-3" />
|
||||||
|
<div v-else ref="metricsWrapper" class="gl-display-flex">
|
||||||
|
<div
|
||||||
|
v-for="metric in metrics"
|
||||||
|
:key="metric.key"
|
||||||
|
ref="metricItem"
|
||||||
|
class="js-metric-card-item gl-flex-grow-1 gl-text-center"
|
||||||
|
>
|
||||||
|
<gl-link v-if="metric.link" :href="metric.link">
|
||||||
|
<h3 class="gl-my-2 gl-text-blue-700">{{ valueText(metric) }}</h3>
|
||||||
|
</gl-link>
|
||||||
|
<h3 v-else class="gl-my-2">{{ valueText(metric) }}</h3>
|
||||||
|
<p class="text-secondary gl-font-sm gl-mb-2">
|
||||||
|
{{ metric.label }}
|
||||||
|
<span v-if="metric.tooltipText">
|
||||||
|
|
||||||
|
<gl-icon
|
||||||
|
v-gl-tooltip="{ title: metric.tooltipText }"
|
||||||
|
:size="14"
|
||||||
|
class="gl-vertical-align-middle"
|
||||||
|
name="question"
|
||||||
|
data-testid="tooltip"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</gl-card>
|
||||||
|
</template>
|
|
@ -30,6 +30,7 @@ const Api = {
|
||||||
projectProtectedBranchesPath: '/api/:version/projects/:id/protected_branches',
|
projectProtectedBranchesPath: '/api/:version/projects/:id/protected_branches',
|
||||||
projectSearchPath: '/api/:version/projects/:id/search',
|
projectSearchPath: '/api/:version/projects/:id/search',
|
||||||
projectMilestonesPath: '/api/:version/projects/:id/milestones',
|
projectMilestonesPath: '/api/:version/projects/:id/milestones',
|
||||||
|
projectIssuePath: '/api/:version/projects/:id/issues/:issue_iid',
|
||||||
mergeRequestsPath: '/api/:version/merge_requests',
|
mergeRequestsPath: '/api/:version/merge_requests',
|
||||||
groupLabelsPath: '/groups/:namespace_path/-/labels',
|
groupLabelsPath: '/groups/:namespace_path/-/labels',
|
||||||
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
|
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
|
||||||
|
@ -54,6 +55,7 @@ const Api = {
|
||||||
releaseLinkPath: '/api/:version/projects/:id/releases/:tag_name/assets/links/:link_id',
|
releaseLinkPath: '/api/:version/projects/:id/releases/:tag_name/assets/links/:link_id',
|
||||||
mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines',
|
mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines',
|
||||||
adminStatisticsPath: '/api/:version/application/statistics',
|
adminStatisticsPath: '/api/:version/application/statistics',
|
||||||
|
pipelineJobsPath: '/api/:version/projects/:id/pipelines/:pipeline_id/jobs',
|
||||||
pipelineSinglePath: '/api/:version/projects/:id/pipelines/:pipeline_id',
|
pipelineSinglePath: '/api/:version/projects/:id/pipelines/:pipeline_id',
|
||||||
pipelinesPath: '/api/:version/projects/:id/pipelines/',
|
pipelinesPath: '/api/:version/projects/:id/pipelines/',
|
||||||
createPipelinePath: '/api/:version/projects/:id/pipeline',
|
createPipelinePath: '/api/:version/projects/:id/pipeline',
|
||||||
|
@ -64,6 +66,10 @@ const Api = {
|
||||||
issuePath: '/api/:version/projects/:id/issues/:issue_iid',
|
issuePath: '/api/:version/projects/:id/issues/:issue_iid',
|
||||||
tagsPath: '/api/:version/projects/:id/repository/tags',
|
tagsPath: '/api/:version/projects/:id/repository/tags',
|
||||||
freezePeriodsPath: '/api/:version/projects/:id/freeze_periods',
|
freezePeriodsPath: '/api/:version/projects/:id/freeze_periods',
|
||||||
|
usageDataIncrementUniqueUsersPath: '/api/:version/usage_data/increment_unique_users',
|
||||||
|
featureFlagUserLists: '/api/:version/projects/:id/feature_flags_user_lists',
|
||||||
|
featureFlagUserList: '/api/:version/projects/:id/feature_flags_user_lists/:list_iid',
|
||||||
|
billableGroupMembersPath: '/api/:version/groups/:id/billable_members',
|
||||||
|
|
||||||
group(groupId, callback = () => {}) {
|
group(groupId, callback = () => {}) {
|
||||||
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);
|
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);
|
||||||
|
@ -111,6 +117,12 @@ const Api = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inviteGroupMember(id, data) {
|
||||||
|
const url = Api.buildUrl(this.groupMembersPath).replace(':id', encodeURIComponent(id));
|
||||||
|
|
||||||
|
return axios.post(url, data);
|
||||||
|
},
|
||||||
|
|
||||||
groupMilestones(id, options) {
|
groupMilestones(id, options) {
|
||||||
const url = Api.buildUrl(this.groupMilestonesPath).replace(':id', encodeURIComponent(id));
|
const url = Api.buildUrl(this.groupMilestonesPath).replace(':id', encodeURIComponent(id));
|
||||||
|
|
||||||
|
@ -317,6 +329,14 @@ const Api = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addProjectIssueAsTodo(projectId, issueIid) {
|
||||||
|
const url = Api.buildUrl(Api.projectIssuePath)
|
||||||
|
.replace(':id', encodeURIComponent(projectId))
|
||||||
|
.replace(':issue_iid', encodeURIComponent(issueIid));
|
||||||
|
|
||||||
|
return axios.post(`${url}/todo`);
|
||||||
|
},
|
||||||
|
|
||||||
mergeRequests(params = {}) {
|
mergeRequests(params = {}) {
|
||||||
const url = Api.buildUrl(Api.mergeRequestsPath);
|
const url = Api.buildUrl(Api.mergeRequestsPath);
|
||||||
|
|
||||||
|
@ -366,7 +386,7 @@ const Api = {
|
||||||
},
|
},
|
||||||
|
|
||||||
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/ee/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||||
const url = Api.buildUrl(Api.commitsPath).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: {
|
||||||
|
@ -590,6 +610,14 @@ const Api = {
|
||||||
return axios.get(url);
|
return axios.get(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pipelineJobs(projectId, pipelineId) {
|
||||||
|
const url = Api.buildUrl(this.pipelineJobsPath)
|
||||||
|
.replace(':id', encodeURIComponent(projectId))
|
||||||
|
.replace(':pipeline_id', encodeURIComponent(pipelineId));
|
||||||
|
|
||||||
|
return axios.get(url);
|
||||||
|
},
|
||||||
|
|
||||||
// Return all pipelines for a project or filter by query params
|
// Return all pipelines for a project or filter by query params
|
||||||
pipelines(id, options = {}) {
|
pipelines(id, options = {}) {
|
||||||
const url = Api.buildUrl(this.pipelinesPath).replace(':id', encodeURIComponent(id));
|
const url = Api.buildUrl(this.pipelinesPath).replace(':id', encodeURIComponent(id));
|
||||||
|
@ -686,9 +714,78 @@ const Api = {
|
||||||
return axios.post(url, freezePeriod);
|
return axios.post(url, freezePeriod);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
trackRedisHllUserEvent(event) {
|
||||||
|
if (!gon.features?.usageDataApi) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = Api.buildUrl(this.usageDataIncrementUniqueUsersPath);
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
};
|
||||||
|
|
||||||
|
return axios.post(url, { event }, { headers });
|
||||||
|
},
|
||||||
|
|
||||||
buildUrl(url) {
|
buildUrl(url) {
|
||||||
return joinPaths(gon.relative_url_root || '', url.replace(':version', gon.api_version));
|
return joinPaths(gon.relative_url_root || '', url.replace(':version', gon.api_version));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fetchFeatureFlagUserLists(id, page) {
|
||||||
|
const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id);
|
||||||
|
|
||||||
|
return axios.get(url, { params: { page } });
|
||||||
|
},
|
||||||
|
|
||||||
|
createFeatureFlagUserList(id, list) {
|
||||||
|
const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id);
|
||||||
|
|
||||||
|
return axios.post(url, list);
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchFeatureFlagUserList(id, listIid) {
|
||||||
|
const url = Api.buildUrl(this.featureFlagUserList)
|
||||||
|
.replace(':id', id)
|
||||||
|
.replace(':list_iid', listIid);
|
||||||
|
|
||||||
|
return axios.get(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateFeatureFlagUserList(id, list) {
|
||||||
|
const url = Api.buildUrl(this.featureFlagUserList)
|
||||||
|
.replace(':id', id)
|
||||||
|
.replace(':list_iid', list.iid);
|
||||||
|
|
||||||
|
return axios.put(url, list);
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteFeatureFlagUserList(id, listIid) {
|
||||||
|
const url = Api.buildUrl(this.featureFlagUserList)
|
||||||
|
.replace(':id', id)
|
||||||
|
.replace(':list_iid', listIid);
|
||||||
|
|
||||||
|
return axios.delete(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchBillableGroupMembersList(namespaceId, options = {}, callback = () => {}) {
|
||||||
|
const url = Api.buildUrl(this.billableGroupMembersPath).replace(':id', namespaceId);
|
||||||
|
const defaults = {
|
||||||
|
per_page: DEFAULT_PER_PAGE,
|
||||||
|
page: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
return axios
|
||||||
|
.get(url, {
|
||||||
|
params: {
|
||||||
|
...defaults,
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(({ data, headers }) => {
|
||||||
|
callback(data);
|
||||||
|
return { data, headers };
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Api;
|
export default Api;
|
||||||
|
|
|
@ -572,7 +572,7 @@ export class AwardsHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingEmojiElements(query) {
|
findMatchingEmojiElements(query) {
|
||||||
const emojiMatches = this.emoji.filterEmojiNamesByAlias(query);
|
const emojiMatches = this.emoji.searchEmoji(query, { match: 'fuzzy' }).map(({ name }) => name);
|
||||||
const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');
|
const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');
|
||||||
const $matchingElements = $emojiElements.filter(
|
const $matchingElements = $emojiElements.filter(
|
||||||
(i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0,
|
(i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0,
|
||||||
|
|
|
@ -218,7 +218,7 @@ export default {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isEditing" class="row-content-block gl-display-flex gl-justify-content-end">
|
<div v-if="isEditing" class="row-content-block">
|
||||||
<gl-button class="btn-cancel gl-mr-4" data-testid="cancelEditing" @click="onCancel">
|
<gl-button class="btn-cancel gl-mr-4" data-testid="cancelEditing" @click="onCancel">
|
||||||
{{ __('Cancel') }}
|
{{ __('Cancel') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
|
@ -232,7 +232,7 @@ export default {
|
||||||
{{ s__('Badges|Save changes') }}
|
{{ s__('Badges|Save changes') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="gl-display-flex gl-justify-content-end form-group">
|
<div v-else class="form-group">
|
||||||
<gl-button :loading="isSaving" type="submit" variant="success" category="primary">
|
<gl-button :loading="isSaving" type="submit" variant="success" category="primary">
|
||||||
{{ s__('Badges|Add badge') }}
|
{{ s__('Badges|Add badge') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapState } from 'vuex';
|
import { mapActions, mapState } from 'vuex';
|
||||||
import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
|
import { GlLoadingIcon, GlButton, GlModalDirective } from '@gitlab/ui';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import { PROJECT_BADGE } from '../constants';
|
import { PROJECT_BADGE } from '../constants';
|
||||||
import Badge from './badge.vue';
|
import Badge from './badge.vue';
|
||||||
|
@ -9,8 +9,11 @@ export default {
|
||||||
name: 'BadgeListRow',
|
name: 'BadgeListRow',
|
||||||
components: {
|
components: {
|
||||||
Badge,
|
Badge,
|
||||||
GlIcon,
|
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
|
GlButton,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
GlModal: GlModalDirective,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
badge: {
|
badge: {
|
||||||
|
@ -51,24 +54,25 @@ export default {
|
||||||
<span class="table-section section-30 str-truncated">{{ badge.linkUrl }}</span>
|
<span class="table-section section-30 str-truncated">{{ badge.linkUrl }}</span>
|
||||||
<div class="table-section section-10 table-button-footer">
|
<div class="table-section section-10 table-button-footer">
|
||||||
<div v-if="canEditBadge" class="table-action-buttons">
|
<div v-if="canEditBadge" class="table-action-buttons">
|
||||||
<button
|
<gl-button
|
||||||
:disabled="badge.isDeleting"
|
:disabled="badge.isDeleting"
|
||||||
class="btn btn-default gl-mr-3"
|
class="gl-mr-3"
|
||||||
type="button"
|
variant="default"
|
||||||
|
icon="pencil"
|
||||||
|
size="medium"
|
||||||
|
:aria-label="__('Edit')"
|
||||||
@click="editBadge(badge)"
|
@click="editBadge(badge)"
|
||||||
>
|
/>
|
||||||
<gl-icon :size="16" :aria-label="__('Edit')" name="pencil" />
|
<gl-button
|
||||||
</button>
|
v-gl-modal.delete-badge-modal
|
||||||
<button
|
|
||||||
:disabled="badge.isDeleting"
|
:disabled="badge.isDeleting"
|
||||||
class="btn btn-danger"
|
variant="danger"
|
||||||
type="button"
|
icon="remove"
|
||||||
data-toggle="modal"
|
size="medium"
|
||||||
data-target="#delete-badge-modal"
|
:aria-label="__('Delete')"
|
||||||
|
data-testid="delete-badge"
|
||||||
@click="updateBadgeInModal(badge)"
|
@click="updateBadgeInModal(badge)"
|
||||||
>
|
/>
|
||||||
<gl-icon :size="16" :aria-label="__('Delete')" name="remove" />
|
|
||||||
</button>
|
|
||||||
<gl-loading-icon v-show="badge.isDeleting" :inline="true" />
|
<gl-loading-icon v-show="badge.isDeleting" :inline="true" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapActions } from 'vuex';
|
import { mapState, mapActions } from 'vuex';
|
||||||
import { GlSprintf } from '@gitlab/ui';
|
import { GlSprintf, GlModal } from '@gitlab/ui';
|
||||||
import { deprecatedCreateFlash as createFlash } from '~/flash';
|
import { deprecatedCreateFlash as createFlash } from '~/flash';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
|
|
||||||
import Badge from './badge.vue';
|
import Badge from './badge.vue';
|
||||||
import BadgeForm from './badge_form.vue';
|
import BadgeForm from './badge_form.vue';
|
||||||
import BadgeList from './badge_list.vue';
|
import BadgeList from './badge_list.vue';
|
||||||
|
@ -14,7 +13,7 @@ export default {
|
||||||
Badge,
|
Badge,
|
||||||
BadgeForm,
|
BadgeForm,
|
||||||
BadgeList,
|
BadgeList,
|
||||||
GlModal: DeprecatedModal2,
|
GlModal,
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
},
|
},
|
||||||
i18n: {
|
i18n: {
|
||||||
|
@ -24,6 +23,17 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['badgeInModal', 'isEditing']),
|
...mapState(['badgeInModal', 'isEditing']),
|
||||||
|
primaryProps() {
|
||||||
|
return {
|
||||||
|
text: s__('Delete badge'),
|
||||||
|
attributes: [{ category: 'primary' }, { variant: 'danger' }],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
cancelProps() {
|
||||||
|
return {
|
||||||
|
text: s__('Cancel'),
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['deleteBadge']),
|
...mapActions(['deleteBadge']),
|
||||||
|
@ -44,11 +54,11 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div class="badge-settings">
|
<div class="badge-settings">
|
||||||
<gl-modal
|
<gl-modal
|
||||||
id="delete-badge-modal"
|
modal-id="delete-badge-modal"
|
||||||
:header-title-text="s__('Badges|Delete badge?')"
|
:title="s__('Badges|Delete badge?')"
|
||||||
:footer-primary-button-text="s__('Badges|Delete badge')"
|
:action-primary="primaryProps"
|
||||||
footer-primary-button-variant="danger"
|
:action-cancel="cancelProps"
|
||||||
@submit="onSubmitModal"
|
@primary="onSubmitModal"
|
||||||
>
|
>
|
||||||
<div class="well">
|
<div class="well">
|
||||||
<badge
|
<badge
|
||||||
|
@ -65,9 +75,9 @@ export default {
|
||||||
</p>
|
</p>
|
||||||
</gl-modal>
|
</gl-modal>
|
||||||
|
|
||||||
<badge-form v-show="isEditing" :is-editing="true" />
|
<badge-form v-show="isEditing" :is-editing="true" data-testid="edit-badge" />
|
||||||
|
|
||||||
<badge-form v-show="!isEditing" :is-editing="false" />
|
<badge-form v-show="!isEditing" :is-editing="false" data-testid="add-new-badge" />
|
||||||
<badge-list v-show="!isEditing" />
|
<badge-list v-show="!isEditing" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -18,11 +18,6 @@ export default {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
diffFile: {
|
|
||||||
type: Object,
|
|
||||||
required: false,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
line: {
|
line: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false,
|
required: false,
|
||||||
|
|
|
@ -1,114 +1,43 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapGetters, mapState } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import { GlButton, GlLoadingIcon, GlIcon } from '@gitlab/ui';
|
import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
|
||||||
import { sprintf, n__ } from '~/locale';
|
|
||||||
import DraftsCount from './drafts_count.vue';
|
|
||||||
import PublishButton from './publish_button.vue';
|
|
||||||
import PreviewItem from './preview_item.vue';
|
import PreviewItem from './preview_item.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlButton,
|
GlDropdown,
|
||||||
GlLoadingIcon,
|
GlDropdownItem,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
DraftsCount,
|
|
||||||
PublishButton,
|
|
||||||
PreviewItem,
|
PreviewItem,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['isNotesFetched']),
|
|
||||||
...mapGetters('batchComments', ['draftsCount', 'sortedDrafts']),
|
...mapGetters('batchComments', ['draftsCount', 'sortedDrafts']),
|
||||||
...mapState('batchComments', ['showPreviewDropdown']),
|
|
||||||
dropdownTitle() {
|
|
||||||
return sprintf(
|
|
||||||
n__('%{count} pending comment', '%{count} pending comments', this.draftsCount),
|
|
||||||
{ count: this.draftsCount },
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
showPreviewDropdown() {
|
|
||||||
if (this.showPreviewDropdown && this.$refs.dropdown) {
|
|
||||||
this.$nextTick(() => this.$refs.dropdown.$el.focus());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
document.addEventListener('click', this.onClickDocument);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
document.removeEventListener('click', this.onClickDocument);
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('batchComments', ['toggleReviewDropdown']),
|
...mapActions('batchComments', ['scrollToDraft']),
|
||||||
isLast(index) {
|
isLast(index) {
|
||||||
return index === this.sortedDrafts.length - 1;
|
return index === this.sortedDrafts.length - 1;
|
||||||
},
|
},
|
||||||
onClickDocument({ target }) {
|
|
||||||
if (
|
|
||||||
this.showPreviewDropdown &&
|
|
||||||
!target.closest('.review-preview-dropdown, .js-publish-draft-button')
|
|
||||||
) {
|
|
||||||
this.toggleReviewDropdown();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<gl-dropdown
|
||||||
class="dropdown float-right review-preview-dropdown"
|
:header-text="n__('%d pending comment', '%d pending comments', draftsCount)"
|
||||||
:class="{
|
dropup
|
||||||
show: showPreviewDropdown,
|
toggle-class="qa-review-preview-toggle"
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<gl-button
|
<template #button-content>
|
||||||
ref="dropdown"
|
{{ __('Pending comments') }}
|
||||||
type="button"
|
<gl-icon class="dropdown-chevron" name="chevron-up" />
|
||||||
category="primary"
|
</template>
|
||||||
variant="success"
|
<gl-dropdown-item
|
||||||
class="review-preview-dropdown-toggle qa-review-preview-toggle"
|
v-for="(draft, index) in sortedDrafts"
|
||||||
@click="toggleReviewDropdown"
|
:key="draft.id"
|
||||||
|
@click="scrollToDraft(draft)"
|
||||||
>
|
>
|
||||||
{{ __('Finish review') }}
|
|
||||||
<drafts-count />
|
|
||||||
<gl-icon name="angle-up" />
|
|
||||||
</gl-button>
|
|
||||||
<div
|
|
||||||
class="dropdown-menu dropdown-menu-large dropdown-menu-right dropdown-open-top"
|
|
||||||
:class="{
|
|
||||||
show: showPreviewDropdown,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div class="dropdown-title gl-display-flex gl-align-items-center">
|
|
||||||
<span class="gl-ml-auto">{{ dropdownTitle }}</span>
|
|
||||||
<gl-button
|
|
||||||
:aria-label="__('Close')"
|
|
||||||
type="button"
|
|
||||||
category="tertiary"
|
|
||||||
size="small"
|
|
||||||
class="dropdown-title-button gl-ml-auto gl-p-0!"
|
|
||||||
icon="close"
|
|
||||||
@click="toggleReviewDropdown"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-content">
|
|
||||||
<ul v-if="isNotesFetched">
|
|
||||||
<li v-for="(draft, index) in sortedDrafts" :key="draft.id">
|
|
||||||
<preview-item :draft="draft" :is-last="isLast(index)" />
|
<preview-item :draft="draft" :is-last="isLast(index)" />
|
||||||
</li>
|
</gl-dropdown-item>
|
||||||
</ul>
|
</gl-dropdown>
|
||||||
<gl-loading-icon v-else size="lg" class="gl-mt-3 gl-mb-3" />
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-footer">
|
|
||||||
<publish-button
|
|
||||||
:show-count="false"
|
|
||||||
:should-publish="true"
|
|
||||||
:label="__('Submit review')"
|
|
||||||
class="float-right gl-mr-3"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { GlSprintf, GlIcon } from '@gitlab/ui';
|
import { GlSprintf, GlIcon } from '@gitlab/ui';
|
||||||
import { IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
|
import { IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
|
||||||
import { sprintf, __ } from '~/locale';
|
import { sprintf, __ } from '~/locale';
|
||||||
|
@ -78,7 +78,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('batchComments', ['scrollToDraft']),
|
|
||||||
getLineClasses(lineNumber) {
|
getLineClasses(lineNumber) {
|
||||||
return getLineClasses(lineNumber);
|
return getLineClasses(lineNumber);
|
||||||
},
|
},
|
||||||
|
@ -88,17 +87,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button
|
<span>
|
||||||
type="button"
|
|
||||||
class="review-preview-item menu-item"
|
|
||||||
:class="[
|
|
||||||
componentClasses,
|
|
||||||
{
|
|
||||||
'is-last': isLast,
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
@click="scrollToDraft(draft)"
|
|
||||||
>
|
|
||||||
<span class="review-preview-item-header">
|
<span class="review-preview-item-header">
|
||||||
<gl-icon class="flex-shrink-0" :name="iconName" />
|
<gl-icon class="flex-shrink-0" :name="iconName" />
|
||||||
<span
|
<span
|
||||||
|
@ -139,5 +128,5 @@ export default {
|
||||||
>
|
>
|
||||||
<gl-icon class="gl-mr-3" name="status_success" /> {{ resolvedStatusMessage }}
|
<gl-icon class="gl-mr-3" name="status_success" /> {{ resolvedStatusMessage }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapState } from 'vuex';
|
import { mapActions, mapState } from 'vuex';
|
||||||
import { GlButton } from '@gitlab/ui';
|
import { GlButton } from '@gitlab/ui';
|
||||||
import { __ } from '~/locale';
|
|
||||||
import DraftsCount from './drafts_count.vue';
|
import DraftsCount from './drafts_count.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -15,11 +14,6 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: __('Finish review'),
|
|
||||||
},
|
|
||||||
category: {
|
category: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -30,22 +24,14 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: 'success',
|
default: 'success',
|
||||||
},
|
},
|
||||||
shouldPublish: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('batchComments', ['isPublishing']),
|
...mapState('batchComments', ['isPublishing']),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('batchComments', ['publishReview', 'toggleReviewDropdown']),
|
...mapActions('batchComments', ['publishReview']),
|
||||||
onClick() {
|
onClick() {
|
||||||
if (this.shouldPublish) {
|
|
||||||
this.publishReview();
|
this.publishReview();
|
||||||
} else {
|
|
||||||
this.toggleReviewDropdown();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -59,7 +45,7 @@ export default {
|
||||||
:variant="variant"
|
:variant="variant"
|
||||||
@click="onClick"
|
@click="onClick"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ __('Submit review') }}
|
||||||
<drafts-count v-if="showCount" />
|
<drafts-count v-if="showCount" />
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,22 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable vue/no-v-html */
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import { mapActions, mapState, mapGetters } from 'vuex';
|
|
||||||
import { GlModal, GlModalDirective, GlButton } from '@gitlab/ui';
|
|
||||||
import { sprintf, s__ } from '~/locale';
|
|
||||||
import PreviewDropdown from './preview_dropdown.vue';
|
import PreviewDropdown from './preview_dropdown.vue';
|
||||||
|
import PublishButton from './publish_button.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlButton,
|
|
||||||
GlModal,
|
|
||||||
PreviewDropdown,
|
PreviewDropdown,
|
||||||
},
|
PublishButton,
|
||||||
directives: {
|
|
||||||
'gl-modal': GlModalDirective,
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['isNotesFetched']),
|
...mapGetters(['isNotesFetched']),
|
||||||
...mapState('batchComments', ['isDiscarding']),
|
|
||||||
...mapGetters('batchComments', ['draftsCount']),
|
...mapGetters('batchComments', ['draftsCount']),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -27,45 +20,17 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('batchComments', ['discardReview', 'expandAllDiscussions']),
|
...mapActions('batchComments', ['expandAllDiscussions']),
|
||||||
},
|
},
|
||||||
modalId: 'discard-draft-review',
|
|
||||||
text: sprintf(
|
|
||||||
s__(
|
|
||||||
`BatchComments|You're about to discard your review which will delete all of your pending comments.
|
|
||||||
The deleted comments %{strong_start}cannot%{strong_end} be restored.`,
|
|
||||||
),
|
|
||||||
{
|
|
||||||
strong_start: '<strong>',
|
|
||||||
strong_end: '</strong>',
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div v-show="draftsCount > 0">
|
<div v-show="draftsCount > 0">
|
||||||
<nav class="review-bar-component">
|
<nav class="review-bar-component">
|
||||||
<div class="review-bar-content qa-review-bar">
|
<div class="review-bar-content qa-review-bar d-flex gl-justify-content-end">
|
||||||
<preview-dropdown />
|
<preview-dropdown />
|
||||||
<gl-button
|
<publish-button class="gl-ml-3" show-count />
|
||||||
v-gl-modal="$options.modalId"
|
|
||||||
:loading="isDiscarding"
|
|
||||||
class="qa-discard-review float-right"
|
|
||||||
>
|
|
||||||
{{ __('Discard review') }}
|
|
||||||
</gl-button>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<gl-modal
|
|
||||||
:title="s__('BatchComments|Discard review?')"
|
|
||||||
:ok-title="s__('BatchComments|Delete all pending comments')"
|
|
||||||
:modal-id="$options.modalId"
|
|
||||||
title-tag="h4"
|
|
||||||
ok-variant="danger qa-modal-delete-pending-comments"
|
|
||||||
@ok="discardReview"
|
|
||||||
>
|
|
||||||
<p v-html="$options.text"></p>
|
|
||||||
</gl-modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -75,15 +75,6 @@ export const updateDiscussionsAfterPublish = ({ dispatch, getters, rootGetters }
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const discardReview = ({ commit, getters }) => {
|
|
||||||
commit(types.REQUEST_DISCARD_REVIEW);
|
|
||||||
|
|
||||||
return service
|
|
||||||
.discard(getters.getNotesData.draftsDiscardPath)
|
|
||||||
.then(() => commit(types.RECEIVE_DISCARD_REVIEW_SUCCESS))
|
|
||||||
.catch(() => commit(types.RECEIVE_DISCARD_REVIEW_ERROR));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateDraft = (
|
export const updateDraft = (
|
||||||
{ commit, getters },
|
{ commit, getters },
|
||||||
{ note, noteText, resolveDiscussion, position, callback },
|
{ note, noteText, resolveDiscussion, position, callback },
|
||||||
|
@ -108,8 +99,6 @@ export const scrollToDraft = ({ dispatch, rootGetters }, draft) => {
|
||||||
const draftID = `note_${draft.id}`;
|
const draftID = `note_${draft.id}`;
|
||||||
const el = document.querySelector(`#${tabEl} #${draftID}`);
|
const el = document.querySelector(`#${tabEl} #${draftID}`);
|
||||||
|
|
||||||
dispatch('closeReviewDropdown');
|
|
||||||
|
|
||||||
window.location.hash = draftID;
|
window.location.hash = draftID;
|
||||||
|
|
||||||
if (window.mrTabs.currentAction !== tab) {
|
if (window.mrTabs.currentAction !== tab) {
|
||||||
|
@ -125,17 +114,6 @@ export const scrollToDraft = ({ dispatch, rootGetters }, draft) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toggleReviewDropdown = ({ dispatch, state }) => {
|
|
||||||
if (state.showPreviewDropdown) {
|
|
||||||
dispatch('closeReviewDropdown');
|
|
||||||
} else {
|
|
||||||
dispatch('openReviewDropdown');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const openReviewDropdown = ({ commit }) => commit(types.OPEN_REVIEW_DROPDOWN);
|
|
||||||
export const closeReviewDropdown = ({ commit }) => commit(types.CLOSE_REVIEW_DROPDOWN);
|
|
||||||
|
|
||||||
export const expandAllDiscussions = ({ dispatch, state }) =>
|
export const expandAllDiscussions = ({ dispatch, state }) =>
|
||||||
state.drafts
|
state.drafts
|
||||||
.filter(draft => draft.discussion_id)
|
.filter(draft => draft.discussion_id)
|
||||||
|
|
|
@ -11,13 +11,6 @@ export const REQUEST_PUBLISH_REVIEW = 'REQUEST_PUBLISH_REVIEW';
|
||||||
export const RECEIVE_PUBLISH_REVIEW_SUCCESS = 'RECEIVE_PUBLISH_REVIEW_SUCCESS';
|
export const RECEIVE_PUBLISH_REVIEW_SUCCESS = 'RECEIVE_PUBLISH_REVIEW_SUCCESS';
|
||||||
export const RECEIVE_PUBLISH_REVIEW_ERROR = 'RECEIVE_PUBLISH_REVIEW_ERROR';
|
export const RECEIVE_PUBLISH_REVIEW_ERROR = 'RECEIVE_PUBLISH_REVIEW_ERROR';
|
||||||
|
|
||||||
export const REQUEST_DISCARD_REVIEW = 'REQUEST_DISCARD_REVIEW';
|
|
||||||
export const RECEIVE_DISCARD_REVIEW_SUCCESS = 'RECEIVE_DISCARD_REVIEW_SUCCESS';
|
|
||||||
export const RECEIVE_DISCARD_REVIEW_ERROR = 'RECEIVE_DISCARD_REVIEW_ERROR';
|
|
||||||
|
|
||||||
export const RECEIVE_DRAFT_UPDATE_SUCCESS = 'RECEIVE_DRAFT_UPDATE_SUCCESS';
|
export const RECEIVE_DRAFT_UPDATE_SUCCESS = 'RECEIVE_DRAFT_UPDATE_SUCCESS';
|
||||||
|
|
||||||
export const OPEN_REVIEW_DROPDOWN = 'OPEN_REVIEW_DROPDOWN';
|
|
||||||
export const CLOSE_REVIEW_DROPDOWN = 'CLOSE_REVIEW_DROPDOWN';
|
|
||||||
|
|
||||||
export const TOGGLE_RESOLVE_DISCUSSION = 'TOGGLE_RESOLVE_DISCUSSION';
|
export const TOGGLE_RESOLVE_DISCUSSION = 'TOGGLE_RESOLVE_DISCUSSION';
|
||||||
|
|
|
@ -43,16 +43,6 @@ export default {
|
||||||
[types.RECEIVE_PUBLISH_REVIEW_ERROR](state) {
|
[types.RECEIVE_PUBLISH_REVIEW_ERROR](state) {
|
||||||
state.isPublishing = false;
|
state.isPublishing = false;
|
||||||
},
|
},
|
||||||
[types.REQUEST_DISCARD_REVIEW](state) {
|
|
||||||
state.isDiscarding = true;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_DISCARD_REVIEW_SUCCESS](state) {
|
|
||||||
state.isDiscarding = false;
|
|
||||||
state.drafts = [];
|
|
||||||
},
|
|
||||||
[types.RECEIVE_DISCARD_REVIEW_ERROR](state) {
|
|
||||||
state.isDiscarding = false;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_DRAFT_UPDATE_SUCCESS](state, data) {
|
[types.RECEIVE_DRAFT_UPDATE_SUCCESS](state, data) {
|
||||||
const index = state.drafts.findIndex(draft => draft.id === data.id);
|
const index = state.drafts.findIndex(draft => draft.id === data.id);
|
||||||
|
|
||||||
|
@ -60,12 +50,6 @@ export default {
|
||||||
state.drafts.splice(index, 1, processDraft(data));
|
state.drafts.splice(index, 1, processDraft(data));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[types.OPEN_REVIEW_DROPDOWN](state) {
|
|
||||||
state.showPreviewDropdown = true;
|
|
||||||
},
|
|
||||||
[types.CLOSE_REVIEW_DROPDOWN](state) {
|
|
||||||
state.showPreviewDropdown = false;
|
|
||||||
},
|
|
||||||
[types.TOGGLE_RESOLVE_DISCUSSION](state, draftId) {
|
[types.TOGGLE_RESOLVE_DISCUSSION](state, draftId) {
|
||||||
state.drafts = state.drafts.map(draft => {
|
state.drafts = state.drafts.map(draft => {
|
||||||
if (draft.id === draftId) {
|
if (draft.id === draftId) {
|
||||||
|
|
|
@ -4,6 +4,4 @@ export default () => ({
|
||||||
drafts: [],
|
drafts: [],
|
||||||
isPublishing: false,
|
isPublishing: false,
|
||||||
currentlyPublishingDrafts: [],
|
currentlyPublishingDrafts: [],
|
||||||
isDiscarding: false,
|
|
||||||
showPreviewDropdown: false,
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Autosize from 'autosize';
|
import Autosize from 'autosize';
|
||||||
import { waitForCSSLoaded } from '../helpers/startup_css_helper';
|
import { waitForCSSLoaded } from '~/helpers/startup_css_helper';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
waitForCSSLoaded(() => {
|
waitForCSSLoaded(() => {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
||||||
* @sentrify
|
* @sentrify
|
||||||
*/
|
*/
|
||||||
export default () => {
|
export default () => {
|
||||||
const $sidebarGutterToggle = $('.js-sidebar-toggle');
|
|
||||||
let bootstrapBreakpoint = bp.getBreakpointSize();
|
let bootstrapBreakpoint = bp.getBreakpointSize();
|
||||||
|
|
||||||
$(window).on('resize.app', () => {
|
$(window).on('resize.app', () => {
|
||||||
|
@ -19,8 +18,13 @@ export default () => {
|
||||||
const breakpointSizes = ['md', 'sm', 'xs'];
|
const breakpointSizes = ['md', 'sm', 'xs'];
|
||||||
|
|
||||||
if (breakpointSizes.includes(bootstrapBreakpoint)) {
|
if (breakpointSizes.includes(bootstrapBreakpoint)) {
|
||||||
const $gutterIcon = $sidebarGutterToggle.find('i');
|
const $toggleContainer = $('.js-sidebar-toggle-container');
|
||||||
if ($gutterIcon.hasClass('fa-angle-double-right')) {
|
const isExpanded = $toggleContainer.data('is-expanded');
|
||||||
|
const $expandIcon = $('.js-sidebar-expand');
|
||||||
|
|
||||||
|
if (isExpanded) {
|
||||||
|
const $sidebarGutterToggle = $expandIcon.closest('.js-sidebar-toggle');
|
||||||
|
|
||||||
$sidebarGutterToggle.trigger('click');
|
$sidebarGutterToggle.trigger('click');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +32,12 @@ export default () => {
|
||||||
|
|
||||||
// Sidebar has an icon which corresponds to collapsing the sidebar
|
// Sidebar has an icon which corresponds to collapsing the sidebar
|
||||||
// only then trigger the click.
|
// only then trigger the click.
|
||||||
|
if (
|
||||||
|
sidebarGutterVueToggleEl &&
|
||||||
|
!sidebarGutterVueToggleEl.classList.contains('js-sidebar-collapsed')
|
||||||
|
) {
|
||||||
if (sidebarGutterVueToggleEl) {
|
if (sidebarGutterVueToggleEl) {
|
||||||
const collapseIcon = sidebarGutterVueToggleEl.querySelector('i.fa-angle-double-right');
|
sidebarGutterVueToggleEl.click();
|
||||||
|
|
||||||
if (collapseIcon) {
|
|
||||||
collapseIcon.click();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Clipboard from 'clipboard';
|
import Clipboard from 'clipboard';
|
||||||
import { sprintf, __ } from '~/locale';
|
import { sprintf, __ } from '~/locale';
|
||||||
|
import { fixTitle, show } from '~/tooltips';
|
||||||
|
|
||||||
function showTooltip(target, title) {
|
function showTooltip(target, title) {
|
||||||
const $target = $(target);
|
const { originalTitle } = target.dataset;
|
||||||
const originalTitle = $target.data('originalTitle');
|
const hideTooltip = () => {
|
||||||
|
target.removeEventListener('mouseout', hideTooltip);
|
||||||
|
setTimeout(() => {
|
||||||
|
target.setAttribute('title', originalTitle);
|
||||||
|
fixTitle(target);
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
if (!$target.data('hideTooltip')) {
|
target.setAttribute('title', title);
|
||||||
$target
|
|
||||||
.attr('title', title)
|
fixTitle(target);
|
||||||
.tooltip('_fixTitle')
|
show(target);
|
||||||
.tooltip('show')
|
|
||||||
.attr('title', originalTitle)
|
target.addEventListener('mouseout', hideTooltip);
|
||||||
.tooltip('_fixTitle');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function genericSuccess(e) {
|
function genericSuccess(e) {
|
||||||
|
|
|
@ -3,9 +3,7 @@ import isEmojiUnicodeSupported from '../emoji/support';
|
||||||
import { initEmojiMap, getEmojiInfo, emojiFallbackImageSrc, emojiImageTag } from '../emoji';
|
import { initEmojiMap, getEmojiInfo, emojiFallbackImageSrc, emojiImageTag } from '../emoji';
|
||||||
|
|
||||||
class GlEmoji extends HTMLElement {
|
class GlEmoji extends HTMLElement {
|
||||||
constructor() {
|
connectedCallback() {
|
||||||
super();
|
|
||||||
|
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
}
|
||||||
initialize() {
|
initialize() {
|
||||||
|
|
|
@ -13,6 +13,9 @@ import './toggler_behavior';
|
||||||
import './preview_markdown';
|
import './preview_markdown';
|
||||||
import initCollapseSidebarOnWindowResize from './collapse_sidebar_on_window_resize';
|
import initCollapseSidebarOnWindowResize from './collapse_sidebar_on_window_resize';
|
||||||
import initSelect2Dropdowns from './select2';
|
import initSelect2Dropdowns from './select2';
|
||||||
|
import { loadStartupCSS } from './load_startup_css';
|
||||||
|
|
||||||
|
loadStartupCSS();
|
||||||
|
|
||||||
installGlEmojiElement();
|
installGlEmojiElement();
|
||||||
|
|
||||||
|
|
15
app/assets/javascripts/behaviors/load_startup_css.js
Normal file
15
app/assets/javascripts/behaviors/load_startup_css.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
export const loadStartupCSS = () => {
|
||||||
|
// We need to fallback to dispatching `load` in case our event listener was added too late
|
||||||
|
// or the browser environment doesn't load media=print.
|
||||||
|
// Do this on `window.load` so that the default deferred behavior takes precedence.
|
||||||
|
// https://gitlab.com/gitlab-org/gitlab/-/issues/239357
|
||||||
|
window.addEventListener(
|
||||||
|
'load',
|
||||||
|
() => {
|
||||||
|
document
|
||||||
|
.querySelectorAll('link[media=print]')
|
||||||
|
.forEach(x => x.dispatchEvent(new Event('load')));
|
||||||
|
},
|
||||||
|
{ once: true },
|
||||||
|
);
|
||||||
|
};
|
|
@ -14,7 +14,6 @@ export default function initGFMInput($els) {
|
||||||
milestones: enableGFM,
|
milestones: enableGFM,
|
||||||
mergeRequests: enableGFM,
|
mergeRequests: enableGFM,
|
||||||
labels: enableGFM,
|
labels: enableGFM,
|
||||||
vulnerabilities: enableGFM,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
96
app/assets/javascripts/behaviors/shortcuts/keybindings.js
Normal file
96
app/assets/javascripts/behaviors/shortcuts/keybindings.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import { flatten } from 'lodash';
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
import AccessorUtilities from '~/lib/utils/accessor';
|
||||||
|
import { shouldDisableShortcuts } from './shortcuts_toggle';
|
||||||
|
|
||||||
|
export const LOCAL_STORAGE_KEY = 'gl-keyboard-shortcuts-customizations';
|
||||||
|
|
||||||
|
let parsedCustomizations = {};
|
||||||
|
const localStorageIsSafe = AccessorUtilities.isLocalStorageAccessSafe();
|
||||||
|
|
||||||
|
if (localStorageIsSafe) {
|
||||||
|
try {
|
||||||
|
parsedCustomizations = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY) || '{}');
|
||||||
|
} catch (e) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of command => keys of all keyboard shortcuts
|
||||||
|
* that have been customized by the user.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* { "globalShortcuts.togglePerformanceBar": ["p e r f"] }
|
||||||
|
*
|
||||||
|
* @type { Object.<string, string[]> }
|
||||||
|
*/
|
||||||
|
export const customizations = parsedCustomizations;
|
||||||
|
|
||||||
|
// All available commands
|
||||||
|
export const TOGGLE_PERFORMANCE_BAR = 'globalShortcuts.togglePerformanceBar';
|
||||||
|
|
||||||
|
/** All keybindings, grouped and ordered with descriptions */
|
||||||
|
export const keybindingGroups = [
|
||||||
|
{
|
||||||
|
groupId: 'globalShortcuts',
|
||||||
|
name: s__('KeyboardShortcuts|Global Shortcuts'),
|
||||||
|
keybindings: [
|
||||||
|
{
|
||||||
|
description: s__('KeyboardShortcuts|Toggle the Performance Bar'),
|
||||||
|
command: TOGGLE_PERFORMANCE_BAR,
|
||||||
|
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||||
|
defaultKeys: ['p b'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// For each keybinding object, add a `customKeys` property populated with the
|
||||||
|
// user's custom keybindings (if the command has been customized).
|
||||||
|
// `customKeys` will be `undefined` if the command hasn't been customized.
|
||||||
|
.map(group => {
|
||||||
|
return {
|
||||||
|
...group,
|
||||||
|
keybindings: group.keybindings.map(binding => ({
|
||||||
|
...binding,
|
||||||
|
customKeys: customizations[binding.command],
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple map of command => keys. All user customizations are included in this map.
|
||||||
|
* This mapping is used to simplify `keysFor` below.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* { "globalShortcuts.togglePerformanceBar": ["p e r f"] }
|
||||||
|
*/
|
||||||
|
const commandToKeys = flatten(keybindingGroups.map(group => group.keybindings)).reduce(
|
||||||
|
(acc, binding) => {
|
||||||
|
acc[binding.command] = binding.customKeys || binding.defaultKeys;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets keyboard shortcuts associated with a command
|
||||||
|
*
|
||||||
|
* @param {string} command The command string. All command
|
||||||
|
* strings are available as imports from this file.
|
||||||
|
*
|
||||||
|
* @returns {string[]} An array of keyboard shortcut strings bound to the command
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* import { keysFor, TOGGLE_PERFORMANCE_BAR } from '~/behaviors/shortcuts/keybindings'
|
||||||
|
*
|
||||||
|
* Mousetrap.bind(keysFor(TOGGLE_PERFORMANCE_BAR), handler);
|
||||||
|
*/
|
||||||
|
export const keysFor = command => {
|
||||||
|
if (shouldDisableShortcuts()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return commandToKeys[command];
|
||||||
|
};
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue