diff --git a/.editorconfig b/.editorconfig index d704f20c72..56ce6d8714 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,6 @@ indent_size = 2 [*.{js,json,vue,scss,rb,haml,yml,md}] indent_style = space charset = utf-8 + +[*.{md,markdown}] +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore index f364771e54..c41556f6aa 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,6 +9,7 @@ /scripts/ /tmp/ /vendor/ +jest.config.js jest.config.*.js karma.config.js webpack.config.js diff --git a/.gitignore b/.gitignore index 3120c1c1bd..29180b76e2 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,6 @@ eslint-report.html /config/gitlab.yml /config/gitlab_ci.yml /config/Gitlab.gitlab-license -/config/initializers/rack_attack.rb /config/initializers/smtp_settings.rb /config/initializers/relative_url.rb /config/resque.yml @@ -92,3 +91,6 @@ jsdoc/ webpack-dev-server.json /.nvimrc .solargraph.yml +apollo.config.js +/tmp/matching_foss_tests.txt +ee/changelogs/unreleased-ee diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 21dfd6563e..4bbf411c23 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,7 +15,7 @@ stages: # in cases where jobs require Docker-in-Docker, the job # definition must be extended with `.use-docker-in-docker` default: - image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-9.6-graphicsmagick-1.3.34" + image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34" tags: - gitlab-org # All jobs are interruptible by default diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index e71e74fd4d..6cd316349c 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -8,11 +8,15 @@ # Technical writing team are the default reviewers for all markdown docs /doc/ @gl-docsteam -# Dev and Doc guidelines +# Doc subpaths +/doc/administration/monitoring/ @aqualls /doc/development/ @marcia @mjang1 /doc/development/documentation/ @mikelewis /doc/ci @marcel.amirault @sselhorn -/doc/.linting @marcel.amirault @eread @aqualls @mikelewis +/doc/user/clusters @aqualls +/doc/user/infrastructure @aqualls +/doc/user/project/clusters @aqualls +/doc/.vale/ @marcel.amirault @eread @aqualls @mikelewis # Frontend maintainers should see everything in `app/assets/` *.scss @annabeldunstone @gitlab-org/maintainers/frontend @@ -37,7 +41,6 @@ /ee/app/finders/ @gitlab-org/maintainers/database # Feature specific owners -/ee/lib/gitlab/code_owners/ @reprazent @kerrizor /ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono /lib/gitlab/auth/ldap/ @dblessing @mkozono /lib/gitlab/ci/templates/ @nolith @zj @@ -46,6 +49,11 @@ /ee/app/models/project_alias.rb @patrickbajao /ee/lib/api/project_aliases.rb @patrickbajao +# Code Owners +# +/ee/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh +/doc/user/project/code_owners.md @reprazent @kerrizor @garyh + # Quality owned files /qa/ @gl-quality diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml index 50dbef4459..5a6f2aacf9 100644 --- a/.gitlab/ci/docs.gitlab-ci.yml +++ b/.gitlab/ci/docs.gitlab-ci.yml @@ -62,7 +62,7 @@ docs lint: graphql-reference-verify: extends: - .default-retry - - .default-cache + - .rails-cache - .default-before_script - .docs:rules:graphql-reference-verify - .use-pg11 diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index 6e9119f295..4403187d42 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -1,157 +1,128 @@ -.assets-compile-cache: - cache: - paths: - - vendor/ruby/ - - public/assets/webpack/ - - assets-hash.txt - - .yarn-cache/ - - tmp/cache/assets/sprockets - - tmp/cache/babel-loader - - tmp/cache/vue-loader - - tmp/cache/webpack-dlls - -.gitlab:assets:compile-metadata: +.frontend-base: extends: - .default-retry - .default-before_script - .assets-compile-cache - image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-graphicsmagick-1.3.34-docker-19.03.1 + variables: + SETUP_DB: "false" + # we override the max_old_space_size to prevent OOM errors + NODE_OPTIONS: --max_old_space_size=3584 + WEBPACK_VENDOR_DLL: "true" + +.compile-assets-base: + extends: .frontend-base + image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.27-lfs-2.9-node-12.x-yarn-1.21-graphicsmagick-1.3.34 stage: prepare + script: + - node --version + - run_timed_command "retry yarn install --frozen-lockfile" + - free -m + - run_timed_command "bin/rake gitlab:assets:compile > assets-compile.log 2>&1" + - run_timed_command "scripts/clean-old-cached-assets" + +compile-production-assets: + extends: + - .compile-assets-base + - .frontend:rules:compile-production-assets variables: NODE_ENV: "production" RAILS_ENV: "production" - SETUP_DB: "false" - SKIP_STORAGE_VALIDATION: "true" WEBPACK_REPORT: "true" - # we override the max_old_space_size to prevent OOM errors - NODE_OPTIONS: --max_old_space_size=3584 - cache: - key: "assets-compile:production:v1" artifacts: name: webpack-report expire_in: 31d paths: - - webpack-report/ - assets-compile.log # These assets are used in multiple locations: # - 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 - - public/assets + - public/assets/ + - webpack-report/ when: always - script: - - node --version - - retry yarn install --frozen-lockfile --production --cache-folder .yarn-cache --prefer-offline - - free -m - - time bin/rake gitlab:assets:compile > assets-compile.log 2>&1 - - scripts/clean-old-cached-assets + after_script: - rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here -gitlab:assets:compile pull-push-cache: +compile-test-assets: extends: - - .gitlab:assets:compile-metadata - - .frontend:rules:gitlab-assets-compile-pull-push-cache - cache: - policy: pull-push + - .compile-assets-base + - .frontend:rules:compile-test-assets + artifacts: + expire_in: 7d + paths: + - assets-compile.log + - public/assets/ + - node_modules/@gitlab/svgs/dist/icons.json # app/helpers/icons_helper.rb uses this file + when: always -gitlab:assets:compile pull-cache: +compile-test-assets as-if-foss: extends: - - .gitlab:assets:compile-metadata - - .frontend:rules:gitlab-assets-compile-pull-cache + - compile-test-assets + - .frontend:rules:compile-test-assets-as-if-foss + - .as-if-foss + +update-assets-compile-production-cache: + extends: + - compile-production-assets + - .shared:rules:update-cache + stage: prepare + artifacts: {} # This job's purpose is only to update the cache. cache: - policy: pull + policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up. + +update-assets-compile-test-cache: + extends: + - compile-test-assets + - .shared:rules:update-cache + stage: prepare + artifacts: {} # This job's purpose is only to update the cache. + cache: + policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up. + +update-yarn-cache: + extends: + - .default-retry + - .yarn-cache + - .shared:rules:update-cache + stage: prepare + script: + - source scripts/utils.sh + - run_timed_command "retry yarn install --frozen-lockfile" + cache: + policy: push build-assets-image: extends: - .use-kaniko - - .frontend:rules:gitlab-assets-compile-pull-cache + - .frontend:rules:compile-production-assets stage: build-images - needs: ["gitlab:assets:compile pull-cache"] + needs: ["compile-production-assets"] variables: GIT_DEPTH: "1" script: # TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists # We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines # https://gitlab.com/gitlab-org/gitlab/issues/208389 - - scripts/build_assets_image - -.compile-assets-metadata: - extends: - - .default-retry - - .default-before_script - - .assets-compile-cache - stage: prepare - script: - - node --version - - retry yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline - - free -m - - time bin/rake gitlab:assets:compile > assets-compile.log 2>&1 - - scripts/clean-old-cached-assets - variables: - SETUP_DB: "false" - # we override the max_old_space_size to prevent OOM errors - NODE_OPTIONS: --max_old_space_size=3584 - WEBPACK_VENDOR_DLL: "true" - cache: - key: "assets-compile:test:v1" - artifacts: - expire_in: 7d - paths: - - node_modules - - public/assets - - assets-compile.log - when: always - -compile-assets pull-push-cache: - extends: - - .compile-assets-metadata - - .frontend:rules:compile-assets-pull-push-cache - cache: - policy: pull-push - -compile-assets pull-push-cache as-if-foss: - extends: - - .compile-assets-metadata - - .frontend:rules:compile-assets-pull-push-cache-as-if-foss - - .as-if-foss - cache: - policy: pull-push - key: "assets-compile:test:as-if-foss:v1" - -compile-assets pull-cache: - extends: - - .compile-assets-metadata - - .frontend:rules:compile-assets-pull-cache - cache: - policy: pull - -compile-assets pull-cache as-if-foss: - extends: - - .compile-assets-metadata - - .frontend:rules:compile-assets-pull-cache-as-if-foss - - .as-if-foss - cache: - policy: pull - key: "assets-compile:test:as-if-foss:v1" + - run_timed_command "scripts/build_assets_image" + retry: 2 .frontend-fixtures-base: extends: - - .default-retry + - .frontend-base - .rails-cache - - .default-before_script - .use-pg11 stage: fixtures - needs: ["setup-test-env", "compile-assets pull-cache"] + needs: ["setup-test-env", "compile-test-assets"] + variables: + SETUP_DB: "true" script: - run_timed_command "scripts/gitaly-test-build" - run_timed_command "scripts/gitaly-test-spawn" - - run_timed_command "bundle exec rake frontend:fixtures" + - run_timed_command "bin/rake frontend:fixtures" artifacts: name: frontend-fixtures expire_in: 31d when: always paths: - - node_modules - - public/assets - tmp/tests/frontend/ frontend-fixtures: @@ -165,25 +136,27 @@ frontend-fixtures-as-if-foss: - .frontend:rules:default-frontend-jobs-as-if-foss - .as-if-foss -.frontend-job-base: +.frontend-test-base: extends: - .default-retry - - .default-cache - - .default-before_script + - .yarn-cache variables: USE_BUNDLE_INSTALL: "false" SETUP_DB: "false" stage: test + before_script: + - source scripts/utils.sh .karma-base: - extends: .frontend-job-base + extends: .frontend-test-base variables: # we override the max_old_space_size to prevent OOM errors NODE_OPTIONS: --max_old_space_size=3584 script: + - source scripts/utils.sh - export BABEL_ENV=coverage CHROME_LOG_FILE=chrome_debug.log - - date - - yarn karma + - run_timed_command "retry yarn install --frozen-lockfile" + - run_timed_command "yarn karma" karma: extends: @@ -210,15 +183,11 @@ karma-as-if-foss: needs: ["frontend-fixtures-as-if-foss"] .jest-base: - extends: .frontend-job-base + extends: .frontend-test-base script: - - date - - yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js - cache: - key: jest - paths: - - tmp/cache/jest/ - policy: pull-push + - source scripts/utils.sh + - run_timed_command "retry yarn install --frozen-lockfile" + - run_timed_command "yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js" jest: extends: @@ -235,21 +204,17 @@ jest: - tmp/tests/frontend/ reports: junit: junit_jest.xml - parallel: 2 + parallel: 4 jest-integration: extends: - - .frontend-job-base + - .frontend-test-base - .frontend:rules:default-frontend-jobs script: - - date - - yarn jest:integration --ci + - source scripts/utils.sh + - run_timed_command "retry yarn install --frozen-lockfile" + - run_timed_command "yarn jest:integration --ci" needs: ["frontend-fixtures"] - cache: - key: jest-integration - paths: - - tmp/cache/jest/ - policy: pull-push jest-as-if-foss: extends: @@ -257,8 +222,7 @@ jest-as-if-foss: - .frontend:rules:default-frontend-jobs-as-if-foss - .as-if-foss needs: ["frontend-fixtures-as-if-foss"] - cache: - policy: pull + parallel: 2 coverage-frontend: extends: @@ -269,33 +233,26 @@ coverage-frontend: stage: post-test before_script: - source scripts/utils.sh - - retry yarn install --frozen-lockfile + - run_timed_command "retry yarn install --frozen-lockfile" script: - - yarn node scripts/frontend/merge_coverage_frontend.js + - run_timed_command "yarn node scripts/frontend/merge_coverage_frontend.js" artifacts: name: coverage-frontend expire_in: 31d paths: - coverage-frontend/ - cache: - policy: pull .qa-frontend-node: extends: - .default-retry + - .yarn-cache - .frontend:rules:qa-frontend-node stage: test dependencies: [] - cache: - key: "$CI_JOB_NAME" - paths: - - .yarn-cache/ - policy: pull-push script: - - date - - yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline - - date - - yarn run webpack-prod + - source scripts/utils.sh + - run_timed_command "yarn install --frozen-lockfile" + - run_timed_command "yarn run webpack-prod" qa-frontend-node:10: extends: .qa-frontend-node @@ -310,27 +267,39 @@ qa-frontend-node:latest: webpack-dev-server: extends: - .default-retry + - .yarn-cache - .frontend:rules:default-frontend-jobs stage: test needs: [] variables: WEBPACK_MEMORY_TEST: "true" WEBPACK_VENDOR_DLL: "true" - cache: - key: - files: - - yarn.lock - prefix: "v1" - paths: - - node_modules/ - - tmp/cache/webpack-dlls/ script: - source scripts/utils.sh - - retry yarn install --frozen-lockfile - - retry yarn webpack-vendor - - node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js + - run_timed_command "retry yarn install --frozen-lockfile" + - run_timed_command "retry yarn webpack-vendor" + - run_timed_command "node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js" artifacts: name: webpack-dev-server expire_in: 31d paths: - webpack-dev-server.json + +bundle-size-review: + extends: + - .default-retry + - .frontend:rules:bundle-size-review + image: registry.gitlab.com/gitlab-org/gitlab-build-images:danger + stage: test + needs: ["compile-production-assets"] + script: + - mkdir -p bundle-size-review + - cp webpack-report/index.html bundle-size-review/bundle-report.html + - yarn global add https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics.git + - danger --dangerfile=danger/bundle_size/Dangerfile --fail-on-errors=true --verbose --danger_id=bundle-size-review + artifacts: + when: always + name: bundle-size-review + expire_in: 31d + paths: + - bundle-size-review diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml index e6619ff2b6..30e3abf13b 100644 --- a/.gitlab/ci/global.gitlab-ci.yml +++ b/.gitlab/ci/global.gitlab-ci.yml @@ -10,49 +10,61 @@ .default-before_script: before_script: - - date - '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb' - export GOPATH=$CI_PROJECT_DIR/.go - mkdir -p $GOPATH - source scripts/utils.sh - source scripts/prepare_build.sh - - date - -# Jobs that only need to pull cache -.default-cache: - cache: - key: "debian-stretch-ruby-2.6.6-pg11-node-12.x" - paths: - - .go/pkg/mod - - vendor/ruby - - .yarn-cache/ - - vendor/gitaly-ruby - policy: pull .rails-cache: cache: - key: - files: - - Gemfile.lock - - GITALY_SERVER_VERSION - prefix: "ruby-go-cache-v1" + key: "rails-v1" paths: - - vendor/ruby - - vendor/gitaly-ruby - - .go/pkg/mod + - vendor/ruby/ + - vendor/gitaly-ruby/ + - .go/pkg/mod/ + policy: pull + +.static-analysis-cache: + cache: + key: "static-analysis-v1" + paths: + - vendor/ruby/ + - node_modules/ + - tmp/rubocop_cache/ + policy: pull + +.qa-cache: + cache: + key: "qa-v1" + paths: + - qa/vendor/ruby/ policy: pull .yarn-cache: cache: - key: - files: - - yarn.lock - prefix: "v1" + key: "yarn-v1" paths: - node_modules/ + - tmp/cache/webpack-dlls/ + policy: pull + +.assets-compile-cache: + cache: + key: "assets-compile-${NODE_ENV}-v1" + paths: + - vendor/ruby/ + - node_modules/ + - assets-hash.txt + - public/assets/webpack/ + - tmp/cache/assets/sprockets/ + - tmp/cache/babel-loader/ + - tmp/cache/vue-loader/ + - tmp/cache/webpack-dlls/ + policy: pull .use-pg11: - image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34" + image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34" services: - name: postgres:11.6 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] @@ -61,7 +73,7 @@ POSTGRES_HOST_AUTH_METHOD: trust .use-pg11-ee: - image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34" + image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34" services: - name: postgres:11.6 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] @@ -75,6 +87,7 @@ name: gcr.io/kaniko-project/executor:debug-v0.20.0 entrypoint: [""] before_script: + - source scripts/utils.sh - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json diff --git a/.gitlab/ci/memory.gitlab-ci.yml b/.gitlab/ci/memory.gitlab-ci.yml index 79dfc88d13..ef6c9b9c8f 100644 --- a/.gitlab/ci/memory.gitlab-ci.yml +++ b/.gitlab/ci/memory.gitlab-ci.yml @@ -1,7 +1,7 @@ .only-code-memory-job-base: extends: - .default-retry - - .default-cache + - .rails-cache - .default-before_script - .memory:rules @@ -39,12 +39,11 @@ memory-on-boot: - .only-code-memory-job-base - .use-pg11 stage: test - needs: ["setup-test-env", "compile-assets pull-cache"] + needs: ["setup-test-env", "compile-test-assets"] variables: NODE_ENV: "production" RAILS_ENV: "production" SETUP_DB: "true" - SKIP_STORAGE_VALIDATION: "true" # we override the max_old_space_size to prevent OOM errors NODE_OPTIONS: --max_old_space_size=3584 script: diff --git a/.gitlab/ci/pages.gitlab-ci.yml b/.gitlab/ci/pages.gitlab-ci.yml index 218ec7043d..a66e0d88db 100644 --- a/.gitlab/ci/pages.gitlab-ci.yml +++ b/.gitlab/ci/pages.gitlab-ci.yml @@ -3,11 +3,16 @@ pages: - .default-retry - .pages:rules stage: pages - dependencies: ["rspec:coverage", "karma", "gitlab:assets:compile pull-cache"] + dependencies: + - rspec:coverage + - coverage-frontend + - karma + - compile-production-assets script: - mv public/ .public/ - mkdir public/ - mv coverage/ public/coverage-ruby/ || true + - mv coverage-frontend/ public/coverage-frontend/ || true - mv coverage-javascript/ public/coverage-javascript/ || true - mv webpack-report/ public/webpack-report/ || true - cp .public/assets/application-*.css public/application.css || true diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml index 40ef13dd92..20527b690a 100644 --- a/.gitlab/ci/qa.gitlab-ci.yml +++ b/.gitlab/ci/qa.gitlab-ci.yml @@ -1,12 +1,9 @@ .qa-job-base: extends: - .default-retry + - .qa-cache stage: test needs: [] - cache: - key: "qa-framework-jobs:v1" - paths: - - vendor/ruby before_script: - '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb' - cd qa/ @@ -22,11 +19,9 @@ qa:internal: qa:internal-as-if-foss: extends: - - .qa-job-base + - qa:internal - .qa:rules:as-if-foss - .as-if-foss - script: - - bundle exec rspec qa:selectors: extends: @@ -41,6 +36,16 @@ qa:selectors-as-if-foss: - .qa:rules:as-if-foss - .as-if-foss +update-qa-cache: + extends: + - .qa-job-base + - .shared:rules:update-cache + stage: prepare + script: + - echo "Cache has been updated and ready to be uploaded." + cache: + policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up. + .package-and-qa-base: image: ruby:2.6-alpine stage: qa diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index e8087aebce..f73e0c1d50 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -1,6 +1,3 @@ -.rails:needs:setup-and-assets: - needs: ["setup-test-env", "compile-assets pull-cache"] - .rails-job-base: extends: - .default-retry @@ -35,32 +32,54 @@ setup-test-env: - tmp/tests/repositories - tmp/tests/second_storage when: always + +update-rails-cache: + extends: + - setup-test-env + - .shared:rules:update-cache + artifacts: {} # This job's purpose is only to update the cache. cache: + policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up. + +.static-analysis-base: + extends: + - .default-retry + - .default-before_script + - .static-analysis-cache + needs: [] + variables: + SETUP_DB: "false" + ENABLE_SPRING: "1" + +update-static-analysis-cache: + extends: + - .static-analysis-base + - .shared:rules:update-cache + stage: prepare + script: + - 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" + - 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: + # 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. policy: pull-push static-analysis: extends: - - .rails-job-base + - .static-analysis-base - .rails:rules:default-refs-code-backstage-qa - - .rails:needs:setup-and-assets stage: test - variables: - SETUP_DB: "false" - parallel: 2 + parallel: 4 script: + - run_timed_command "retry yarn install --frozen-lockfile" - scripts/static-analysis - cache: - key: "ruby-2.6.6-pg11-rubocop" - paths: - - vendor/ruby - - tmp/rubocop_cache - policy: pull-push downtime_check: extends: - .rails-job-base - .rails:rules:downtime_check - needs: ["setup-test-env"] + needs: [] stage: test variables: SETUP_DB: "false" @@ -70,7 +89,7 @@ downtime_check: .rspec-base: extends: .rails-job-base stage: test - needs: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache"] + needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"] script: - run_timed_command "scripts/gitaly-test-build" - run_timed_command "scripts/gitaly-test-spawn" @@ -173,7 +192,7 @@ db:migrate-from-v12.10.0: db:rollback: extends: .db-job-base script: - - bundle exec rake db:migrate VERSION=20180101160629 + - bundle exec rake db:migrate VERSION=20181228175414 - bundle exec rake db:migrate SKIP_SCHEMA_VERSION_CHECK=true gitlab:setup: @@ -218,8 +237,6 @@ rspec:coverage: - memory-on-boot variables: SETUP_DB: "false" - cache: - policy: pull script: - bundle exec scripts/merge-simplecov - bundle exec scripts/gather-test-memory-data @@ -247,7 +264,7 @@ rspec:coverage: - .rails:rules:as-if-foss - .as-if-foss - .use-pg11 - needs: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache as-if-foss"] + needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss"] .rspec-ee-base-pg11: extends: @@ -323,3 +340,26 @@ db:rollback geo: - bundle exec rake geo:db:migrate # EE: default refs (MRs, master, schedules) jobs # ################################################## + +################################################## +# EE: Canonical MR pipelines +rspec foss-impact: + extends: + - .rspec-base + - .as-if-foss + - .rails:rules:ee-mr-only + - .use-pg11 + script: + - install_gitlab_gem + - run_timed_command "scripts/gitaly-test-build" + - run_timed_command "scripts/gitaly-test-spawn" + - source scripts/rspec_helpers.sh + - tooling/bin/find_foss_tests tmp/matching_foss_tests.txt + - rspec_matched_tests tmp/matching_foss_tests.txt "--tag ~quarantine --tag ~geo --tag ~level:migration" + artifacts: + expire_in: 7d + paths: + - tmp/matching_foss_tests.txt + - tmp/capybara/ +# EE: Merge Request pipelines +################################################## diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml index 153334e1af..65abb6c5cb 100644 --- a/.gitlab/ci/reports.gitlab-ci.yml +++ b/.gitlab/ci/reports.gitlab-ci.yml @@ -94,9 +94,9 @@ dependency_scanning: stage: test needs: [] variables: + DS_MAJOR_VERSION: 2 DS_EXCLUDED_PATHS: "qa/qa/ee/fixtures/secure_premade_reports,spec,ee/spec" # GitLab-specific script: - - export DS_VERSION=${SP_VERSION:-$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')} - | if ! docker info &>/dev/null; then if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then @@ -138,7 +138,7 @@ dependency_scanning: ) \ --volume "$PWD:/code" \ --volume /var/run/docker.sock:/var/run/docker.sock \ - "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$DS_VERSION" /code + "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$DS_MAJOR_VERSION" /code artifacts: paths: - gl-dependency-scanning-report.json # GitLab-specific @@ -146,37 +146,38 @@ dependency_scanning: dependency_scanning: gl-dependency-scanning-report.json expire_in: 1 week # GitLab-specific -# We need to duplicate this job's definition because it seems it's impossible to -# override an included `only.refs`. -# See https://gitlab.com/gitlab-org/gitlab/issues/31371. -dast: - extends: - - .default-retry - - .reports:rules:dast - # This is needed so that manual jobs with needs don't block the pipeline. - # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979. - dependencies: ["review-deploy"] - stage: qa # GitLab-specific - image: - name: "registry.gitlab.com/gitlab-org/security-products/dast:$DAST_VERSION" - variables: - # To be done in a later iteration - # DAST_USERNAME: "root" - # DAST_USERNAME_FIELD: "user[login]" - # DAST_PASSWORD_FIELD: "user[passowrd]" - DAST_VERSION: 1 - script: - - 'export DAST_WEBSITE="${DAST_WEBSITE:-$(cat environment_url.txt)}"' - # To be done in a later iteration - # - 'export DAST_AUTH_URL="${DAST_WEBSITE}/users/sign_in"' - # - 'export DAST_PASSWORD="${REVIEW_APPS_ROOT_PASSWORD}"' - - /analyze -t $DAST_WEBSITE - artifacts: - paths: - - gl-dast-report.json # GitLab-specific - reports: - dast: gl-dast-report.json - expire_in: 1 week # GitLab-specific +# Temporarily disabling review apps +## We need to duplicate this job's definition because it seems it's impossible to +## override an included `only.refs`. +## See https://gitlab.com/gitlab-org/gitlab/issues/31371. +#dast: +# extends: +# - .default-retry +# - .reports:rules:dast +# # This is needed so that manual jobs with needs don't block the pipeline. +# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979. +# dependencies: ["review-deploy"] +# stage: qa # GitLab-specific +# image: +# name: "registry.gitlab.com/gitlab-org/security-products/dast:$DAST_VERSION" +# variables: +# # To be done in a later iteration +# # DAST_USERNAME: "root" +# # DAST_USERNAME_FIELD: "user[login]" +# # DAST_PASSWORD_FIELD: "user[passowrd]" +# DAST_VERSION: 1 +# script: +# - 'export DAST_WEBSITE="${DAST_WEBSITE:-$(cat environment_url.txt)}"' +# # To be done in a later iteration +# # - 'export DAST_AUTH_URL="${DAST_WEBSITE}/users/sign_in"' +# # - 'export DAST_PASSWORD="${REVIEW_APPS_ROOT_PASSWORD}"' +# - /analyze -t $DAST_WEBSITE +# artifacts: +# paths: +# - gl-dast-report.json # GitLab-specific +# reports: +# dast: gl-dast-report.json +# expire_in: 1 week # GitLab-specific # To be done in a later iteration: https://gitlab.com/gitlab-org/gitlab/issues/31160#note_278188255 # schedule:dast: diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml index 46a281cd48..6898da95c1 100644 --- a/.gitlab/ci/review.gitlab-ci.yml +++ b/.gitlab/ci/review.gitlab-ci.yml @@ -1,13 +1,13 @@ build-qa-image: extends: - .use-kaniko - - .default-retry - .review:rules:build-qa-image stage: build-images needs: [] script: - export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}" - /kaniko/executor --context=${CI_PROJECT_DIR} --dockerfile=${CI_PROJECT_DIR}/qa/Dockerfile --destination=${QA_IMAGE} --cache=true + retry: 2 review-cleanup: extends: @@ -27,24 +27,25 @@ review-cleanup: - ruby -rrubygems scripts/review_apps/automated_cleanup.rb - gcp_cleanup -review-build-cng: - extends: - - .default-retry - - .review:rules:review-build-cng - image: ruby:2.6-alpine - stage: review-prepare - before_script: - - source scripts/utils.sh - - install_api_client_dependencies_with_apk - - install_gitlab_gem - needs: - - job: gitlab:assets:compile pull-cache - artifacts: false - script: - - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng - # When the job is manual, review-deploy is also manual and we don't want people - # to have to manually start the jobs in sequence, so we do it for them. - - '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"' +# Temporarily disabling review apps +#review-build-cng: +# extends: +# - .default-retry +# - .review:rules:review-build-cng +# image: ruby:2.6-alpine +# stage: review-prepare +# before_script: +# - source scripts/utils.sh +# - install_api_client_dependencies_with_apk +# - install_gitlab_gem +# needs: +# - job: compile-production-assets +# artifacts: false +# script: +# - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng +# # When the job is manual, review-deploy is also manual and we don't want people +# # to have to manually start the jobs in sequence, so we do it for them. +# - '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"' .review-workflow-base: extends: @@ -53,43 +54,44 @@ review-build-cng: variables: HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}" DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}" - GITLAB_HELM_CHART_REF: "v3.3.3" + GITLAB_HELM_CHART_REF: "master" environment: name: review/${CI_COMMIT_REF_NAME} url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN} on_stop: review-stop auto_stop_in: 48 hours -review-deploy: - extends: - - .review-workflow-base - - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise - stage: review - dependencies: [] - resource_group: "review/${CI_COMMIT_REF_NAME}" - before_script: - - export GITLAB_SHELL_VERSION=$( environment_url.txt - - source ./scripts/utils.sh - - install_api_client_dependencies_with_apk - - source scripts/review_apps/review-apps.sh - script: - - check_kube_domain - - ensure_namespace - - install_external_dns - - download_chart - - date - - deploy || (display_deployment_debug && exit 1) - # 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. - - '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"' - - '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"' - artifacts: - paths: [environment_url.txt] - expire_in: 2 days - when: always +# Temporarily disabling review apps +#review-deploy: +# extends: +# - .review-workflow-base +# - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise +# stage: review +# dependencies: [] +# resource_group: "review/${CI_COMMIT_REF_NAME}" +# before_script: +# - export GITLAB_SHELL_VERSION=$( environment_url.txt +# - source ./scripts/utils.sh +# - install_api_client_dependencies_with_apk +# - source scripts/review_apps/review-apps.sh +# script: +# - check_kube_domain +# - ensure_namespace +# - install_external_dns +# - download_chart +# - date +# - deploy || (display_deployment_debug && exit 1) +# # 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. +# - '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"' +# - '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"' +# artifacts: +# paths: [environment_url.txt] +# expire_in: 2 days +# when: always .review-stop-base: extends: .review-workflow-base @@ -122,109 +124,110 @@ review-stop: script: - delete_release -.review-qa-base: - extends: - - .default-retry - - .use-docker-in-docker - image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6 - stage: qa - # This is needed so that manual jobs with needs don't block the pipeline. - # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979. - dependencies: ["review-deploy"] - variables: - QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa" - QA_CAN_TEST_GIT_PROTOCOL_V2: "false" - QA_DEBUG: "true" - GITLAB_USERNAME: "root" - GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}" - GITLAB_ADMIN_USERNAME: "root" - GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}" - GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}" - EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}" - before_script: - - export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}" - - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)" - - echo "${CI_ENVIRONMENT_URL}" - - echo "${QA_IMAGE}" - - source scripts/utils.sh - - install_api_client_dependencies_with_apk - - gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}} - artifacts: - paths: - - ./qa/gitlab-qa-run-* - expire_in: 7 days - when: always - -review-qa-smoke: - extends: - - .review-qa-base - - .review:rules:review-qa-smoke - script: - - gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" - -review-qa-all: - extends: - - .review-qa-base - - .review:rules:mr-only-manual - parallel: 5 - script: - - export KNAPSACK_REPORT_PATH=knapsack/master_report.json - - export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb - - gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation - -review-performance: - extends: - - .default-retry - - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise - image: - name: sitespeedio/sitespeed.io:6.3.1 - entrypoint: [""] - stage: qa - # This is needed so that manual jobs with needs don't block the pipeline. - # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979. - dependencies: ["review-deploy"] - before_script: - - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)" - - echo "${CI_ENVIRONMENT_URL}" - - mkdir -p gitlab-exporter - - wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js - - mkdir -p sitespeed-results - script: - - /start.sh --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}" - after_script: - - mv sitespeed-results/data/performance.json performance.json - artifacts: - paths: - - sitespeed-results/ - reports: - performance: performance.json - expire_in: 31d - -parallel-spec-reports: - extends: - - .review:rules:mr-only-manual - image: ruby:2.6-alpine - stage: post-qa - dependencies: ["review-qa-all"] - variables: - NEW_PARALLEL_SPECS_REPORT: qa/report-new.html - BASE_ARTIFACT_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/qa/" - script: - - apk add --update build-base libxml2-dev libxslt-dev && rm -rf /var/cache/apk/* - - gem install nokogiri --no-document - - cd qa/gitlab-qa-run-*/gitlab-* - - ARTIFACT_DIRS=$(pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_) - - cd - - - '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}' - - scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm - artifacts: - when: always - paths: - - qa/report-new.html - - qa/gitlab-qa-run-* - reports: - junit: qa/gitlab-qa-run-*/**/rspec-*.xml - expire_in: 31d +# Temporarily disabling review apps +#.review-qa-base: +# extends: +# - .default-retry +# - .use-docker-in-docker +# image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6 +# stage: qa +# # This is needed so that manual jobs with needs don't block the pipeline. +# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979. +# dependencies: ["review-deploy"] +# variables: +# QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa" +# QA_CAN_TEST_GIT_PROTOCOL_V2: "false" +# QA_DEBUG: "true" +# GITLAB_USERNAME: "root" +# GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}" +# GITLAB_ADMIN_USERNAME: "root" +# GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}" +# GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}" +# EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}" +# before_script: +# - export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}" +# - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)" +# - echo "${CI_ENVIRONMENT_URL}" +# - echo "${QA_IMAGE}" +# - source scripts/utils.sh +# - install_api_client_dependencies_with_apk +# - gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}} +# artifacts: +# paths: +# - ./qa/gitlab-qa-run-* +# expire_in: 7 days +# when: always +# +#review-qa-smoke: +# extends: +# - .review-qa-base +# - .review:rules:review-qa-smoke +# script: +# - gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" +# +#review-qa-all: +# extends: +# - .review-qa-base +# - .review:rules:mr-only-manual +# parallel: 5 +# script: +# - export KNAPSACK_REPORT_PATH=knapsack/master_report.json +# - export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb +# - gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation +# +#review-performance: +# extends: +# - .default-retry +# - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise +# image: +# name: sitespeedio/sitespeed.io:6.3.1 +# entrypoint: [""] +# stage: qa +# # This is needed so that manual jobs with needs don't block the pipeline. +# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979. +# dependencies: ["review-deploy"] +# before_script: +# - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)" +# - echo "${CI_ENVIRONMENT_URL}" +# - mkdir -p gitlab-exporter +# - wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js +# - mkdir -p sitespeed-results +# script: +# - /start.sh --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}" +# after_script: +# - mv sitespeed-results/data/performance.json performance.json +# artifacts: +# paths: +# - sitespeed-results/ +# reports: +# performance: performance.json +# expire_in: 31d +# +#parallel-spec-reports: +# extends: +# - .review:rules:mr-only-manual +# image: ruby:2.6-alpine +# stage: post-qa +# dependencies: ["review-qa-all"] +# variables: +# NEW_PARALLEL_SPECS_REPORT: qa/report-new.html +# BASE_ARTIFACT_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/qa/" +# script: +# - apk add --update build-base libxml2-dev libxslt-dev && rm -rf /var/cache/apk/* +# - gem install nokogiri --no-document +# - cd qa/gitlab-qa-run-*/gitlab-* +# - ARTIFACT_DIRS=$(pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_) +# - cd - +# - '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}' +# - scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm +# artifacts: +# when: always +# paths: +# - qa/report-new.html +# - qa/gitlab-qa-run-* +# reports: +# junit: qa/gitlab-qa-run-*/**/rspec-*.xml +# expire_in: 31d danger-review: extends: @@ -238,5 +241,3 @@ danger-review: - source scripts/utils.sh - retry yarn install --frozen-lockfile - danger --fail-on-errors=true --verbose - cache: - policy: pull diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 383aca0043..fbbb0391ec 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -37,6 +37,9 @@ .if-merge-request-title-as-if-foss: &if-merge-request-title-as-if-foss if: '$CI_MERGE_REQUEST_TITLE =~ /RUN AS-IF-FOSS/' +.if-merge-request-title-update-caches: &if-merge-request-title-update-caches + if: '$CI_MERGE_REQUEST_TITLE =~ /UPDATE CACHE/' + .if-security-merge-request: &if-security-merge-request if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security" && $CI_MERGE_REQUEST_IID' @@ -49,6 +52,9 @@ .if-dot-com-gitlab-org-merge-request: &if-dot-com-gitlab-org-merge-request if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org" && $CI_MERGE_REQUEST_IID' +.if-dot-com-gitlab-org-and-security-merge-request: &if-dot-com-gitlab-org-and-security-merge-request + if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/security$)/ && $CI_MERGE_REQUEST_IID' + .if-dot-com-gitlab-org-and-security-tag: &if-dot-com-gitlab-org-and-security-tag if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/security$)/ && $CI_COMMIT_TAG' @@ -78,9 +84,11 @@ .frontend-patterns: &frontend-patterns - "{package.json,yarn.lock}" - - "{babel.config,jest.config}.js" + - "babel.config.js" + - "jest.config.{base,integration,unit}.js" - ".csscomb.json" - "Dockerfile.assets" + - "config/**/*.js" - "vendor/assets/**/*" - "{,ee/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*" @@ -93,7 +101,8 @@ .code-patterns: &code-patterns - "{package.json,yarn.lock}" - - "{babel.config,jest.config}.js" + - "babel.config.js" + - "jest.config.{base,integration,unit}.js" - ".csscomb.json" - "Dockerfile.assets" - "vendor/assets/**/*" @@ -113,7 +122,8 @@ .code-backstage-patterns: &code-backstage-patterns - "{package.json,yarn.lock}" - - "{babel.config,jest.config}.js" + - "babel.config.js" + - "jest.config.{base,integration,unit}.js" - ".csscomb.json" - "Dockerfile.assets" - "vendor/assets/**/*" @@ -135,7 +145,8 @@ .code-qa-patterns: &code-qa-patterns - "{package.json,yarn.lock}" - - "{babel.config,jest.config}.js" + - "babel.config.js" + - "jest.config.{base,integration,unit}.js" - ".csscomb.json" - "Dockerfile.assets" - "vendor/assets/**/*" @@ -154,7 +165,8 @@ .code-backstage-qa-patterns: &code-backstage-qa-patterns - "{package.json,yarn.lock}" - - "{babel.config,jest.config}.js" + - "babel.config.js" + - "jest.config.{base,integration,unit}.js" - ".csscomb.json" - "Dockerfile.assets" - "vendor/assets/**/*" @@ -177,6 +189,14 @@ - ".dockerignore" - "qa/**/*" +################ +# Shared rules # +################ +.shared:rules:update-cache: + rules: + - <<: *if-master-schedule-2-hourly + - <<: *if-merge-request-title-update-caches + #################### # Cache repo rules # #################### @@ -238,51 +258,21 @@ ################## # Frontend rules # ################## -# This job only runs on `master` since it pushes to the cache. -.frontend:rules:gitlab-assets-compile-pull-push-cache: - rules: - - <<: *if-not-canonical-namespace - when: never - - <<: *if-master-refs - changes: *code-backstage-qa-patterns - when: on_success - -.frontend:rules:gitlab-assets-compile-pull-cache: +.frontend:rules:compile-production-assets: rules: - <<: *if-not-canonical-namespace when: never - <<: *if-default-refs changes: *code-backstage-qa-patterns - when: on_success -.frontend:rules:compile-assets-pull-push-cache: +.frontend:rules:compile-test-assets: rules: - - <<: *if-master-refs - changes: *code-backstage-qa-patterns - when: on_success + - changes: *code-backstage-qa-patterns -# This job only runs on `master` since it pushes to the cache. -.frontend:rules:compile-assets-pull-push-cache-as-if-foss: +.frontend:rules:compile-test-assets-as-if-foss: rules: - <<: *if-not-ee when: never - - <<: *if-master-push - changes: *code-backstage-qa-patterns - - <<: *if-master-schedule-2-hourly - -.frontend:rules:compile-assets-pull-cache: - rules: - - <<: *if-default-refs - changes: *code-backstage-qa-patterns - when: on_success - -.frontend:rules:compile-assets-pull-cache-as-if-foss: - rules: - - <<: *if-not-ee - when: never - - <<: *if-master-push - changes: *code-backstage-qa-patterns - - <<: *if-master-schedule-2-hourly - <<: *if-security-merge-request changes: *code-backstage-qa-patterns - <<: *if-merge-request-title-as-if-foss @@ -293,15 +283,11 @@ rules: - <<: *if-default-refs changes: *code-backstage-patterns - when: on_success .frontend:rules:default-frontend-jobs-as-if-foss: rules: - <<: *if-not-ee when: never - - <<: *if-master-push - changes: *code-backstage-patterns - - <<: *if-master-schedule-2-hourly - <<: *if-security-merge-request changes: *code-backstage-patterns - <<: *if-merge-request-title-as-if-foss @@ -321,10 +307,8 @@ rules: - <<: *if-master-refs changes: *frontend-dependency-patterns - when: on_success - <<: *if-merge-request changes: *frontend-dependency-patterns - when: on_success .frontend:rules:qa-frontend-node-latest: rules: @@ -335,6 +319,12 @@ changes: *frontend-dependency-patterns allow_failure: true +.frontend:rules:bundle-size-review: + rules: + - if: '$DANGER_GITLAB_API_TOKEN && $CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' + changes: *frontend-patterns + allow_failure: true + ################ # Memory rules # ################ @@ -368,9 +358,6 @@ rules: - <<: *if-not-ee when: never - - <<: *if-master-push - changes: *code-qa-patterns - - <<: *if-master-schedule-2-hourly - <<: *if-security-merge-request changes: *code-qa-patterns - <<: *if-merge-request-title-as-if-foss @@ -379,13 +366,13 @@ .qa:rules:package-and-qa: rules: - - <<: *if-dot-com-gitlab-org-merge-request + - <<: *if-dot-com-gitlab-org-and-security-merge-request changes: *ci-patterns allow_failure: true - - <<: *if-dot-com-gitlab-org-merge-request + - <<: *if-dot-com-gitlab-org-and-security-merge-request changes: *qa-patterns allow_failure: true - - <<: *if-dot-com-gitlab-org-merge-request + - <<: *if-dot-com-gitlab-org-and-security-merge-request changes: *code-patterns when: manual allow_failure: true @@ -416,9 +403,6 @@ rules: - <<: *if-not-ee when: never - - <<: *if-master-push - changes: *code-backstage-patterns - - <<: *if-master-schedule-2-hourly - <<: *if-security-merge-request changes: *code-backstage-patterns - <<: *if-merge-request-title-as-if-foss @@ -434,6 +418,17 @@ - <<: *if-master-refs changes: *code-backstage-patterns +.rails:rules:ee-mr-only: + rules: + - <<: *if-not-ee + when: never + - <<: *if-merge-request-title-as-if-foss + when: never + - <<: *if-security-merge-request + changes: *code-backstage-patterns + - <<: *if-dot-com-gitlab-org-merge-request + changes: *code-backstage-patterns + .rails:rules:downtime_check: rules: - <<: *if-merge-request @@ -505,7 +500,7 @@ rules: - <<: *if-not-ee when: never - - <<: *if-dot-com-gitlab-org-merge-request + - <<: *if-dot-com-gitlab-org-and-security-merge-request changes: *code-qa-patterns - <<: *if-dot-com-gitlab-org-schedule diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml index 9be495f1ef..b878bec375 100644 --- a/.gitlab/ci/setup.gitlab-ci.yml +++ b/.gitlab/ci/setup.gitlab-ci.yml @@ -3,7 +3,7 @@ cache gems: extends: - .default-retry - - .default-cache + - .rails-cache - .default-before_script - .setup:rules:cache-gems stage: test diff --git a/.gitlab/ci/test-metadata.gitlab-ci.yml b/.gitlab/ci/test-metadata.gitlab-ci.yml index 65cce76fc4..1764e9136a 100644 --- a/.gitlab/ci/test-metadata.gitlab-ci.yml +++ b/.gitlab/ci/test-metadata.gitlab-ci.yml @@ -3,11 +3,6 @@ TESTS_METADATA_S3_BUCKET: "gitlab-ce-cache" before_script: - source scripts/utils.sh - cache: - key: tests_metadata - paths: - - knapsack/ - - rspec_flaky/ artifacts: expire_in: 31d paths: @@ -20,8 +15,6 @@ retrieve-tests-metadata: - .tests-metadata-state - .test-metadata:rules:retrieve-tests-metadata stage: prepare - cache: - policy: pull script: - source scripts/rspec_helpers.sh - retrieve_tests_metadata @@ -44,8 +37,6 @@ update-tests-metadata: - rspec-ee unit pg11 geo - rspec-ee integration pg11 geo - rspec-ee system pg11 geo - cache: - policy: push script: - retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document - source scripts/rspec_helpers.sh diff --git a/.gitlab/issue_templates/Acceptance_Testing.md b/.gitlab/issue_templates/Acceptance Testing.md similarity index 100% rename from .gitlab/issue_templates/Acceptance_Testing.md rename to .gitlab/issue_templates/Acceptance Testing.md diff --git a/.gitlab/issue_templates/Problem_Validation.md b/.gitlab/issue_templates/Problem Validation.md similarity index 100% rename from .gitlab/issue_templates/Problem_Validation.md rename to .gitlab/issue_templates/Problem Validation.md diff --git a/.gitlab/issue_templates/QA failure.md b/.gitlab/issue_templates/QA Failure.md similarity index 100% rename from .gitlab/issue_templates/QA failure.md rename to .gitlab/issue_templates/QA Failure.md diff --git a/.gitlab/issue_templates/Solution_validation b/.gitlab/issue_templates/Solution Validation.md similarity index 100% rename from .gitlab/issue_templates/Solution_validation rename to .gitlab/issue_templates/Solution Validation.md diff --git a/.gitlab/issue_templates/Test plan.md b/.gitlab/issue_templates/Test Plan.md similarity index 100% rename from .gitlab/issue_templates/Test plan.md rename to .gitlab/issue_templates/Test Plan.md diff --git a/.gitlab/merge_request_templates/Change documentation location.md b/.gitlab/merge_request_templates/Change Documentation Location.md similarity index 100% rename from .gitlab/merge_request_templates/Change documentation location.md rename to .gitlab/merge_request_templates/Change Documentation Location.md diff --git a/.gitlab/merge_request_templates/Documentation.md b/.gitlab/merge_request_templates/Documentation.md index 72bfd2cdec..282e80d700 100644 --- a/.gitlab/merge_request_templates/Documentation.md +++ b/.gitlab/merge_request_templates/Documentation.md @@ -24,6 +24,8 @@ - ~"development guidelines" and ~"Description templates (.gitlab/\*)" when creating/updating issue and MR description templates. - [ ] Assign the [designated Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments). +Do not add the ~"feature", ~"frontend", ~"backend", ~"bug", or ~"database" labels if you are only updating documentation. These labels will cause the MR to be added to code verification QA issues. + When applicable: - [ ] Update the [permissions table](https://docs.gitlab.com/ee/user/permissions.html). diff --git a/.gitlab/merge_request_templates/New static analysis check.md b/.gitlab/merge_request_templates/New Static Analysis Check.md similarity index 100% rename from .gitlab/merge_request_templates/New static analysis check.md rename to .gitlab/merge_request_templates/New Static Analysis Check.md diff --git a/.haml-lint.yml b/.haml-lint.yml index 399fa9656a..33a960f7ef 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -80,8 +80,8 @@ linters: ignored_cops: - Layout/BlockAlignment - Layout/EndAlignment + - Layout/LineLength - Lint/Void - - Metrics/LineLength - Naming/FileName - Style/AlignParameters - Style/BlockNesting @@ -92,7 +92,6 @@ linters: - Style/IfUnlessModifier - Style/IndentationWidth - Style/Next - - Style/TrailingBlankLines - Style/TrailingWhitespace - Style/WhileUntilModifier @@ -112,7 +111,7 @@ linters: - Layout/SpaceInsideArrayLiteralBrackets - Layout/SpaceInsideHashLiteralBraces - Layout/SpaceInsideStringInterpolation - - Layout/TrailingBlankLines + - Layout/TrailingEmptyLines - Lint/BooleanSymbol - Lint/LiteralInInterpolation - Lint/ParenthesesAsGroupedExpression diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index a79bba24ed..5bd7dc1883 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2020-04-20 07:11:26 +0000 using Haml-Lint version 0.34.0. +# on 2020-05-21 10:58:59 -0400 using Haml-Lint version 0.34.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -162,7 +162,6 @@ linters: - "app/views/projects/_home_panel.html.haml" - "app/views/projects/_import_project_pane.html.haml" - "app/views/projects/_issuable_by_email.html.haml" - - "app/views/projects/_md_preview.html.haml" - "app/views/projects/_readme.html.haml" - "app/views/projects/artifacts/_artifact.html.haml" - "app/views/projects/artifacts/_tree_file.html.haml" @@ -267,7 +266,6 @@ linters: - "app/views/projects/triggers/_index.html.haml" - "app/views/projects/triggers/_trigger.html.haml" - "app/views/projects/triggers/edit.html.haml" - - "app/views/projects/wikis/_pages_wiki_page.html.haml" - "app/views/search/results/_issue.html.haml" - "app/views/search/results/_note.html.haml" - "app/views/search/results/_snippet_blob.html.haml" @@ -277,6 +275,7 @@ linters: - "app/views/shared/_delete_label_modal.html.haml" - "app/views/shared/_group_form.html.haml" - "app/views/shared/_group_tips.html.haml" + - "app/views/shared/_md_preview.html.haml" - "app/views/shared/_milestone_expired.html.haml" - "app/views/shared/_no_password.html.haml" - "app/views/shared/_ping_consent.html.haml" @@ -313,6 +312,7 @@ linters: - "app/views/shared/snippets/_snippet.html.haml" - "app/views/shared/web_hooks/_form.html.haml" - "app/views/shared/web_hooks/_hook.html.haml" + - "app/views/shared/wikis/_pages_wiki_page.html.haml" - "app/views/u2f/_authenticate.html.haml" - "app/views/u2f/_register.html.haml" - "app/views/users/_deletion_guidance.html.haml" @@ -324,7 +324,6 @@ linters: - "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/new.html.haml" - - "ee/app/views/admin/licenses/show.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/users/_auditor_access_level_radio.html.haml" diff --git a/.markdownlint.json b/.markdownlint.json index 88e3d5f775..b4da68989f 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -43,8 +43,10 @@ "Consul", "Debian", "DevOps", + "Docker", "Elasticsearch", "Facebook", + "fastlane", "GDK", "Geo", "Git LFS", @@ -101,6 +103,7 @@ "OpenShift", "PgBouncer", "PostgreSQL", + "Praefect", "Prometheus", "Puma", "puma-worker-killer", diff --git a/.rubocop.yml b/.rubocop.yml index 3d013a650e..ed17799478 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,18 +2,21 @@ inherit_gem: gitlab-styles: - rubocop-default.yml -inherit_from: .rubocop_todo.yml require: - ./rubocop/rubocop - rubocop-rspec +inherit_from: + - .rubocop_todo.yml + - ./rubocop/rubocop-migrations.yml + inherit_mode: merge: - Include AllCops: TargetRubyVersion: 2.6 - TargetRailsVersion: 5.0 + TargetRailsVersion: 6.0 Exclude: - 'vendor/**/*' - 'node_modules/**/*' @@ -27,6 +30,7 @@ AllCops: - 'plugins/**/*' - 'file_hooks/**/*' CacheRootDirectory: tmp + MaxFilesInCache: 18000 Cop/AvoidKeywordArgumentsInSidekiqWorkers: Enabled: true @@ -178,6 +182,9 @@ Rails/ApplicationRecord: - ee/db/**/*.rb - ee/spec/**/*.rb +Cop/DefaultScope: + Enabled: true + Rails/FindBy: Enabled: true Include: @@ -186,6 +193,14 @@ Rails/FindBy: - 'spec/**/*.rb' - 'ee/spec/**/*.rb' +# This is currently exiting with a rubocop exception error and should be +# resolved hopefully a future update +# An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting +# app/models/abuse_report.rb:15:2. +# To see the complete backtrace run rubocop -d. +Rails/UniqueValidationWithoutIndex: + Enabled: false + # GitLab ################################################################### Gitlab/ModuleWithInstanceVariables: @@ -225,6 +240,7 @@ Gitlab/Json: - 'scripts/**/*' - 'lib/rspec_flaky/**/*' - 'lib/quality/**/*' + - 'lib/gitlab/danger/**/*' GitlabSecurity/PublicSend: Enabled: true @@ -240,10 +256,7 @@ GitlabSecurity/PublicSend: - 'ee/spec/**/*' Gitlab/DuplicateSpecLocation: - Exclude: - - ee/spec/lib/gitlab/gl_repository_spec.rb - - ee/spec/services/merge_requests/refresh_service_spec.rb - - ee/spec/services/ee/merge_requests/refresh_service_spec.rb + Enabled: true Cop/InjectEnterpriseEditionModule: Enabled: true @@ -259,12 +272,15 @@ Style/ReturnNil: Performance/RegexpMatch: Enabled: false -ActiveRecordAssociationReload: +Cop/ActiveRecordAssociationReload: Enabled: true Exclude: - 'spec/**/*' - 'ee/spec/**/*' +Gitlab/AvoidFeatureGet: + Enabled: true + Naming/PredicateName: Enabled: true Exclude: @@ -349,39 +365,17 @@ RSpec/LeakyConstantDeclaration: Exclude: - 'spec/db/schema_spec.rb' - 'spec/lib/feature_spec.rb' - - 'spec/lib/gitlab/ci/build/credentials/factory_spec.rb' - - 'spec/lib/gitlab/ci/config/entry/retry_spec.rb' - - 'spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb' - - 'spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb' - - 'spec/lib/gitlab/config/entry/factory_spec.rb' - 'spec/lib/gitlab/config/entry/simplifiable_spec.rb' - - 'spec/lib/gitlab/database/migration_helpers_spec.rb' - - 'spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb' - - 'spec/lib/gitlab/database/with_lock_retries_spec.rb' - - 'spec/lib/gitlab/git/diff_collection_spec.rb' - - 'spec/lib/gitlab/import_export/import_test_coverage_spec.rb' - - 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb' - - 'spec/lib/gitlab/jira_import/issues_importer_spec.rb' - - 'spec/lib/gitlab/no_cache_headers_spec.rb' - - 'spec/lib/gitlab/path_regex_spec.rb' - 'spec/lib/gitlab/quick_actions/dsl_spec.rb' - - 'spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb' - - 'spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb' - 'spec/lib/marginalia_spec.rb' - 'spec/mailers/notify_spec.rb' - - 'spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb' - 'spec/models/concerns/batch_destroy_dependent_associations_spec.rb' - 'spec/models/concerns/bulk_insert_safe_spec.rb' - 'spec/models/concerns/bulk_insertable_associations_spec.rb' - 'spec/models/concerns/triggerable_hooks_spec.rb' - 'spec/models/repository_spec.rb' - - 'spec/requests/api/graphql/tasks/task_completion_status_spec.rb' - - 'spec/serializers/commit_entity_spec.rb' - 'spec/services/clusters/applications/check_installation_progress_service_spec.rb' - - 'spec/services/clusters/applications/check_uninstall_progress_service_spec.rb' - - 'spec/support/shared_contexts/spam_constants.rb' - 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb' - - 'spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb' RSpec/EmptyLineAfterHook: Enabled: false @@ -452,4 +446,16 @@ Rails/TimeZone: - 'ee/app/services/**/*' - 'ee/spec/controllers/**/*' - 'ee/spec/services/**/*' + - 'app/models/**/*' + - 'spec/models/**/*' + - 'ee/app/models/**/*' + - 'ee/spec/models/**/*' +# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040 +Rails/SaveBang: + Enabled: true + Include: + - 'spec/**/*.rb' + - 'ee/spec/**/*.rb' + - 'qa/spec/**/*.rb' + - 'qa/qa/specs/**/*.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index bd0f9184cd..9e3a54fa7e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,30 +1,21 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-01-16 11:53:06 -0800 using RuboCop version 0.74.0. +# on 2020-05-20 16:32:14 -0400 using RuboCop version 0.82.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 299 +# Offense count: 308 # Cop supports --auto-correct. Capybara/CurrentPathExpectation: Enabled: false -# Offense count: 1432 +# Offense count: 1715 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: with_first_argument, with_fixed_indentation -Layout/AlignArguments: - Enabled: false - -# Offense count: 1630 -# Cop supports --auto-correct. -# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. -# SupportedHashRocketStyles: key, separator, table -# SupportedColonStyles: key, separator, table -# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit -Layout/AlignHash: +Layout/ArgumentAlignment: Enabled: false # Offense count: 13 @@ -41,7 +32,7 @@ Layout/ClosingHeredocIndentation: - 'spec/rubocop/cop/active_record_association_reload_spec.rb' - 'spec/services/task_list_toggle_service_spec.rb' -# Offense count: 9 +# Offense count: 13 # Cop supports --auto-correct. Layout/ClosingParenthesisIndentation: Exclude: @@ -52,7 +43,7 @@ Layout/ClosingParenthesisIndentation: - 'spec/support/helpers/stub_object_storage.rb' - 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb' -# Offense count: 69 +# Offense count: 72 # Cop supports --auto-correct. Layout/EmptyLinesAroundArguments: Exclude: @@ -60,46 +51,61 @@ Layout/EmptyLinesAroundArguments: - 'app/models/concerns/resolvable_discussion.rb' - 'app/models/diff_discussion.rb' - 'app/models/discussion.rb' - - 'ee/app/helpers/license_helper.rb' - 'ee/spec/models/geo/project_registry_spec.rb' - 'lib/banzai/pipeline/broadcast_message_pipeline.rb' - 'lib/banzai/pipeline/gfm_pipeline.rb' - 'lib/banzai/pipeline/single_line_pipeline.rb' - 'spec/features/markdown/copy_as_gfm_spec.rb' -# Offense count: 305 +# Offense count: 413 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_brackets -Layout/IndentFirstArrayElement: +Layout/FirstArrayElementIndentation: Enabled: false -# Offense count: 1005 +# Offense count: 1218 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces -Layout/IndentFirstHashElement: +Layout/FirstHashElementIndentation: Enabled: false # Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: consistent, align_parentheses -Layout/IndentFirstParameter: +Layout/FirstParameterIndentation: Exclude: - 'lib/gitlab/cross_project_access.rb' - 'lib/gitlab/data_builder/push.rb' - 'spec/support/helpers/repo_helpers.rb' - 'spec/support/helpers/stub_object_storage.rb' -# Offense count: 54 +# Offense count: 2164 +# Cop supports --auto-correct. +# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. +# SupportedHashRocketStyles: key, separator, table +# SupportedColonStyles: key, separator, table +# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit +Layout/HashAlignment: + Enabled: false + +# Offense count: 9396 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 1313 + +# Offense count: 94 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: aligned, indented Layout/MultilineOperationIndentation: Enabled: false -# Offense count: 10 +# Offense count: 9 # Cop supports --auto-correct. Layout/RescueEnsureAlignment: Exclude: @@ -107,21 +113,33 @@ Layout/RescueEnsureAlignment: - 'app/models/project.rb' - 'app/services/prometheus/proxy_service.rb' - 'app/workers/delete_stored_files_worker.rb' - - 'app/workers/reactive_caching_worker.rb' - 'config/initializers/1_settings.rb' - 'config/initializers/trusted_proxies.rb' - 'lib/gitlab/background_migration/archive_legacy_traces.rb' - 'lib/gitlab/highlight.rb' - 'lib/tasks/gitlab/lfs/migrate.rake' -# Offense count: 522 +# Offense count: 36 +# Cop supports --auto-correct. +Layout/SpaceAroundMethodCallOperator: + Enabled: false + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment. +Layout/SpaceBeforeFirstArg: + Exclude: + - 'spec/requests/api/runner_spec.rb' + - 'spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb' + +# Offense count: 642 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: require_no_space, require_space Layout/SpaceInLambdaLiteral: Enabled: false -# Offense count: 796 +# Offense count: 926 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space @@ -129,7 +147,7 @@ Layout/SpaceInLambdaLiteral: Layout/SpaceInsideBlockBraces: Enabled: false -# Offense count: 315 +# Offense count: 401 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: space, no_space @@ -153,12 +171,47 @@ Lint/DuplicateMethods: - 'lib/gitlab/git/tree.rb' - 'lib/gitlab/git/wiki_page.rb' -# Offense count: 122 +# Offense count: 157 # Configuration parameters: MaximumRangeSize. Lint/MissingCopEnableDirective: Enabled: false -# Offense count: 6 +# Offense count: 11 +# Cop supports --auto-correct. +Lint/NonDeterministicRequireOrder: + Exclude: + - 'ee/spec/spec_helper.rb' + - 'qa/spec/spec_helper.rb' + - 'spec/spec_helper.rb' + +# Offense count: 3 +# Configuration parameters: AllowedImplicitNamespaces. +# AllowedImplicitNamespaces: Gem +Lint/RaiseException: + Exclude: + - 'db/migrate/20190402150158_backport_enterprise_schema.rb' + - 'ee/spec/requests/api/helpers_spec.rb' + - 'spec/requests/api/helpers_spec.rb' + +# Offense count: 27 +# Cop supports --auto-correct. +Lint/RedundantCopDisableDirective: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Lint/SendWithMixinArgument: + Exclude: + - 'config/initializers/trusted_proxies.rb' + +# Offense count: 3 +Lint/StructNewOverride: + Exclude: + - 'app/presenters/sentry_error_presenter.rb' + - 'app/serializers/environment_serializer.rb' + - 'lib/gitlab/ci/pipeline/duration.rb' + +# Offense count: 7 Lint/UriEscapeUnescape: Exclude: - 'app/controllers/application_controller.rb' @@ -166,14 +219,20 @@ Lint/UriEscapeUnescape: - 'spec/lib/google_api/auth_spec.rb' - 'spec/requests/api/files_spec.rb' -# Offense count: 165 +# Offense count: 3 # Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. -# URISchemes: http, https -Metrics/LineLength: - Max: 176 +Lint/UriRegexp: + Exclude: + - 'app/models/concerns/mentionable/reference_regexes.rb' + - 'app/services/projects/download_service.rb' + - 'lib/gitlab/ci/pipeline/chain/config/content/remote.rb' -# Offense count: 143 +# Offense count: 65 +# Cop supports --auto-correct. +Migration/DepartmentName: + Enabled: false + +# Offense count: 156 # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS Naming/FileName: @@ -190,43 +249,78 @@ Naming/HeredocDelimiterCase: - 'spec/support/helpers/repo_helpers.rb' - 'spec/support/helpers/seed_repo.rb' -# Offense count: 211 -# Configuration parameters: Blacklist. -# Blacklist: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$)) +# Offense count: 239 +# Configuration parameters: ForbiddenDelimiters. +# ForbiddenDelimiters: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$)) Naming/HeredocDelimiterNaming: Enabled: false -# Offense count: 139 +# Offense count: 5 +# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. +# AllowedNames: io, id, to, by, on, in, at, ip, db, os, pp +Naming/MethodParameterName: + Exclude: + - 'lib/gitlab/diff/inline_diff.rb' + - 'spec/support/helpers/key_generator_helper.rb' + +# Offense count: 162 # Cop supports --auto-correct. # Configuration parameters: PreferredName. Naming/RescuedExceptionsVariableName: Enabled: false -# Offense count: 9913 +# Offense count: 20 +# Cop supports --auto-correct. +Performance/Count: + Exclude: + - 'app/helpers/groups_helper.rb' + - 'app/services/merge_requests/add_context_service.rb' + - 'ee/lib/gitlab/geo/fdw.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' + - 'spec/lib/gitlab/conflict/file_spec.rb' + - 'spec/lib/gitlab/git/tree_spec.rb' + - 'spec/models/ci/build_spec.rb' + - 'spec/support/matchers/exceed_query_limit.rb' + +# Offense count: 25 +# Cop supports --auto-correct. +Performance/Detect: + Exclude: + - '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/import_export/project/tree_restorer_spec.rb' + - 'spec/models/event_spec.rb' + - 'spec/requests/api/jobs_spec.rb' + +# Offense count: 11832 # Configuration parameters: Prefixes. # Prefixes: when, with, without RSpec/ContextWording: Enabled: false -# Offense count: 879 +# Offense count: 1121 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: method_call, block RSpec/ExpectChange: Enabled: false -# Offense count: 660 +# Offense count: 751 RSpec/ExpectInHook: Enabled: false -# Offense count: 10 +# Offense count: 9 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: it_behaves_like, it_should_behave_like RSpec/ItBehavesLike: Exclude: - 'spec/lib/gitlab/git/commit_spec.rb' - - 'spec/lib/gitlab/git/repository_spec.rb' - 'spec/services/notification_service_spec.rb' # Offense count: 68 @@ -244,30 +338,28 @@ RSpec/LetBeforeExamples: - 'spec/rubocop/cop/migration/update_column_in_batches_spec.rb' - 'spec/serializers/pipeline_details_entity_spec.rb' -# Offense count: 2018 +# Offense count: 2188 # Cop supports --auto-correct. # Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers. # SupportedStyles: inflected, explicit RSpec/PredicateMatcher: Enabled: false -# Offense count: 584 +# Offense count: 635 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: and_return, block RSpec/ReturnFromStub: Enabled: false -# Offense count: 380 +# Offense count: 518 RSpec/ScatteredLet: Enabled: false -# Offense count: 8 +# Offense count: 4 RSpec/ScatteredSetup: Exclude: - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/requests/api/jobs_spec.rb' - - 'spec/services/projects/create_service_spec.rb' # Offense count: 10 # Cop supports --auto-correct. @@ -284,67 +376,92 @@ Rails/ApplicationController: - 'spec/controllers/concerns/continue_params_spec.rb' - 'spec/lib/marginalia_spec.rb' -# Offense count: 8 +# Offense count: 3 # Cop supports --auto-correct. Rails/BelongsTo: Exclude: - 'app/models/deployment.rb' - 'app/models/environment.rb' - - 'ee/app/models/prometheus_alert.rb' - - 'ee/app/models/prometheus_alert_event.rb' -# Offense count: 151 +# Offense count: 71 +# Configuration parameters: Database, Include. +# SupportedDatabases: mysql, postgresql +# Include: db/migrate/*.rb +Rails/BulkChangeTable: + Enabled: false + +# Offense count: 208 # Configuration parameters: Include. # Include: db/migrate/*.rb Rails/CreateTableWithTimestamps: Enabled: false -# Offense count: 266 +# Offense count: 346 # Configuration parameters: EnforcedStyle. # SupportedStyles: slashes, arguments Rails/FilePath: Enabled: false -# Offense count: 211 +# Offense count: 264 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasManyOrHasOneDependent: Enabled: false -# Offense count: 431 +# Offense count: 467 # Configuration parameters: Include. # Include: app/helpers/**/*.rb Rails/HelperInstanceVariable: Enabled: false -# Offense count: 103 +# Offense count: 15 +# Cop supports --auto-correct. +Rails/IndexBy: + Exclude: + - 'app/models/ci/pipeline.rb' + - 'app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb' + - 'ee/app/services/projects/update_mirror_service.rb' + - 'ee/app/services/security/store_report_service.rb' + - 'ee/lib/ee/gitlab/auth/ldap/sync/group.rb' + - 'ee/lib/ee/gitlab/background_migration/backfill_version_data_from_gitaly.rb' + - 'ee/lib/gitlab/analytics/type_of_work/tasks_by_type.rb' + - 'ee/lib/gitlab/elastic/document_reference.rb' + - 'ee/lib/gitlab/group_plans_preloader.rb' + - 'lib/gitlab/database/count/reltuples_count_strategy.rb' + - 'lib/gitlab/language_detection.rb' + +# Offense count: 36 +# Cop supports --auto-correct. +Rails/IndexWith: + Enabled: false + +# Offense count: 105 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/InverseOf: Enabled: false -# Offense count: 51 +# Offense count: 55 # Configuration parameters: Include. # Include: app/controllers/**/*.rb Rails/LexicallyScopedActionFilter: Enabled: false -# Offense count: 4 +# Offense count: 3 # Cop supports --auto-correct. Rails/LinkToBlank: Exclude: - 'app/helpers/projects_helper.rb' - 'app/helpers/wiki_helper.rb' - 'ee/app/helpers/ee/user_callouts_helper.rb' - - 'ee/app/helpers/license_helper.rb' -# Offense count: 35 +# Offense count: 34 # Configuration parameters: Include. # Include: **/Rakefile, **/*.rake Rails/RakeEnvironment: Enabled: false -# Offense count: 868 +# Offense count: 926 # Configuration parameters: Blacklist, Whitelist. # Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters Rails/SkipsModelValidations: @@ -360,13 +477,18 @@ Security/YAMLLoad: - 'spec/initializers/secret_token_spec.rb' - 'spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb' -# Offense count: 34 -# Configuration parameters: EnforcedStyle. +# Offense count: 10 +# Configuration parameters: EnforcedStyle, AllowModifiersOnSymbols. # SupportedStyles: inline, group Style/AccessModifierDeclarations: - Enabled: false + Exclude: + - 'app/helpers/issues_helper.rb' + - 'app/helpers/lazy_image_tag_helper.rb' + - 'lib/gitlab/cache/request_cache.rb' + - 'lib/gitlab/request_profiler.rb' + - 'spec/support/forgery_protection.rb' -# Offense count: 127 +# Offense count: 148 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: percent_q, bare_percent @@ -379,7 +501,7 @@ Style/CommentedKeyword: - 'lib/tasks/gitlab/backup.rake' - 'spec/tasks/gitlab/backup_rake_spec.rb' -# Offense count: 6 +# Offense count: 5 # Cop supports --auto-correct. Style/EachWithObject: Exclude: @@ -388,9 +510,8 @@ Style/EachWithObject: - 'lib/gitlab/hook_data/issuable_builder.rb' - 'lib/gitlab/i18n/po_linter.rb' - 'lib/gitlab/import_export/members_mapper.rb' - - 'lib/gitlab/import_export/relation_factory.rb' -# Offense count: 41 +# Offense count: 46 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: empty, nil, both @@ -404,7 +525,7 @@ Style/EmptyLambdaParameter: - 'app/models/ci/build.rb' - 'app/models/ci/runner.rb' -# Offense count: 8 +# Offense count: 7 # Cop supports --auto-correct. Style/EmptyLiteral: Exclude: @@ -414,38 +535,66 @@ Style/EmptyLiteral: - 'spec/helpers/merge_requests_helper_spec.rb' - 'spec/lib/gitlab/workhorse_spec.rb' - 'spec/requests/api/jobs_spec.rb' - - 'spec/support/shared_examples/chat_slash_commands_shared_examples.rb' -# Offense count: 148 +# Offense count: 170 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: compact, expanded Style/EmptyMethod: Enabled: false -# Offense count: 346 +# Offense count: 431 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: format, sprintf, percent Style/FormatString: Enabled: false -# Offense count: 692 +# Offense count: 769 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false -# Offense count: 27 +# Offense count: 47 +# Cop supports --auto-correct. +Style/HashEachMethods: + Enabled: false + +# Offense count: 6 +# Cop supports --auto-correct. +Style/HashTransformKeys: + Exclude: + - 'ee/app/models/vulnerabilities/occurrence.rb' + - 'ee/spec/lib/gitlab/ci/templates/dependency_scanning_gitlab_ci_yaml_spec.rb' + - 'lib/banzai/filter/commit_trailers_filter.rb' + - 'lib/gitlab/analytics/cycle_analytics/stage_events.rb' + +# Offense count: 10 +# Cop supports --auto-correct. +Style/HashTransformValues: + Exclude: + - 'app/validators/addressable_url_validator.rb' + - 'config/initializers/action_dispatch_journey_formatter.rb' + - 'ee/app/helpers/compliance_management/compliance_framework/project_settings_helper.rb' + - 'ee/app/services/packages/nuget/metadata_extraction_service.rb' + - 'lib/gitlab/config/entry/configurable.rb' + - 'lib/gitlab/config/entry/node.rb' + - 'lib/gitlab/discussions_diff/file_collection.rb' + - 'lib/gitlab/error_tracking.rb' + - 'lib/rspec_flaky/flaky_examples_collection.rb' + - 'spec/lib/gitlab/database_importers/common_metrics/prometheus_metric_spec.rb' + +# Offense count: 31 # Configuration parameters: AllowIfModifier. Style/IfInsideElse: Enabled: false -# Offense count: 1474 +# Offense count: 1313 # Cop supports --auto-correct. Style/IfUnlessModifier: Enabled: false -# Offense count: 314 +# Offense count: 377 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: line_count_dependent, lambda, literal @@ -460,51 +609,49 @@ Style/MethodMissingSuper: Style/MissingRespondToMissing: Enabled: false -# Offense count: 6 +# Offense count: 5 Style/MixinUsage: Exclude: - 'spec/factories/ci/builds.rb' - 'spec/factories/ci/job_artifacts.rb' - 'spec/factories/lfs_objects.rb' - 'spec/factories/notes.rb' - - 'spec/lib/gitlab/import_export/project_tree_restorer_spec.rb' - 'spec/lib/gitlab/import_export/version_checker_spec.rb' -# Offense count: 4 +# Offense count: 2 # Cop supports --auto-correct. Style/MultilineIfModifier: Exclude: - - 'app/helpers/snippets_helper.rb' - 'app/services/ci/process_pipeline_service.rb' - 'lib/api/commit_statuses.rb' -# Offense count: 25 +# Offense count: 29 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength. # SupportedStyles: skip_modifier_ifs, always Style/Next: Enabled: false -# Offense count: 71 +# Offense count: 89 # Cop supports --auto-correct. # Configuration parameters: EnforcedOctalStyle. # SupportedOctalStyles: zero_with_o, zero_only Style/NumericLiteralPrefix: Enabled: false -# Offense count: 234 +# Offense count: 255 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. # SupportedStyles: predicate, comparison Style/NumericPredicate: Enabled: false -# Offense count: 106 +# Offense count: 117 # Cop supports --auto-correct. Style/ParallelAssignment: Enabled: false -# Offense count: 1692 +# Offense count: 2035 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: @@ -526,51 +673,60 @@ Style/PerlBackrefs: - 'lib/gitlab/search_results.rb' - 'lib/gitlab/sherlock/query.rb' -# Offense count: 165 +# Offense count: 200 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: compact, exploded Style/RaiseArgs: Enabled: false -# Offense count: 221 +# Offense count: 246 # Cop supports --auto-correct. Style/RedundantFreeze: Enabled: false -# Offense count: 15 +# Offense count: 123 +# Cop supports --auto-correct. +Style/RedundantInterpolation: + Enabled: false + +# Offense count: 6 +# Cop supports --auto-correct. +Style/RedundantParentheses: + Exclude: + - 'ee/app/models/ee/merge_request.rb' + +# Offense count: 33 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/concerns/issuable_actions.rb' - - 'app/controllers/groups/application_controller.rb' - - 'app/controllers/omniauth_callbacks_controller.rb' - - 'app/controllers/profiles/keys_controller.rb' - - 'app/controllers/projects/application_controller.rb' - - 'app/services/access_token_validation_service.rb' - - 'lib/gitlab/utils.rb' - - 'lib/google_api/auth.rb' + Enabled: false -# Offense count: 739 +# Offense count: 801 # Cop supports --auto-correct. Style/RedundantSelf: Enabled: false -# Offense count: 80 +# Offense count: 2 +# Cop supports --auto-correct. +Style/RedundantSort: + Exclude: + - 'ee/app/presenters/packages/nuget/search_results_presenter.rb' + - 'ee/spec/presenters/packages/nuget/search_results_presenter_spec.rb' + +# Offense count: 120 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, AllowInnerSlashes. # SupportedStyles: slashes, percent_r, mixed Style/RegexpLiteral: Enabled: false -# Offense count: 42 +# Offense count: 46 # Cop supports --auto-correct. Style/RescueModifier: Enabled: false -# Offense count: 237 +# Offense count: 286 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: implicit, explicit @@ -592,28 +748,544 @@ Style/SingleLineMethods: Exclude: - 'lib/gitlab/ci/ansi2html.rb' -# Offense count: 94 +# Offense count: 102 # Cop supports --auto-correct. # Configuration parameters: . # SupportedStyles: use_perl_names, use_english_names Style/SpecialGlobalVars: EnforcedStyle: use_perl_names -# Offense count: 75 +# Offense count: 93 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: single_quotes, double_quotes Style/StringLiteralsInInterpolation: Enabled: false -# Offense count: 216 +# Offense count: 233 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. # IgnoredMethods: respond_to, define_method Style/SymbolProc: Enabled: false -# Offense count: 99 +# Offense count: 1478 # Cop supports --auto-correct. -Style/UnneededInterpolation: - Enabled: false +# Configuration parameters: AllowImplicitReturn, AllowedReceivers. +Rails/SaveBang: + Exclude: + - 'ee/spec/controllers/groups/epic_issues_controller_spec.rb' + - 'ee/spec/controllers/groups/epic_links_controller_spec.rb' + - 'ee/spec/controllers/groups/epics_controller_spec.rb' + - 'ee/spec/controllers/groups/roadmap_controller_spec.rb' + - 'ee/spec/controllers/projects/environments_controller_spec.rb' + - 'ee/spec/controllers/projects/issues_controller_spec.rb' + - 'ee/spec/controllers/projects/merge_requests/creations_controller_spec.rb' + - 'ee/spec/controllers/projects/merge_requests_controller_spec.rb' + - 'ee/spec/controllers/projects/service_desk_controller_spec.rb' + - 'ee/spec/controllers/projects/subscriptions_controller_spec.rb' + - 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb' + - 'ee/spec/controllers/subscriptions_controller_spec.rb' + - 'ee/spec/factories/merge_requests.rb' + - 'ee/spec/features/admin/geo/admin_geo_nodes_spec.rb' + - 'ee/spec/features/boards/scoped_issue_board_spec.rb' + - 'ee/spec/features/ci_shared_runner_warnings_spec.rb' + - 'ee/spec/features/dashboards/operations_spec.rb' + - 'ee/spec/features/issues/gfm_autocomplete_ee_spec.rb' + - 'ee/spec/features/merge_request/user_approves_spec.rb' + - 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb' + - 'ee/spec/features/projects/members/invite_group_and_members_spec.rb' + - 'ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb' + - 'ee/spec/features/projects/new_project_spec.rb' + - 'ee/spec/features/projects/settings/user_manages_approval_settings_spec.rb' + - 'ee/spec/features/projects/settings/user_manages_members_spec.rb' + - 'ee/spec/features/search/elastic/global_search_spec.rb' + - 'ee/spec/finders/epics_finder_spec.rb' + - 'ee/spec/frontend/fixtures/analytics.rb' + - 'ee/spec/helpers/application_helper_spec.rb' + - 'ee/spec/helpers/ee/issues_helper_spec.rb' + - 'ee/spec/initializers/fog_google_https_private_urls_spec.rb' + - 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb' + - 'ee/spec/lib/ee/gitlab/auth/ldap/sync/group_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/move_epic_issues_after_epics_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_merge_requests_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_projects_spec.rb' + - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb' + - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb' + - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb' + - 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb' + - 'ee/spec/lib/gitlab/auth/saml/user_spec.rb' + - 'ee/spec/lib/gitlab/elastic/search_results_spec.rb' + - 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb' + - 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb' + - 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb' + - 'ee/spec/lib/gitlab/geo_spec.rb' + - 'ee/spec/lib/gitlab/git_access_spec.rb' + - 'ee/spec/mailers/notify_spec.rb' + - 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb' + - 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb' + - 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb' + - 'ee/spec/models/application_setting_spec.rb' + - 'ee/spec/models/approval_merge_request_rule_spec.rb' + - 'ee/spec/models/approval_state_spec.rb' + - 'ee/spec/models/burndown_spec.rb' + - 'ee/spec/models/ci/build_spec.rb' + - 'ee/spec/models/ci/pipeline_spec.rb' + - 'ee/spec/models/ci/subscriptions/project_spec.rb' + - 'ee/spec/models/concerns/deprecated_approvals_before_merge_spec.rb' + - 'ee/spec/models/concerns/elastic/note_spec.rb' + - 'ee/spec/models/ee/protected_branch_spec.rb' + - 'ee/spec/models/ee/protected_ref_access_spec.rb' + - 'ee/spec/models/ee/protected_ref_spec.rb' + - 'ee/spec/models/epic_spec.rb' + - 'ee/spec/models/geo/project_registry_spec.rb' + - 'ee/spec/models/geo_node_spec.rb' + - 'ee/spec/models/geo_node_status_spec.rb' + - 'ee/spec/models/group_spec.rb' + - 'ee/spec/models/issue_spec.rb' + - 'ee/spec/models/label_note_spec.rb' + - 'ee/spec/models/license_spec.rb' + - 'ee/spec/models/merge_request_spec.rb' + - 'ee/spec/models/operations/feature_flag_scope_spec.rb' + - 'ee/spec/models/operations/feature_flag_spec.rb' + - 'ee/spec/models/operations/feature_flags/strategy_spec.rb' + - 'ee/spec/models/operations/feature_flags/user_list_spec.rb' + - 'ee/spec/models/project_services/github_service_spec.rb' + - 'ee/spec/models/project_services/jenkins_service_spec.rb' + - 'ee/spec/models/project_spec.rb' + - 'ee/spec/models/scim_identity_spec.rb' + - 'ee/spec/models/scim_oauth_access_token_spec.rb' + - 'ee/spec/models/user_preference_spec.rb' + - 'ee/spec/models/user_spec.rb' + - 'ee/spec/models/visible_approvable_spec.rb' + - 'ee/spec/models/vulnerabilities/feedback_spec.rb' + - 'ee/spec/models/vulnerabilities/issue_link_spec.rb' + - 'ee/spec/policies/protected_branch_policy_spec.rb' + - 'ee/spec/presenters/audit_event_presenter_spec.rb' + - 'ee/spec/presenters/epic_presenter_spec.rb' + - 'ee/spec/presenters/packages/conan/package_presenter_spec.rb' + - 'ee/spec/requests/api/boards_spec.rb' + - 'ee/spec/requests/api/epic_issues_spec.rb' + - 'ee/spec/requests/api/epic_links_spec.rb' + - 'ee/spec/requests/api/epics_spec.rb' + - 'ee/spec/requests/api/geo_nodes_spec.rb' + - 'ee/spec/requests/api/geo_spec.rb' + - 'ee/spec/requests/api/graphql/group/epics_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb' + - 'ee/spec/requests/api/groups_spec.rb' + - 'ee/spec/requests/api/issues_spec.rb' + - 'ee/spec/requests/api/ldap_group_links_spec.rb' + - 'ee/spec/requests/api/maven_packages_spec.rb' + - 'ee/spec/requests/api/merge_request_approval_rules_spec.rb' + - 'ee/spec/requests/api/merge_request_approvals_spec.rb' + - 'ee/spec/requests/api/merge_requests_spec.rb' + - 'ee/spec/requests/api/project_approvals_spec.rb' + - 'ee/spec/requests/api/projects_spec.rb' + - 'ee/spec/requests/api/protected_branches_spec.rb' + - 'ee/spec/requests/api/scim_spec.rb' + - 'ee/spec/requests/api/todos_spec.rb' + - 'ee/spec/services/approval_rules/finalize_service_spec.rb' + - 'ee/spec/services/ci/register_job_service_spec.rb' + - 'ee/spec/services/ee/boards/issues/create_service_spec.rb' + - 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb' + - 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb' + - 'ee/spec/services/ee/issues/update_service_spec.rb' + - 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb' + - 'ee/spec/services/ee/merge_requests/update_service_spec.rb' + - 'ee/spec/services/ee/notes/quick_actions_service_spec.rb' + - 'ee/spec/services/ee/notification_service_spec.rb' + - 'ee/spec/services/ee/resource_events/change_weight_service_spec.rb' + - 'ee/spec/services/elastic/index_record_service_spec.rb' + - 'ee/spec/services/epic_links/create_service_spec.rb' + - 'ee/spec/services/epics/issue_promote_service_spec.rb' + - 'ee/spec/services/epics/tree_reorder_service_spec.rb' + - 'ee/spec/services/epics/update_dates_service_spec.rb' + - 'ee/spec/services/epics/update_service_spec.rb' + - 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb' + - 'ee/spec/services/geo/metrics_update_service_spec.rb' + - 'ee/spec/services/geo/registry_consistency_service_spec.rb' + - 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb' + - 'ee/spec/services/groups/autocomplete_service_spec.rb' + - 'ee/spec/services/ldap_group_reset_service_spec.rb' + - 'ee/spec/services/lfs/unlock_file_service_spec.rb' + - 'ee/spec/services/merge_requests/approval_service_spec.rb' + - 'ee/spec/services/merge_requests/remove_approval_service_spec.rb' + - 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb' + - 'ee/spec/services/projects/after_rename_service_spec.rb' + - 'ee/spec/services/projects/update_service_spec.rb' + - 'ee/spec/services/quick_actions/interpret_service_spec.rb' + - 'ee/spec/services/slash_commands/global_slack_handler_spec.rb' + - 'ee/spec/services/start_pull_mirroring_service_spec.rb' + - 'ee/spec/services/status_page/trigger_publish_service_spec.rb' + - 'ee/spec/services/todo_service_spec.rb' + - 'ee/spec/services/update_build_minutes_service_spec.rb' + - 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb' + - 'ee/spec/support/shared_examples/models/concerns/replicator_shared_examples.rb' + - 'ee/spec/support/shared_examples/models/member_shared_examples.rb' + - 'ee/spec/support/shared_examples/models/mentionable_shared_examples.rb' + - 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb' + - 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb' + - 'ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb' + - 'ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb' + - 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb' + - 'ee/spec/workers/create_github_webhook_worker_spec.rb' + - 'ee/spec/workers/elastic_indexer_worker_spec.rb' + - 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb' + - 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb' + - 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb' + - 'ee/spec/workers/repository_import_worker_spec.rb' + - 'ee/spec/workers/update_all_mirrors_worker_spec.rb' + - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb' + - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb' + - 'spec/controllers/abuse_reports_controller_spec.rb' + - 'spec/controllers/admin/impersonations_controller_spec.rb' + - 'spec/controllers/admin/runners_controller_spec.rb' + - 'spec/controllers/boards/issues_controller_spec.rb' + - 'spec/controllers/groups/runners_controller_spec.rb' + - 'spec/controllers/oauth/authorizations_controller_spec.rb' + - 'spec/controllers/omniauth_callbacks_controller_spec.rb' + - 'spec/controllers/profiles/emails_controller_spec.rb' + - 'spec/controllers/profiles/notifications_controller_spec.rb' + - 'spec/controllers/projects/artifacts_controller_spec.rb' + - 'spec/controllers/projects/cycle_analytics_controller_spec.rb' + - 'spec/controllers/projects/issues_controller_spec.rb' + - 'spec/controllers/projects/labels_controller_spec.rb' + - 'spec/controllers/projects/merge_requests_controller_spec.rb' + - 'spec/controllers/projects/milestones_controller_spec.rb' + - 'spec/controllers/projects/notes_controller_spec.rb' + - 'spec/controllers/projects/pipelines_controller_spec.rb' + - 'spec/controllers/projects/runners_controller_spec.rb' + - 'spec/controllers/projects_controller_spec.rb' + - 'spec/factories/ci/pipelines.rb' + - 'spec/factories/design_management/designs.rb' + - 'spec/factories/design_management/versions.rb' + - 'spec/factories/labels.rb' + - 'spec/factories/projects.rb' + - 'spec/features/admin/admin_mode/login_spec.rb' + - 'spec/features/admin/admin_runners_spec.rb' + - 'spec/features/admin/admin_users_impersonation_tokens_spec.rb' + - 'spec/features/admin/admin_users_spec.rb' + - 'spec/features/boards/sidebar_spec.rb' + - 'spec/features/calendar_spec.rb' + - 'spec/features/commits_spec.rb' + - 'spec/features/dashboard/datetime_on_tooltips_spec.rb' + - 'spec/features/dashboard/issuables_counter_spec.rb' + - 'spec/features/dashboard/project_member_activity_index_spec.rb' + - 'spec/features/dashboard/projects_spec.rb' + - 'spec/features/error_tracking/user_sees_error_index_spec.rb' + - 'spec/features/groups/members/request_access_spec.rb' + - 'spec/features/issues/bulk_assignment_labels_spec.rb' + - 'spec/features/issues/gfm_autocomplete_spec.rb' + - 'spec/features/issues/issue_sidebar_spec.rb' + - 'spec/features/issues/note_polling_spec.rb' + - 'spec/features/issues/user_creates_branch_and_merge_request_spec.rb' + - 'spec/features/issues/user_creates_confidential_merge_request_spec.rb' + - 'spec/features/issues/user_edits_issue_spec.rb' + - 'spec/features/issues/user_filters_issues_spec.rb' + - 'spec/features/issues/user_sees_live_update_spec.rb' + - 'spec/features/issues/user_sorts_issues_spec.rb' + - 'spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb' + - 'spec/features/merge_request/user_posts_diff_notes_spec.rb' + - 'spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb' + - 'spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb' + - 'spec/features/merge_request/user_sees_merge_widget_spec.rb' + - 'spec/features/merge_requests/user_mass_updates_spec.rb' + - 'spec/features/profiles/emails_spec.rb' + - 'spec/features/profiles/password_spec.rb' + - 'spec/features/profiles/personal_access_tokens_spec.rb' + - 'spec/features/projects/features_visibility_spec.rb' + - 'spec/features/projects/jobs_spec.rb' + - 'spec/features/projects/members/user_requests_access_spec.rb' + - 'spec/features/projects/pages_lets_encrypt_spec.rb' + - 'spec/features/projects/pages_spec.rb' + - 'spec/features/projects/remote_mirror_spec.rb' + - 'spec/features/projects/services/user_activates_slack_notifications_spec.rb' + - 'spec/features/projects/settings/access_tokens_spec.rb' + - 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb' + - 'spec/features/projects/user_sees_sidebar_spec.rb' + - 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb' + - 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb' + - 'spec/features/security/project/private_access_spec.rb' + - 'spec/features/users/login_spec.rb' + - 'spec/features/users/show_spec.rb' + - 'spec/finders/autocomplete/move_to_project_finder_spec.rb' + - 'spec/finders/group_descendants_finder_spec.rb' + - 'spec/finders/issues_finder_spec.rb' + - 'spec/finders/merge_requests_finder_spec.rb' + - 'spec/finders/projects_finder_spec.rb' + - 'spec/finders/uploader_finder_spec.rb' + - 'spec/frontend/fixtures/issues.rb' + - 'spec/frontend/fixtures/merge_requests.rb' + - 'spec/graphql/mutations/merge_requests/set_locked_spec.rb' + - 'spec/graphql/mutations/merge_requests/set_wip_spec.rb' + - 'spec/graphql/resolvers/boards_resolver_spec.rb' + - 'spec/helpers/appearances_helper_spec.rb' + - 'spec/helpers/profiles_helper_spec.rb' + - 'spec/helpers/projects/alert_management_helper_spec.rb' + - 'spec/helpers/projects_helper_spec.rb' + - 'spec/helpers/visibility_level_helper_spec.rb' + - 'spec/initializers/active_record_locking_spec.rb' + - 'spec/initializers/fog_google_https_private_urls_spec.rb' + - 'spec/lib/after_commit_queue_spec.rb' + - 'spec/lib/backup/manager_spec.rb' + - 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb' + - 'spec/lib/gitlab/auth/ldap/user_spec.rb' + - 'spec/lib/gitlab/auth/o_auth/user_spec.rb' + - 'spec/lib/gitlab/auth/saml/user_spec.rb' + - 'spec/lib/gitlab/auth_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb' + - 'spec/lib/gitlab/background_migration/digest_column_spec.rb' + - 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb' + - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb' + - 'spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb' + - 'spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb' + - 'spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb' + - 'spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb' + - 'spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb' + - 'spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb' + - 'spec/lib/gitlab/background_migration/populate_merge_request_assignees_table_spec.rb' + - 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb' + - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb' + - 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb' + - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb' + - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb' + - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb' + - 'spec/lib/gitlab/ci/ansi2json/style_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/partitioning_migration_helpers/table_management_helpers_spec.rb' + - 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb' + - 'spec/lib/gitlab/git/remote_mirror_spec.rb' + - 'spec/lib/gitlab/git_access_spec.rb' + - 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb' + - 'spec/lib/gitlab/import_export/avatar_saver_spec.rb' + - 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb' + - 'spec/lib/gitlab/import_export/fork_spec.rb' + - 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb' + - 'spec/lib/gitlab/import_export/importer_spec.rb' + - 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/lfs_saver_spec.rb' + - 'spec/lib/gitlab/import_export/members_mapper_spec.rb' + - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb' + - 'spec/lib/gitlab/import_export/repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/saver_spec.rb' + - 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb' + - 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb' + - 'spec/lib/gitlab/import_export/uploads_manager_spec.rb' + - 'spec/lib/gitlab/import_export/uploads_saver_spec.rb' + - 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb' + - 'spec/lib/gitlab/lets_encrypt/client_spec.rb' + - 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb' + - 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb' + - 'spec/lib/gitlab/shard_health_cache_spec.rb' + - 'spec/mailers/notify_spec.rb' + - 'spec/migrations/20200122123016_backfill_project_settings_spec.rb' + - 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb' + - 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb' + - 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb' + - 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb' + - 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb' + - 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb' + - 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb' + - 'spec/migrations/fill_file_store_lfs_objects_spec.rb' + - 'spec/migrations/fill_store_uploads_spec.rb' + - 'spec/migrations/fix_null_type_labels_spec.rb' + - 'spec/migrations/fix_pool_repository_source_project_id_spec.rb' + - 'spec/migrations/fix_wrong_pages_access_level_spec.rb' + - 'spec/migrations/insert_project_hooks_plan_limits_spec.rb' + - 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb' + - 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb' + - 'spec/models/appearance_spec.rb' + - 'spec/models/application_setting_spec.rb' + - 'spec/models/ci/build_spec.rb' + - 'spec/models/ci/instance_variable_spec.rb' + - 'spec/models/ci/pipeline_spec.rb' + - 'spec/models/ci/runner_spec.rb' + - 'spec/models/clusters/applications/helm_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/featurable_spec.rb' + - 'spec/models/concerns/issuable_spec.rb' + - 'spec/models/concerns/mentionable_spec.rb' + - 'spec/models/concerns/milestoneable_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/cycle_analytics/issue_spec.rb' + - 'spec/models/cycle_analytics/plan_spec.rb' + - 'spec/models/deploy_keys_project_spec.rb' + - 'spec/models/deploy_token_spec.rb' + - 'spec/models/deployment_spec.rb' + - 'spec/models/design_management/version_spec.rb' + - 'spec/models/diff_note_spec.rb' + - 'spec/models/email_spec.rb' + - 'spec/models/environment_spec.rb' + - 'spec/models/event_spec.rb' + - 'spec/models/fork_network_spec.rb' + - 'spec/models/generic_commit_status_spec.rb' + - 'spec/models/grafana_integration_spec.rb' + - 'spec/models/group_spec.rb' + - 'spec/models/hooks/system_hook_spec.rb' + - 'spec/models/hooks/web_hook_spec.rb' + - 'spec/models/identity_spec.rb' + - 'spec/models/issue_spec.rb' + - 'spec/models/key_spec.rb' + - 'spec/models/lfs_objects_project_spec.rb' + - 'spec/models/member_spec.rb' + - 'spec/models/members/group_member_spec.rb' + - 'spec/models/members/project_member_spec.rb' + - 'spec/models/merge_request_spec.rb' + - 'spec/models/milestone_spec.rb' + - 'spec/models/namespace_spec.rb' + - 'spec/models/note_spec.rb' + - 'spec/models/notification_setting_spec.rb' + - 'spec/models/pages_domain_spec.rb' + - 'spec/models/project_services/bamboo_service_spec.rb' + - 'spec/models/project_services/jira_service_spec.rb' + - 'spec/models/project_services/pipelines_email_service_spec.rb' + - 'spec/models/project_services/teamcity_service_spec.rb' + - 'spec/models/project_spec.rb' + - 'spec/models/project_team_spec.rb' + - 'spec/models/release_spec.rb' + - 'spec/models/remote_mirror_spec.rb' + - 'spec/models/resource_milestone_event_spec.rb' + - 'spec/models/route_spec.rb' + - 'spec/models/sentry_issue_spec.rb' + - 'spec/models/service_spec.rb' + - 'spec/models/snippet_spec.rb' + - 'spec/models/upload_spec.rb' + - 'spec/models/user_preference_spec.rb' + - 'spec/models/user_spec.rb' + - 'spec/models/wiki_page/meta_spec.rb' + - 'spec/models/wiki_page_spec.rb' + - 'spec/policies/ci/build_policy_spec.rb' + - 'spec/policies/ci/pipeline_policy_spec.rb' + - 'spec/policies/ci/pipeline_schedule_policy_spec.rb' + - 'spec/policies/merge_request_policy_spec.rb' + - 'spec/policies/project_policy_spec.rb' + - 'spec/requests/api/boards_spec.rb' + - 'spec/requests/api/deployments_spec.rb' + - 'spec/requests/api/environments_spec.rb' + - 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb' + - 'spec/requests/api/graphql/user_query_spec.rb' + - 'spec/requests/api/graphql_spec.rb' + - 'spec/requests/api/group_milestones_spec.rb' + - 'spec/requests/api/internal/base_spec.rb' + - 'spec/requests/api/issues/get_group_issues_spec.rb' + - 'spec/requests/api/jobs_spec.rb' + - 'spec/requests/api/labels_spec.rb' + - 'spec/requests/api/members_spec.rb' + - 'spec/requests/api/merge_request_diffs_spec.rb' + - 'spec/requests/api/merge_requests_spec.rb' + - 'spec/requests/api/pipeline_schedules_spec.rb' + - 'spec/requests/api/project_import_spec.rb' + - 'spec/requests/api/projects_spec.rb' + - 'spec/requests/api/runners_spec.rb' + - 'spec/requests/api/snippets_spec.rb' + - 'spec/requests/git_http_spec.rb' + - 'spec/requests/profiles/notifications_controller_spec.rb' + - 'spec/requests/projects/cycle_analytics_events_spec.rb' + - 'spec/serializers/environment_status_entity_spec.rb' + - 'spec/serializers/merge_request_poll_widget_entity_spec.rb' + - 'spec/serializers/merge_request_widget_entity_spec.rb' + - 'spec/services/ci/create_pipeline_service_spec.rb' + - 'spec/services/ci/register_job_service_spec.rb' + - 'spec/services/ci/retry_build_service_spec.rb' + - 'spec/services/deployments/after_create_service_spec.rb' + - 'spec/services/design_management/generate_image_versions_service_spec.rb' + - 'spec/services/draft_notes/destroy_service_spec.rb' + - 'spec/services/emails/confirm_service_spec.rb' + - 'spec/services/groups/destroy_service_spec.rb' + - 'spec/services/groups/import_export/import_service_spec.rb' + - 'spec/services/issuable/clone/attributes_rewriter_spec.rb' + - 'spec/services/issuable/common_system_notes_service_spec.rb' + - 'spec/services/issues/close_service_spec.rb' + - 'spec/services/issues/create_service_spec.rb' + - 'spec/services/issues/export_csv_service_spec.rb' + - 'spec/services/issues/reopen_service_spec.rb' + - 'spec/services/issues/update_service_spec.rb' + - 'spec/services/labels/promote_service_spec.rb' + - 'spec/services/members/destroy_service_spec.rb' + - 'spec/services/merge_requests/conflicts/list_service_spec.rb' + - 'spec/services/merge_requests/create_service_spec.rb' + - 'spec/services/merge_requests/merge_service_spec.rb' + - 'spec/services/merge_requests/post_merge_service_spec.rb' + - 'spec/services/merge_requests/refresh_service_spec.rb' + - 'spec/services/merge_requests/update_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/notification_recipients/build_service_spec.rb' + - 'spec/services/notification_service_spec.rb' + - 'spec/services/projects/after_rename_service_spec.rb' + - 'spec/services/projects/create_service_spec.rb' + - 'spec/services/projects/fork_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/system_hooks_service_spec.rb' + - 'spec/services/system_note_service_spec.rb' + - 'spec/services/system_notes/issuables_service_spec.rb' + - 'spec/services/todo_service_spec.rb' + - 'spec/services/todos/destroy/confidential_issue_service_spec.rb' + - 'spec/services/users/destroy_service_spec.rb' + - 'spec/services/users/repair_ldap_blocked_service_spec.rb' + - 'spec/support/helpers/cycle_analytics_helpers.rb' + - 'spec/support/helpers/jira_service_helper.rb' + - 'spec/support/helpers/login_helpers.rb' + - 'spec/support/helpers/notification_helpers.rb' + - 'spec/support/helpers/stub_action_cable_connection.rb' + - 'spec/support/helpers/stub_object_storage.rb' + - 'spec/support/migrations_helpers/cluster_helpers.rb' + - 'spec/support/migrations_helpers/track_untracked_uploads_helpers.rb' + - 'spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb' + - 'spec/support/shared_contexts/mailers/notify_shared_context.rb' + - 'spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb' + - 'spec/support/shared_examples/controllers/sessionless_auth_controller_shared_examples.rb' + - 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb' + - 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb' + - 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb' + - 'spec/support/shared_examples/models/member_shared_examples.rb' + - 'spec/support/shared_examples/models/members_notifications_shared_example.rb' + - 'spec/support/shared_examples/models/mentionable_shared_examples.rb' + - 'spec/support/shared_examples/models/relative_positioning_shared_examples.rb' + - 'spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb' + - 'spec/support/shared_examples/models/update_project_statistics_shared_examples.rb' + - 'spec/support/shared_examples/models/with_uploads_shared_examples.rb' + - 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb' + - 'spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/boards_shared_examples.rb' + - 'spec/support/shared_examples/services/common_system_notes_shared_examples.rb' + - 'spec/support/shared_examples/services/issuable_shared_examples.rb' + - 'spec/tasks/gitlab/web_hook_rake_spec.rb' + - 'spec/views/projects/imports/new.html.haml_spec.rb' + - 'spec/views/projects/merge_requests/show.html.haml_spec.rb' + - 'spec/views/shared/_label_row.html.haml_spec.rb' + - 'spec/workers/migrate_external_diffs_worker_spec.rb' + - 'spec/workers/namespaceless_project_destroy_worker_spec.rb' + - 'spec/workers/pages_domain_verification_worker_spec.rb' + - 'spec/workers/propagate_service_template_worker_spec.rb' + - 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb' + - 'spec/workers/repository_cleanup_worker_spec.rb' + - 'spec/workers/repository_import_worker_spec.rb' + - 'spec/workers/repository_update_remote_mirror_worker_spec.rb' diff --git a/.ruby-version b/.ruby-version index 57cf282ebb..338a5b5d8f 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.5 +2.6.6 diff --git a/CHANGELOG-EE.md b/CHANGELOG-EE.md index 93ea5184a7..1fe9715d33 100644 --- a/CHANGELOG-EE.md +++ b/CHANGELOG-EE.md @@ -1,8 +1,11 @@ Please view this file on the master branch, on stable branches it's out of date. -## 13.0.5 (2020-06-04) +## 13.0.6 (2020-06-10) + +### Security (1 change) + +- Do not set fallback mirror user. -- No changes. ## 13.0.4 (2020-06-03) @@ -12,10 +15,6 @@ Please view this file on the master branch, on stable branches it's out of date. - No changes. -## 13.0.2 (2020-05-28) - -- No changes. - ## 13.0.1 (2020-05-27) ### Security (3 changes) @@ -351,6 +350,33 @@ Please view this file on the master branch, on stable branches it's out of date. - Translate unauthenticated user string for Audit Event. !31856 (Sashi Kumar) +## 12.10.11 (2020-06-10) + +### Security (1 change) + +- Do not set fallback mirror user. + + +## 12.10.8 (2020-05-28) + +### Fixed (1 change) + +- Geo: Fix empty synchronisation status when nothing is synchronised. !30710 + + +## 12.10.7 (2020-05-27) + +### Security (3 changes) + +- Change the mirror user along with pull mirror settings. +- Allow only users with a verified email to be member of a group when the group has restricted membership based on email domain. +- Do not auto-confirm email in Trial registration. + + +## 12.10.6 (2020-05-15) + +- No changes. + ## 12.10.5 (2020-05-13) ### Fixed (1 change) @@ -421,6 +447,22 @@ Please view this file on the master branch, on stable branches it's out of date. - Add health status counts to usage data. !28964 +## 12.9.10 (2020-06-10) + +### Security (1 change) + +- Do not set fallback mirror user. + + +## 12.9.8 (2020-05-27) + +### Security (3 changes) + +- Change the mirror user along with pull mirror settings. +- Allow only users with a verified email to be member of a group when the group has restricted membership based on email domain. +- Do not auto-confirm email in Trial registration. + + ## 12.9.6 (2020-05-05) - No changes. diff --git a/CHANGELOG.md b/CHANGELOG.md index a10f9b9284..196f184f92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,24 +2,498 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 13.1.0 (2020-06-22) + +### Removed (4 changes, 2 of them are from the community) + +- Remove deprecated dashboard & group milestone pages. !13237 +- Removed UltraAuth integration for OmniAuth. !29330 (Kartikey Tanna) +- Remove all search autocomplete for groups/projects/other. !31187 +- Remove temporary datepicker position fix as it is no longer required. !31836 (Arun Kumar Mohan) + +### Fixed (154 changes, 57 of them are from the community) + +- Fix 'Active' checkbox text in Pipeline Schedule form to be a label. !27054 (Jonston Chan) +- Fix back button when switching MR tabs. !29862 (Lee Tickett) +- Remove ability to scroll Issue while in Design View. !29881 +- Fix merge request note label URLs. !30428 (Lee Tickett) +- Fix default path when creating project from group template. !30597 (Lee Tickett) +- Group authorization refresh to consider shared groups. !31204 +- Fix group transfer service to deny moving group to its subgroup. !31495 (Abhisek Datta) +- Fix issuable listings with any label filter. !31729 +- Move prepend to last in ee-app-services. !31838 (Rajendra Kadam) +- Fallback to lowest visibility level in snippet visibility radio. !31847 (Jacopo Beschi @jacopo-beschi) +- Add class stubs and fix leaky constant alert in query limit helper spec. !31949 (Rajendra Kadam) +- Remove usage of spam constants in spec. !31959 (Rajendra Kadam) +- Fix leaky constant issue in uninstall progress service check. !32036 (Rajendra Kadam) +- Fix leaky constant issue in commit entity spec. !32039 (Rajendra Kadam) +- Fix leaky constant issue in task completion status spec. !32043 (Rajendra Kadam) +- Fix leaky constant issue in admin mode migration spec. !32074 (Rajendra Kadam) +- Fix leaky constant issue in sidekiq middleware server metric spec. !32104 (Rajendra Kadam) +- Fix leaky constant issue in sidekiq middleware client metric spec. !32108 (Rajendra Kadam) +- Fix leaky constant issue in path regex spec. !32115 (Rajendra Kadam) +- Fix leaky constant issue importer and cache headers spec. !32122 (Rajendra Kadam) +- Fix leaky constant issue in relation factory spec. !32129 (Rajendra Kadam) +- Fix leaky constant issue in test coverage spec. !32134 (Rajendra Kadam) +- Prevent emails to user on expiry of impersonation token. !32140 +- Fix leaky constant issue in diff collection spec. !32163 (Rajendra Kadam) +- Fix leaky constant issue in migration helpers, with lock retries and ignored cols spec. !32170 (Rajendra Kadam) +- Fix leaky constant issue in factory spec. !32174 (Rajendra Kadam) +- Fix leaky constant issue in creds factory spec. !32176 (Rajendra Kadam) +- Use applogger in project import state file. !32182 (Rajendra Kadam) +- Use applogger in project.rb. !32183 (Rajendra Kadam) +- Use applogger in chat_team.rb. !32184 (Rajendra Kadam) +- Use applogger in repository model. !32185 (Rajendra Kadam) +- Use applogger in build and ssh host key. !32187 (Rajendra Kadam) +- Use applogger in cache attrs and highest role ruby files. !32189 (Rajendra Kadam) +- Use applogger in legacy project and namespace. !32190 (Rajendra Kadam) +- Use applogger in base.rb. !32191 (Rajendra Kadam) +- Use applogger in usage ping and webhook service. !32192 (Rajendra Kadam) +- Use applogger in exclusive_lease_guard. !32194 (Rajendra Kadam) +- Use applogger in groups destroy service and label create service. !32195 (Rajendra Kadam) +- Use applogger in merge_service.rb. !32196 (Rajendra Kadam) +- Use applogger in project create service and after import service. !32198 (Rajendra Kadam) +- Use applogger in update stats service. !32200 (Rajendra Kadam) +- Use applogger in base attachment service. !32201 (Rajendra Kadam) +- Use applogger in export service. !32203 (Rajendra Kadam) +- Use applogger in akismet service. !32205 (Rajendra Kadam) +- Use applogger in file mover file. !32206 (Rajendra Kadam) +- Use applogger in commit signature worker. !32207 (Rajendra Kadam) +- Use applogger in delete user worker. !32209 (Rajendra Kadam) +- Use applogger in email receiver worker. !32211 (Rajendra Kadam) +- Use applogger in artifact worker. !32212 (Rajendra Kadam) +- Use applogger in new note worker. !32213 (Rajendra Kadam) +- Fix duplicate filename displayed in design todos. !32274 (Arun Kumar Mohan) +- Add value length validations for instance level variable. !32303 +- Resolve image overflow at releases list panel. !32307 +- Clean up shared/tmp folder after Import/Export. !32326 +- Fix creating release evidence if release is created via UI. !32441 +- GraphQL hasNextPage and hasPreviousPage return correct values. !32476 +- Fix loading and empty state styling for alerts list. !32531 +- Resolve incorrect x-axis padding on the Environments Dashboard. !32533 +- Fix time_tracking help link. !32552 +- Don't display confidential note icon on confidential issue public notes. !32571 +- Update container expiration policy database defaults. !32600 +- Fix rendering of emojis in status tooltips. !32604 +- Hid copy contents button when blob has rendering error. !32632 +- Avoid refresh to show endedAt after mutation. !32636 +- Fix for metrics creation when saving MR. !32668 +- Skip the individual JIRA issues if failed to import vs failing the whole batch. !32673 +- Hide "Import from Jira" option from non-entitled users. !32685 +- Fix broken help link on operations settings page. !32722 +- Allow different in bulk editing issues. !32734 +- Fix whitespace changes overgrowing the diff container. !32774 +- Improve spacing and wrapping of group actions buttons and stats in group list view. !32786 +- Fix "Broadcast Messages" table overflow and button alignment. !32801 +- Fix 404 when downloading a non-archive artifact. !32811 +- Make commits author button confirm to Pajamas specs. !32821 +- Fix filename duplication in design notes in activity feeds. !32823 (Arun Kumar Mohan) +- Prevent multiple Auto DevOps deployment jobs running concurrently when using manual rollout. !32824 +- Implement displaying downstream pipeline error details. !32844 +- Fix Runner heartbeats that results in considering them offline. !32851 +- Conan package registry support for the conan_export.tgz file. !32866 +- Fix plural message in account deletion section. !32868 +- Fix atomic processing bumping a lock_version. !32914 +- AsciiDoc: Add support for built-in alignment roles. !32928 (mnrvwl) +- Fix a bug where some Vue apps would be unable to load when DAG tab is disabled. !32966 +- Fix undefined error in Gitlab::Git::Diff. !32967 +- Fix spelling error on Ci::RunnersFinder. !32985 (Arthur de Lapertosa Lisboa) +- Fix polling for resource events. !33025 +- Fix broken CSS classes inside alert management list. !33038 +- Fix bug in snippet create mutation with non ActiveRecord errors. !33085 +- Fix overflow issue in MR and Issue comments. !33100 +- Fix alignment of button text on the Edit Release page. !33104 +- Deduplicate URL parameters when requesting merge request diffs which causes diffs load to fail. !33117 +- Fix tabbing through form fields in projects/new flow. !33209 +- Fix incorrect commit search results returned when searching with ref. !33216 +- Fix NoMethodError by using the correct method to report exceptions to Sentry. !33260 +- Fix KaTeX font paths. !33338 +- Resolve Fix Incomplete Kubernetes Cluster Status List. !33344 +- Fix auto-merge not running after discussions resolved. !33371 +- Fix bug in snippets updating only file_name or content. !33375 +- Fix invisible emoji modal on Set Status form when clicked the second time. !33398 +- vertically center action icon in the CI pipeline. !33427 (Nathanael Weber) +- Wrap auto merge parameters update in database transaction. !33471 +- Return 404 response when redirecting request with invalid url. !33492 +- Fix ambiguous string concatenation on CleanupProjectsWithMissingNamespace. !33497 +- Fix snippet repository import edge cases. !33506 +- Rust CI template: Replace --all with --workspace on cargo test. !33517 (Markus Becker) +- Make markdown textarea links tab-accessible. !33518 +- Pass hard delete option to snippets bulk destroy. !33520 +- Fix CI rules for ECS related jobs. !33527 +- Update GitLab Workhorse to v8.34.0. !33543 +- Fix snippet repository import fail with older export files. !33584 +- Web IDE: Create template files in the folder from which new file request was made. !33585 (Ashesh Vidyut) +- Improve header acccessibility. !33603 +- Remove non migrated snippets from failed imports. !33621 +- Prevent duplicate issues when importing from CSV. !33626 +- Fix sidebar spacing for alert details. !33630 +- Fix linking alerts to created issues for the Generic alerts intergration. !33647 +- Resolve spacing ux debt on Release assets form field. !33684 +- Fix pagination link header. !33714 (Max Wittig) +- Fix Value Stream Analytics summary when using non-english locale. !33717 +- Fix bug with variable substitution in alerts. !33772 +- Allow wiki pages with +<> characters in their title to be saved. !33803 +- Fix force_remove_source_branch not working in API. !33804 +- Fix prometheus alerts not being automatically created. !33806 +- Fix pagination for resource label events. !33821 +- Fix relative URL root in wiki_base_path. !33841 +- Return code navigation path for nil diff_refs. !33850 +- Record audit event when an admin creates a new SSH Key for a user via the API. !33859 (Rajendra Kadam) +- Do not create duplicate issues for exising Alert Management alerts. !33860 +- Add link text to collapsed left sidebar links for screen readers. !33866 +- Update text in error tracking list error message. !33872 +- Adjust wrong column reference for ResetMergeStatus (background job). !33899 +- Fixed dashboard YAML file validaiton for files which do not contain object as root element. !33935 +- Fix design note scrolling. !33939 +- Update validates_hostname gem with support for more TLDs. !34010 +- Update wording of addMultipleToDiscussionWarning. !34088 +- Show all storages in settings. !34093 +- Set author as nullable in snippet GraphQL Type. !34135 +- Fix rendering of very long paths in merge request file tree. !34153 +- Remove not null constraint from events tables. !34190 +- Ensure we always generate a valid wiki event URL. !34191 +- Send information about attached files to the GraphQL mutation. !34221 +- Update issue limits template to use minutes. !34254 +- Add route for the lost-and-found group and update the route of orphaned projects. !34285 +- GraphQL - properly handle pagination of millisecond-precision timestamps. !34352 +- Fix 500 error in BlobController#delete. !34367 +- Updated Auto DevOps with a fix to delete PostgreSQL PVC on environment cleanup, a fix for multiline K8S_SECRET variables, updated Helm to 2.16.7 and glibc to 2.31. !34399 (verenion) +- Fix issues with scroll on iOS / iPad OS. !34486 +- Fix order of integrations to be sorted alphabetically. !34501 +- Fix undefined method error. !34522 +- Use Keys::DestroyService for deleting an SSH key when an admin deletes a key via the API. !34535 (Rajendra Kadam) +- Removed default artifact name for Terraform template. !34557 +- Footer system message fix. +- Set experiementation cookie for GitLab domain only. +- Add DS detection of build.gradle.kts. + +### Changed (76 changes, 5 of them are from the community) + +- Add a GraphQL endpoint to fetch Jira projects through its REST API. !28190 +- Change legends in monitor dashboards to tabular layout. !30131 +- Move pipelines routing under /-/ scope. !30730 +- Set markdown toolbar to use hyphens for lists. !31426 +- Use sprites for comment icons on Commits. !31696 +- Rate limit project export by user. !31719 +- Reorder diffs compare versions dropdowns. !31770 (Gilang Gumilar) +- Enable the `in this group` action in the Search dropdown. !31939 +- Externalize i18n strings from ./app/views/shared/_promo.html.haml. !32109 (Gilang Gumilar) +- Add Usage Ping count for all searches. !32111 +- Add tags_count to container registry api and controller. !32141 +- Externalize i18n strings from ./app/views/shared/milestones/_sidebar.html.haml. !32150 (Gilang Gumilar) +- Externalize i18n strings from ./app/views/shared/milestones/_form_dates.html.haml. !32162 (Gilang Gumilar) +- Improve Container Registry UI header. !32424 +- Added node size to cluster index. !32435 +- Update operations metrics settings title and description to make them general. !32494 +- Track merge_requests_users usage data. !32562 +- Adds cluster CPU and Memory to cluster index. !32601 +- Allow the snippet create service to accept an array of files. !32649 +- Move review related controllers/workers outside EE. !32663 +- Move the Members section from settings to the side nav for projects. !32667 +- Show more context in unresolved jump button. !32737 +- Exclude extra.server fields from exceptions_json.log. !32770 +- Improve new/unknown sign-in email styling. !32808 +- Allow the snippet update service to accept an array of files. !32832 +- Add new issue link to email notification header. !32833 +- Bump cluster-applications to 0.17.0, which updates Runner to 0.17.0 and Cilium to 1.7.4. !32931 +- Update artifacts section to show when an artifact is locked. !32992 +- Include tag count in the image repository list. !33027 +- Clean up gitlab-shell install-from-source path. !33057 +- Increase LFS token default time to 2 hours. !33140 +- Add explicit mention of Merge request in Slack message. !33152 +- Expose `release_links.type` via API. !33154 +- Add link_type column to release_links table. !33156 +- Move broadcast notification dismiss button to the top. !33174 +- Remove null constraint for JID in GroupImportState. !33181 +- Added provider type icon to cluster list. !33196 +- Remove search icon from Project find file button. !33198 +- Refine SAST language detection by frameworks. !33226 +- Render Merge request reference as link. !33248 +- Upgrade to Gitaly v13.1.0-rc1. !33302 +- Show disabled suggestion button with tooltip message. !33357 +- Add update validations to SnippetInputAction. !33379 +- Add snippet DB visibility check in spec. !33388 (Jacopo Beschi @jacopo-beschi) +- Add Hugo logo to project templates. !33402 +- Add GitBook logo to project templates. !33403 +- Add GoMicro logo to project templates. !33404 +- Add Jekyll logo to project templates. !33405 +- Add Hexo logo to project templates. !33406 +- Rename Add Designs button. !33491 +- Add CPU, memory usage charts to self monitoring default dashboard. !33532 +- Add database migrations to design_management_designs.filename to enforce a 255 character limit, and modify any filenames that exceed that limit. !33565 +- Track Sentry error status updates with dedicated actions. !33623 +- Alert Managament: Change sorting order to have newest alerts first. !33642 +- Add blobs field to SnippetType in GraphQL. !33657 +- Format metrics column chart x axis dates. !33681 +- Style ToastUI contextual menus. !33719 +- Update Auto deploy image to v0.16.1, introducing support for AUTO_DEVOPS_DEPLOY_DEBUG. !33799 +- Add whether instance has Auto DevOps enabled to usage ping. !33811 +- Update local IP address and domain name allow list input label. !33812 +- Add date time format to the monitor stacked-column chart. !33814 +- Allow Tf Plan to genrate multiple reports. !33867 +- Remove async_merge_request_check_mergeability feature flag. !33917 +- Filter potentially-sensitive Sidekiq arguments from logs and Sentry. !33967 +- Update Static Site Editor toolbar to group inline-code and code-block buttons together. !34006 +- Set default values for SAST_EXCLUDED_PATHS and DS_EXCLUDED_PATHS. !34076 +- Add ability to filter self monitoring resource usage charts by instance name. !34084 +- Pick repository storage based on weight. !34095 +- Display error for YAML files that are too large. !34199 +- Change copy of webhooks / integration help text. !34301 +- Update board header icons. !34366 +- Show Redis instance in performance bar. !34377 +- Add secret detection template to Auto DevOps. !34467 +- Add allowed actions to snippet input action. !34499 +- Change from vendor specific to Gitlab. !34576 +- Assign alerts sidebar base. + +### Performance (19 changes, 1 of them is from the community) + +- Improve performance of commit search by limiting the number of results requested. !32260 +- Add GraphQL lookahead support. !32373 +- Update index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial index for secret_detection. !32584 +- Add index on id and type for Snippets. !32885 +- Use build_stubbed to avoid interacting with the DB in todos helper specs. !32906 (Arun Kumar Mohan) +- Optimize SQL queries on Milestone index page. !32953 +- Add build report results data model. !32991 +- Adjust condition for partial indexes on services table. !33044 +- Add index to issues and epics on last_edited_by_id. !33075 +- Fix preconnect typo in rel link. !33255 +- Add project_id, user_id, status, ref index to ci_pipelines. !33290 +- Move migration related to ci_builds to post_deployment. !33416 +- Reduce redundant queries for Search API users scope. !33795 +- Speed up boot time in production. !33929 +- Harden CI pipelines usage data queries with an index. !34045 +- Add partial index on locked merge requets. !34127 +- Lazy load commit_date and authored_date on Commit. !34181 +- Optimize container repository for groups query. !34364 +- Enable CI Atomic Processing by default. + +### Added (149 changes, 14 of them are from the community) + +- Add rake task to verify encrypted data through secrets. !21851 +- User can apply multiple suggestions at the same time. !22439 (Jesse Hall) +- Resolve Add a button to assign users who have commented on an issue. !23883 +- Resolve Graph code coverage changes over time for a project. !26174 +- Add doc for custom validators in api styleguide. !26734 (Rajendra Kadam) +- Add Scheduled Job for Monitoring Monitor Group Demo Environments. !27360 +- Add setting to allow merge on skipped pipeline. !27490 (Mathieu Parent) +- Add dark theme (alpha). !28252 +- Show estimate on issues list. !28271 (Lee Tickett) +- Make Fixed Email Notification Generally Available. !28338 (jacopo-beschi) +- Add a link to the `renamed` viewer to fully expand the renamed file (if it's text). !28448 +- Focus and toggle metrics dashboard panels via keyboard. !28603 +- Remove `scoped_approval_rules` feature flag. !28864 (Lee Tickett) +- Create Group import UI for creating new Groups. !29271 +- Add finder for group-level runners. !29283 (Arthur de Lapertosa Lisboa) +- Allow customization of badge key_text and key_width. !29381 (Fabian Schneider @fabsrc) +- Support Workhorse directly uploading files to S3. !29389 +- Add frontend support for multiline comments. !29516 +- Support first_name and last_name attributes in LDAP user sync. !29542 +- Add link to status page detail view for status page published issues. !30249 +- Add metrics dashboard name to document title. !30392 +- Backfill StatusPage::Published incidents and enable a publish quick action for EE. !30906 +- Add missing Merge Request fields. !30935 +- Show build status on branch list. !30948 (Lee Tickett) +- Add mutation to create commits in GraphQL. !31102 +- Add GraphQL support for authored and assigned Merge Requests. !31227 +- Add usage data metrics for terraform states. !31280 +- Add usage data metrics for terraform reports. !31281 +- Add API endpoint for listing bridge jobs. !31370 (Abhijith Sivarajan) +- SpamVerdictService can call external spam check endpoint. !31449 +- Move Admin note feature to GitLab Core. !31457 (Rajendra) +- Add DAG serializer for pipelines controller. !31583 +- Save repository storages in application settings with weights. !31645 +- Add API endpoint for resource milestone events. !31720 +- Show import in progress screen for group imports. !31731 +- Add Verify/FailFast CI template. !31812 +- Improve Add/Remove Issue Labels API. !31864 (Lee Tickett) +- Add mutation to create a merge request in GraphQL. !31867 +- Add warning popup for Elastic Stack update. !31972 +- Add API support for sharing groups with groups. !32008 +- Add the container expiration policy attribute to the project GraphQL type. !32100 +- Add GraphQL support for project and group labels. !32113 +- Add number of database calls to Prometheus metrics and logs for sidekiq and request. !32131 +- Filter pipelines by status. !32151 +- Filter pipelines based on url query params. !32230 +- Add metrics for Redis usage during Sidekiq job execution. !32265 +- Add filters to merge request fields. !32328 +- Support reading .editorconfig files inside of the Web IDE. !32378 +- [Frontend] Resolvable design discussions. !32399 +- Table index added to `metrics_dashboard_annotations` for future pruning of stale metrics Annotations for metrics dashboards are now checked for valid start and end dates. !32433 +- Enable GitLab-Flavored Markdown processing for design links. !32446 +- Filter Pipelines by Tag Name. !32470 +- Adds sorting by column to alert management list. !32478 +- Add project specific repository storage API. !32493 +- Adapt Limitable for system-wide features. !32574 +- Add application limits to instance level CI/CD variables. !32575 +- Add model for project level security auto-fix settings. !32577 +- Expose Jira imported issues count in GraphQL. !32580 +- Organize alerts by status tabs. !32582 +- Add note to ECS CI template. !32597 +- Add metrics for Redis usage during web requests. !32605 +- Add database and GraphQL support for alert assignees. !32609 +- Set fingerprints and increment events count for Alert Management alerts. !32613 +- Process stuck jira import jobs. !32643 +- Allow user to add custom links to their metrics dashboard panels. !32646 +- Add tags to experimental queue selector attributes. !32651 +- Allow generic endpoint to receive alerts from external Prometheus. !32676 +- Customize the Cloud Native Buildpack builder used with Auto Build. !32691 +- Add timezone display to alert based issue start time. !32702 +- Display dates on metrics dashboards in UTC time zone. !32746 +- Store Todo resolution method. !32753 +- Add experience_level to user_preferences. !32784 +- Remove metrics dashboard annotations attached to time periods older than two weeks. !32838 +- Monitor:Health metrics instrumenation. !32846 +- Adds PostHog as a CI/CD Managed Application. !32856 +- Groups API has top_level_only option to exclude subgroups. !32870 +- Create operations_feature_flags_issues table. !32876 +- Add api.js methods to update issues and merge requests. !32893 +- Render user-defined links in dashboard yml file on metrics dashboard. !32895 +- Add accessibility report MR widget. !32902 +- Add a GraphQL mutation for toggling the resolved state of a Discussion. !32934 +- Add container expiration policy objects to the GraphQL API. !32944 +- Don't hide Commit tab in Web IDE when there are no changes yet. !32979 +- Add column for alert slack notifications. !33017 +- Add ability to insert an image via SSE. !33029 +- Add user root query to GraphQL API. !33041 +- Adds groupMembership and projectMembership to GraphQL API. !33049 +- Alerts list pagination. !33073 +- Add ApplicationSetting ui changes for repository_storages_weighted. !33096 +- Display confirmation modal when user exits SSE and there are unsaved changes. !33103 +- Add column dashboard_timezone to project_metrics_setting. !33120 +- Allow the assignment of alerts to users from the alert detail view. !33122 +- Add solarized dark for Web IDE. !33148 +- Add support for artifacts/exclude configuration. !33170 +- Add root users query to GraphQL API. !33195 +- Added validation for YAML files with metrics dashboard definitions. !33202 +- Create issue from alert. !33213 +- Add max import file size option. !33215 (Roger Meier) +- Add system note when assigning user to alert. !33217 +- Add count of alerts from all sources to usage ping. !33220 +- Add button to create an issue from an alert management alert. !33221 +- Add more detail to alert integration settings description. !33244 +- Add Evidence to Releases GraphQL endpoint. !33254 +- Add support for pasting images in the Web IDE. !33256 +- Add ProjectAccessToken table. !33272 +- Automatically resolve alert when associated issue closes. !33278 +- Add `link_type` to `ReleaseLink` GraphQL type. !33386 +- Add members to project graphQL endpoint. !33418 +- Update Static Site Editor WYSIWYG mode to hide front matter. !33441 +- Added delete action for Dashboard Annotations in GraphQL. !33468 +- Create graphQL endpoint for Jira users import. !33501 +- Support IAP protected prometheus installations. !33508 +- New instance-level variables UI. !33510 +- Provide `__range` variable for Prometheus queries. !33521 +- Add support for `git filter-repo` to repository cleanup. !33576 +- Close open reply input fields in the design view sidebar when leaving a new comment. !33587 +- Add dashboard schema validation warnings as metrics dashboard GraphQL field. !33592 +- Add time range to user-defined links in metrics dashboard. !33663 +- Increase events count for Prometheus alerts. !33706 +- Track pod logs refresh action. !33802 +- Add secret detection template. !33869 +- Add DAG visualization MVC. !33958 +- Introduce a feature flag for Vue-based UI for all import providers. !33980 +- Add sticky title on Issue pages. !33983 +- Allow Release asset links to be associated with a type. !33998 +- Support user-defined Grafana links in metrics dashboard. !34003 +- Adds AWS guidance to CI/CD > Add Variable modal. !34009 +- Show custom attributes within Admin Pages. !34017 (Roger Meier) +- Enable Slack notifications for alerts. !34038 +- Container expiration policy regular expressions are now validated. !34063 +- Add todo when alert is assigned to a user. !34104 +- Track merge requests submitted by Static Site Editor. !34105 +- Turn off alert issue creation by default. !34107 +- Add detailed logs of each Redis instance usage during job execution and web requests. !34110 +- Add API to schedule project repository storage moves. !34119 +- Add validation step on backend for metrics dashboard links. !34204 +- Track when Static Site Editor is initialized. !34215 +- Bring SAST to Core - brakeman. !34217 +- Mask key comments when exposing SSH/Deploy Keys via the API. !34255 +- Convert `:release` yaml to `release-cli` commands. !34261 +- Validate regex before sending them to CleanupContainerRepositoryWorker. !34282 +- Add secret_detection to DOWNLOADABLE_TYPES. !34313 +- Enable ability to assign alerts to users with corresponding system notes and todos. !34360 +- Enable CI Inheriting Env Variables feature. !34495 +- Show tooltip on error detail page when hovering over dates. !34506 +- Add native code intelligence. !34542 +- Bump cluster-applications version to v0.20.0. !34569 +- Add search argument for AlertStatusCountsResolver. !34596 +- Allow CI_JOB_TOKEN for authenticating to the Terraform state API. !34618 + +### Other (65 changes, 36 of them are from the community) + +- Improve fast-forward merge is not possible message. !22834 (Ben Bodenmiller) +- Remove unused WAF indexes from CI variables. !30021 +- Update the visual design of badges in some areas. !31646 +- Extract featurable concern from ProjectFeature. !31700 (Alexander Randa) +- Remove update function logic from list model. !31900 (nuwe1) +- Remove nextpage function logic from list model. !31904 (nuwe1) +- Squash database migrations prior to 2019 into one. !31936 +- Update deprecated slot syntax in app/assets/javascripts/reports/components/grouped_test_reports_app.vue. !31975 (Gilang Gumilar) +- Replace slot syntax for Vue 3 migration. !31987 (gaslan) +- Update deprecated slot syntax in ./app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue. !31994 (Gilang Gumilar) +- Update deprecated slot syntax in ./app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue. !31995 (Gilang Gumilar) +- Update deprecated slot syntax in ./app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue. !32010 (Gilang Gumilar) +- Update deprecated slot syntax in ./app/assets/javascripts/environments/components/environments_app.vue. !32011 (Gilang Gumilar) +- Remove setLoadingState logic from issue model. !32226 (nuwe1) +- Remove addAssignee logic from issue model. !32231 (nuwe1) +- Remove addLabel Logic from issue models. !32233 (nuwe1) +- Remove addMilestone logic from issue model. !32235 (nuwe1) +- Remove destroy function logic from list model. !32237 (nuwe1) +- Remove findAssignee logic from issue model. !32238 (nuwe1) +- Remove findLabel logic from issue model. !32239 (nuwe1) +- Remove findIssue logic from list model. !32241 (nuwe1) +- Remove moveIssue logic from list model. !32242 (nuwe1) +- Remove newIssue logic from list model. !32244 (nuwe1) +- Remove removeAllAssignees logic from issue model. !32247 (nuwe1) +- Remove removeAssignee logic from issue model. !32248 (nuwe1) +- Clarify verbiage for stuck job messages. !32250 +- Remove removeLabel logic from issue model. !32251 (nuwe1) +- Remove removeLabels logic from issue model. !32252 (nuwe1) +- Remove removeMilestone logic from issue model. !32253 (nuwe1) +- Remove removeMultipleIssues logic from list model. !32254 (nuwe1) +- Remove setFetchingState logic from issue model. !32255 (nuwe1) +- Remove updateData logic from issue model. !32256 (nuwe1) +- Update U2F docs for Firefox 67+. !32289 (Takuya Noguchi) +- Update alert management mobile table alignment. !32295 +- Include available instance memory in usage ping. !32315 +- Moves merge request reviews into Core. !32558 +- Update GitLab Runner Helm Chart to 0.17.0. !32634 +- Add snowplow tracking for logs page. !32704 +- Extend "Remember me" token after each login. !32730 +- Assign alerts sidebar container fix. !32743 +- Add anchor for creating a branch. !32745 +- Tidy. !32759 (Lee Tickett) +- Less verbose JiraService error logs. !32847 +- Reduced padding and increased emphasis of titles within the epic tree. !32873 +- Remove obsolete users.ghost column. !32957 +- Move NoPrimary table def to last context in spec. !33015 (Rajendra Kadam) +- Document github rate limit behavior. !33090 +- Added build_id column to requirements_management_test_reports table. !33184 +- Add version history information on U2F support. !33229 (Takuya Noguchi) +- Convert IP spoofing errors into client errors. !33280 +- Update docs to reflect move web IDE Terminal and file sync to Core. !33419 +- Add hovering icon for sorting columns on alert management list. !33429 +- Avoid javascript for omniauth logins. !33459 (Diego Louzán) +- Add opacity transition to active design discussion pins. !33493 +- Update GitLab Runner Helm Chart to 0.17.1. !33504 +- Make project selector in various dashboard more translatable. !33771 +- Update Workhorse to v8.35.0. !33817 +- Remove FF hide_token_from_runners_api. !33947 +- Bump omniauth_openid_connect to 0.3.5. !34030 (Roger Meier) +- Specify tiers for SAML SSO at self-hosted plans. !34040 (Takuya Noguchi) +- Backfill failed imported snippet repositories. !34052 +- Use GitLab SVG icon for file attacher action. !34196 +- Add GraphQL snippet FileInputType. !34442 +- Update red hex values to match GitLab UI. !34544 +- Remove removeIssue logic from list model. (nuwe1) + + ## 13.0.6 (2020-06-10) - No changes. -## 13.0.5 (2020-06-04) - -### Fixed (4 changes) - -- Fix NoMethodError by using the correct method to report exceptions to Sentry. !33260 -- Fix bug in snippets updating only file_name or content. !33375 -- Fix ambiguous string concatenation on CleanupProjectsWithMissingNamespace. !33497 -- Fix linking alerts to created issues for the Generic alerts intergration. !33647 - -### Other (1 change) - -- Update GitLab Workhorse to v8.31.2. !33818 - - ## 13.0.4 (2020-06-03) ### Security (1 change) @@ -41,10 +515,6 @@ entry. - Fix close issue when user created the issue. !33294 -## 13.0.2 (2020-05-28) - -- No changes. - ## 13.0.1 (2020-05-27) ### Security (12 changes) @@ -632,6 +1102,49 @@ entry. - Use visitUrl in Alert management. !32414 +## 12.10.11 (2020-06-10) + +- No changes. + +## 12.10.8 (2020-05-28) + +### Fixed (2 changes) + +- Fix Geo replication for design thumbnails. !32703 +- Fix 404s downloading build artifacts. !32741 + + +## 12.10.7 (2020-05-27) + +### Security (14 changes) + +- Add an extra validation to Static Site Editor payload. +- Hide EKS secret key in admin integrations settings. +- Added data integrity check before updating a deploy key. +- Display only verified emails on notifications and profile page. +- Disable caching on repo/blobs/[sha]/raw endpoint. +- Require confirmed email address for GitLab OAuth authentication. +- Kubernetes cluster details page no longer exposes Service Token. +- Fix confirming unverified emails with soft email confirmation flow enabled. +- Disallow user to control PUT request using mermaid markdown in issue description. +- Check forked project permissions before allowing fork. +- Limit memory footprint of a command that generates ZIP artifacts metadata. +- Fix file enuming using Group Import. +- Prevent XSS in the monitoring dashboard. +- Use `gsub` instead of the Ruby `%` operator to perform variable substitution in Prometheus proxy API. + + +## 12.10.6 (2020-05-15) + +### Fixed (5 changes) + +- Fix duplicate index removal on ci_pipelines.project_id. !31043 +- Fix 500 on creating an invalid domains and verification. !31190 +- Fix incorrect number of errors returned when querying sentry errors. !31252 +- Add instance column to services table if it's missing. !31631 +- Fix incorrect regex used in FileUploader#extract_dynamic_path. !32271 + + ## 12.10.5 (2020-05-13) ### Added (1 change) @@ -1121,6 +1634,29 @@ entry. - Remove store_mentions! in Snippets::CreateService. !29581 (Sashi Kumar) +## 12.9.10 (2020-06-10) + +- No changes. + +## 12.9.8 (2020-05-27) + +### Security (13 changes) + +- Hide EKS secret key in admin integrations settings. +- Added data integrity check before updating a deploy key. +- Display only verified emails on notifications and profile page. +- Disable caching on repo/blobs/[sha]/raw endpoint. +- Require confirmed email address for GitLab OAuth authentication. +- Kubernetes cluster details page no longer exposes Service Token. +- Fix confirming unverified emails with soft email confirmation flow enabled. +- Disallow user to control PUT request using mermaid markdown in issue description. +- Check forked project permissions before allowing fork. +- Limit memory footprint of a command that generates ZIP artifacts metadata. +- Fix file enuming using Group Import. +- Prevent XSS in the monitoring dashboard. +- Use `gsub` instead of the Ruby `%` operator to perform variable substitution in Prometheus proxy API. + + ## 12.9.6 (2020-05-05) ### Fixed (1 change) diff --git a/Dangerfile b/Dangerfile index 7879c14b31..cc6ebc27d4 100644 --- a/Dangerfile +++ b/Dangerfile @@ -7,8 +7,16 @@ danger.import_plugin('danger/plugins/helper.rb') danger.import_plugin('danger/plugins/roulette.rb') danger.import_plugin('danger/plugins/changelog.rb') -unless helper.release_automation? - GitlabDanger.new(helper.gitlab_helper).rule_names.each do |file| - danger.import_dangerfile(path: File.join('danger', file)) - end +return if helper.release_automation? + +gitlab_danger = GitlabDanger.new(helper.gitlab_helper) + +gitlab_danger.rule_names.each do |file| + danger.import_dangerfile(path: File.join('danger', file)) +end + +anything_to_post = status_report.values.any? { |data| data.any? } + +if gitlab_danger.ci? && anything_to_post + markdown("**If needed, you can retry the [`danger-review` job](#{ENV['CI_JOB_URL']}) that generated this comment.**") end diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 6fe535b5ba..9e6fba6c2c 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -13.0.6 +203182ffe94da165d4ff81332b1b3fff9771e631 diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 67aee23940..ac565bc1ca 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -13.2.0 +13.3.0 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 594580cb92..13afb01d49 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -8.31.2 +8.35.0 diff --git a/Gemfile b/Gemfile index 9c8c5e8b30..5477ee3d18 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails', '~> 6.0.3' +gem 'rails', '~> 6.0.3.1' gem 'bootsnap', '~> 1.4.6' @@ -43,8 +43,7 @@ gem 'omniauth-shibboleth', '~> 1.3.0' gem 'omniauth-twitter', '~> 1.4' gem 'omniauth_crowd', '~> 2.2.0' gem 'omniauth-authentiq', '~> 0.3.3' -gem 'omniauth_openid_connect', '~> 0.3.3' -gem "omniauth-ultraauth", '~> 0.0.2' +gem 'omniauth_openid_connect', '~> 0.3.5' gem 'omniauth-salesforce', '~> 1.0.5' gem 'rack-oauth2', '~> 1.9.3' gem 'jwt', '~> 2.1.0' @@ -64,7 +63,7 @@ gem 'attr_encrypted', '~> 3.1.0' gem 'u2f', '~> 0.2.1' # GitLab Pages -gem 'validates_hostname', '~> 1.0.6' +gem 'validates_hostname', '~> 1.0.10' gem 'rubyzip', '~> 2.0.0', require: 'zip' # GitLab Pages letsencrypt support gem 'acme-client', '~> 2.0.5' @@ -113,14 +112,14 @@ gem 'fog-aws', '~> 3.5' # Locked until fog-google resolves https://github.com/fog/fog-google/issues/421. # Also see config/initializers/fog_core_patch.rb. gem 'fog-core', '= 2.1.0' -gem 'fog-google', '~> 1.9' +gem 'fog-google', '~> 1.10' gem 'fog-local', '~> 0.6' gem 'fog-openstack', '~> 1.0' gem 'fog-rackspace', '~> 0.1.1' gem 'fog-aliyun', '~> 0.3' # for Google storage -gem 'google-api-client', '~> 0.23' +gem 'google-api-client', '~> 0.33' # for aws storage gem 'unf', '~> 0.1.4' @@ -343,7 +342,7 @@ group :development do end group :development, :test do - gem 'bullet', '~> 6.0.2', require: !!ENV['ENABLE_BULLET'] + gem 'bullet', '~> 6.0.2' gem 'pry-byebug', '~> 3.5.1', platform: :mri gem 'pry-rails', '~> 0.3.9' @@ -362,10 +361,10 @@ group :development, :test do gem 'spring', '~> 2.0.0' gem 'spring-commands-rspec', '~> 1.0.4' - gem 'gitlab-styles', '~> 3.2.0', require: false + gem 'gitlab-styles', '~> 4.2.0', require: false # Pin these dependencies, otherwise a new rule could break the CI pipelines - gem 'rubocop', '~> 0.74.0' - gem 'rubocop-performance', '~> 1.4.1' + gem 'rubocop', '~> 0.82.0' + gem 'rubocop-performance', '~> 1.5.2' gem 'rubocop-rspec', '~> 1.37.0' gem 'scss_lint', '~> 0.56.0', require: false @@ -403,7 +402,6 @@ group :test do gem 'shoulda-matchers', '~> 4.0.1', require: false gem 'email_spec', '~> 2.2.0' - gem 'json-schema', '~> 2.8.0' gem 'webmock', '~> 3.5.1' gem 'rails-controller-testing' gem 'concurrent-ruby', '~> 1.1' @@ -454,7 +452,7 @@ group :ed25519 do end # Gitaly GRPC protocol definitions -gem 'gitaly', '~> 13.0.0.pre.rc1' +gem 'gitaly', '~> 13.1.0.pre.rc1' gem 'grpc', '~> 1.24.0' @@ -498,3 +496,4 @@ gem 'valid_email', '~> 0.1' # JSON gem 'json', '~> 2.3.0' +gem 'json-schema', '~> 2.8.0' diff --git a/Gemfile.lock b/Gemfile.lock index ffff576e8b..319c4df3f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,59 +6,59 @@ GEM ace-rails-ap (4.1.2) acme-client (2.0.5) faraday (~> 0.9, >= 0.9.1) - actioncable (6.0.3) - actionpack (= 6.0.3) + actioncable (6.0.3.1) + actionpack (= 6.0.3.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.3) - actionpack (= 6.0.3) - activejob (= 6.0.3) - activerecord (= 6.0.3) - activestorage (= 6.0.3) - activesupport (= 6.0.3) + actionmailbox (6.0.3.1) + actionpack (= 6.0.3.1) + activejob (= 6.0.3.1) + activerecord (= 6.0.3.1) + activestorage (= 6.0.3.1) + activesupport (= 6.0.3.1) mail (>= 2.7.1) - actionmailer (6.0.3) - actionpack (= 6.0.3) - actionview (= 6.0.3) - activejob (= 6.0.3) + actionmailer (6.0.3.1) + actionpack (= 6.0.3.1) + actionview (= 6.0.3.1) + activejob (= 6.0.3.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.3) - actionview (= 6.0.3) - activesupport (= 6.0.3) + actionpack (6.0.3.1) + actionview (= 6.0.3.1) + activesupport (= 6.0.3.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.3) - actionpack (= 6.0.3) - activerecord (= 6.0.3) - activestorage (= 6.0.3) - activesupport (= 6.0.3) + actiontext (6.0.3.1) + actionpack (= 6.0.3.1) + activerecord (= 6.0.3.1) + activestorage (= 6.0.3.1) + activesupport (= 6.0.3.1) nokogiri (>= 1.8.5) - actionview (6.0.3) - activesupport (= 6.0.3) + actionview (6.0.3.1) + activesupport (= 6.0.3.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.0.3) - activesupport (= 6.0.3) + activejob (6.0.3.1) + activesupport (= 6.0.3.1) globalid (>= 0.3.6) - activemodel (6.0.3) - activesupport (= 6.0.3) - activerecord (6.0.3) - activemodel (= 6.0.3) - activesupport (= 6.0.3) + activemodel (6.0.3.1) + activesupport (= 6.0.3.1) + activerecord (6.0.3.1) + activemodel (= 6.0.3.1) + activesupport (= 6.0.3.1) activerecord-explain-analyze (0.1.0) activerecord (>= 4) pg - activestorage (6.0.3) - actionpack (= 6.0.3) - activejob (= 6.0.3) - activerecord (= 6.0.3) + activestorage (6.0.3.1) + actionpack (= 6.0.3.1) + activejob (= 6.0.3.1) + activerecord (= 6.0.3.1) marcel (~> 0.3.1) - activesupport (6.0.3) + activesupport (6.0.3.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -286,7 +286,7 @@ GEM factory_bot_rails (5.1.0) factory_bot (~> 5.1.0) railties (>= 4.2.0) - faraday (0.15.4) + faraday (0.17.3) multipart-post (>= 1.2, < 3) faraday-http-cache (2.0.0) faraday (~> 0.8) @@ -330,11 +330,11 @@ GEM excon (~> 0.58) formatador (~> 0.2) mime-types - fog-google (1.9.1) + fog-google (1.10.0) fog-core (<= 2.1.0) fog-json (~> 1.2) fog-xml (~> 0.1.0) - google-api-client (~> 0.23.0) + google-api-client (>= 0.32, < 0.34) fog-json (1.2.0) fog-core multi_json (~> 1.10) @@ -377,7 +377,7 @@ GEM po_to_json (>= 1.0.0) rails (>= 3.2.0) git (1.5.0) - gitaly (13.0.0.pre.rc1) + gitaly (13.1.0.pre.rc1) grpc (~> 1.0) github-markup (1.7.0) gitlab-chronic (0.10.5) @@ -400,11 +400,11 @@ GEM gitlab-puma (>= 2.7, < 5) gitlab-sidekiq-fetcher (0.5.2) sidekiq (~> 5) - gitlab-styles (3.2.0) - rubocop (~> 0.74.0) + gitlab-styles (4.2.0) + rubocop (~> 0.82.0) rubocop-gitlab-security (~> 0.1.0) - rubocop-performance (~> 1.4.1) - rubocop-rails (~> 2.0) + rubocop-performance (~> 1.5.2) + rubocop-rails (~> 2.5) rubocop-rspec (~> 1.36) gitlab_chronic_duration (0.10.6.2) numerizer (~> 0.2) @@ -419,23 +419,24 @@ GEM actionpack (>= 3.0) multi_json request_store (>= 1.0) - google-api-client (0.23.4) + google-api-client (0.33.2) addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.5, < 0.7.0) + googleauth (~> 0.9) httpclient (>= 2.8.1, < 3.0) - mime-types (~> 3.0) + mini_mime (~> 1.0) representable (~> 3.0) retriable (>= 2.0, < 4.0) + signet (~> 0.12) google-protobuf (3.8.0) googleapis-common-protos-types (1.0.4) google-protobuf (~> 3.0) - googleauth (0.6.6) - faraday (~> 0.12) + googleauth (0.12.0) + faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) - memoist (~> 0.12) + memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) - signet (~> 0.7) + signet (~> 0.14) gpgme (2.0.20) mini_portile2 (~> 2.3) grape (1.1.0) @@ -529,7 +530,7 @@ GEM mime-types (~> 3.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.8.2) + i18n (1.8.3) concurrent-ruby (~> 1.0) i18n_data (0.8.0) icalendar (2.4.1) @@ -604,7 +605,7 @@ GEM ruby_dep (~> 1.2) locale (2.1.2) lockbox (0.3.3) - lograge (0.10.0) + lograge (0.11.2) actionpack (>= 4) activesupport (>= 4) railties (>= 4) @@ -661,8 +662,8 @@ GEM shellany (~> 0.0) numerizer (0.2.0) oauth (0.5.4) - oauth2 (1.4.1) - faraday (>= 0.8, < 0.16.0) + oauth2 (1.4.4) + faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) @@ -722,13 +723,11 @@ GEM omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) rack - omniauth-ultraauth (0.0.2) - omniauth_openid_connect (~> 0.3.0) omniauth_crowd (2.2.3) activesupport nokogiri (>= 1.4.4) omniauth (~> 1.0) - omniauth_openid_connect (0.3.3) + omniauth_openid_connect (0.3.5) addressable (~> 2.5) omniauth (~> 1.9) openid_connect (~> 1.1) @@ -750,7 +749,7 @@ GEM orm_adapter (0.5.0) os (1.0.0) parallel (1.19.1) - parser (2.7.0.4) + parser (2.7.1.2) ast (~> 2.4.0) parslet (1.8.2) peek (1.1.0) @@ -803,20 +802,20 @@ GEM rack-test (1.1.0) rack (>= 1.0, < 3) rack-timeout (0.5.1) - rails (6.0.3) - actioncable (= 6.0.3) - actionmailbox (= 6.0.3) - actionmailer (= 6.0.3) - actionpack (= 6.0.3) - actiontext (= 6.0.3) - actionview (= 6.0.3) - activejob (= 6.0.3) - activemodel (= 6.0.3) - activerecord (= 6.0.3) - activestorage (= 6.0.3) - activesupport (= 6.0.3) + rails (6.0.3.1) + actioncable (= 6.0.3.1) + actionmailbox (= 6.0.3.1) + actionmailer (= 6.0.3.1) + actionpack (= 6.0.3.1) + actiontext (= 6.0.3.1) + actionview (= 6.0.3.1) + activejob (= 6.0.3.1) + activemodel (= 6.0.3.1) + activerecord (= 6.0.3.1) + activestorage (= 6.0.3.1) + activesupport (= 6.0.3.1) bundler (>= 1.3.0) - railties (= 6.0.3) + railties (= 6.0.3.1) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.4) actionpack (>= 5.0.1.x) @@ -830,9 +829,9 @@ GEM rails-i18n (6.0.0) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 7) - railties (6.0.3) - actionpack (= 6.0.3) - activesupport (= 6.0.3) + railties (6.0.3.1) + actionpack (= 6.0.3.1) + activesupport (= 6.0.3.1) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) @@ -888,6 +887,7 @@ GEM mime-types (>= 1.16, < 4.0) netrc (~> 0.8) retriable (3.1.2) + rexml (3.2.4) rinku (2.0.0) rotp (2.1.2) rouge (3.19.0) @@ -931,18 +931,20 @@ GEM pg rails sqlite3 - rubocop (0.74.0) + rubocop (0.82.0) jaro_winkler (~> 1.5.1) parallel (~> 1.10) - parser (>= 2.6) + parser (>= 2.7.0.1) rainbow (>= 2.2.2, < 4.0) + rexml ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) + unicode-display_width (>= 1.4.0, < 2.0) rubocop-gitlab-security (0.1.1) rubocop (>= 0.51) - rubocop-performance (1.4.1) + rubocop-performance (1.5.2) rubocop (>= 0.71.0) - rubocop-rails (2.4.0) + rubocop-rails (2.5.2) + activesupport rack (>= 1.1) rubocop (>= 0.72.0) rubocop-rspec (1.37.0) @@ -1009,9 +1011,9 @@ GEM sidekiq-cron (1.0.4) fugit (~> 1.1) sidekiq (>= 4.2.1) - signet (0.11.0) + signet (0.14.0) addressable (~> 2.3) - faraday (~> 0.9) + faraday (>= 0.17.3, < 2.0) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) simple_po_parser (1.1.2) @@ -1083,7 +1085,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.5) - unicode-display_width (1.6.0) + unicode-display_width (1.7.0) unicode_plot (0.0.4) enumerable-statistics (>= 2.0.1) unicode_utils (1.4.0) @@ -1113,7 +1115,7 @@ GEM validate_url (1.0.8) activemodel (>= 3.0.0) public_suffix - validates_hostname (1.0.6) + validates_hostname (1.0.10) activerecord (>= 3.0) activesupport (>= 3.0) version_sorter (2.2.4) @@ -1223,7 +1225,7 @@ DEPENDENCIES fog-aliyun (~> 0.3) fog-aws (~> 3.5) fog-core (= 2.1.0) - fog-google (~> 1.9) + fog-google (~> 1.10) fog-local (~> 0.6) fog-openstack (~> 1.0) fog-rackspace (~> 0.1.1) @@ -1234,7 +1236,7 @@ DEPENDENCIES gettext (~> 3.2.2) gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails_js (~> 1.3) - gitaly (~> 13.0.0.pre.rc1) + gitaly (~> 13.1.0.pre.rc1) github-markup (~> 1.7.0) gitlab-chronic (~> 0.10.5) gitlab-labkit (= 0.12.0) @@ -1245,11 +1247,11 @@ DEPENDENCIES gitlab-puma (~> 4.3.3.gitlab.2) gitlab-puma_worker_killer (~> 0.1.1.gitlab.1) gitlab-sidekiq-fetcher (= 0.5.2) - gitlab-styles (~> 3.2.0) + gitlab-styles (~> 4.2.0) gitlab_chronic_duration (~> 0.10.6.2) gitlab_omniauth-ldap (~> 2.1.1) gon (~> 6.2) - google-api-client (~> 0.23) + google-api-client (~> 0.33) google-protobuf (~> 3.8.0) gpgme (~> 2.0.19) grape (~> 1.1.0) @@ -1317,9 +1319,8 @@ DEPENDENCIES omniauth-saml (~> 1.10) omniauth-shibboleth (~> 1.3.0) omniauth-twitter (~> 1.4) - omniauth-ultraauth (~> 0.0.2) omniauth_crowd (~> 2.2.0) - omniauth_openid_connect (~> 0.3.3) + omniauth_openid_connect (~> 0.3.5) org-ruby (~> 0.9.12) parallel (~> 1.19) peek (~> 1.1) @@ -1335,7 +1336,7 @@ DEPENDENCIES rack-oauth2 (~> 1.9.3) rack-proxy (~> 0.6.0) rack-timeout - rails (~> 6.0.3) + rails (~> 6.0.3.1) rails-controller-testing rails-i18n (~> 6.0) rainbow (~> 3.0) @@ -1358,8 +1359,8 @@ DEPENDENCIES rspec-retry (~> 0.6.1) rspec_junit_formatter rspec_profiling (~> 0.0.5) - rubocop (~> 0.74.0) - rubocop-performance (~> 1.4.1) + rubocop (~> 0.82.0) + rubocop-performance (~> 1.5.2) rubocop-rspec (~> 1.37.0) ruby-fogbugz (~> 0.2.1) ruby-prof (~> 1.3.0) @@ -1400,7 +1401,7 @@ DEPENDENCIES unicorn-worker-killer (~> 0.4.4) unleash (~> 0.1.5) valid_email (~> 0.1) - validates_hostname (~> 1.0.6) + validates_hostname (~> 1.0.10) version_sorter (~> 2.2.4) vmstat (~> 2.3.0) webmock (~> 3.5.1) diff --git a/VERSION b/VERSION index 6fe535b5ba..e6ba351366 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -13.0.6 +13.1.0 diff --git a/app/assets/images/aws_logo.svg b/app/assets/images/aws_logo.svg new file mode 100644 index 0000000000..e028fd1b1c --- /dev/null +++ b/app/assets/images/aws_logo.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + diff --git a/app/assets/images/experienced.svg b/app/assets/images/experienced.svg new file mode 100644 index 0000000000..1c93cfcf1e --- /dev/null +++ b/app/assets/images/experienced.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/images/learn-gitlab-avatar.jpg b/app/assets/images/learn-gitlab-avatar.jpg new file mode 100644 index 0000000000..65ec29444c Binary files /dev/null and b/app/assets/images/learn-gitlab-avatar.jpg differ diff --git a/app/assets/images/novice.svg b/app/assets/images/novice.svg new file mode 100644 index 0000000000..c6744fa455 --- /dev/null +++ b/app/assets/images/novice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue index 89db7db77d..ed6b4b7fdb 100644 --- a/app/assets/javascripts/alert_management/components/alert_details.vue +++ b/app/assets/javascripts/alert_management/components/alert_details.vue @@ -2,31 +2,32 @@ import * as Sentry from '@sentry/browser'; import { GlAlert, + GlBadge, GlIcon, GlLoadingIcon, - GlDropdown, - GlDropdownItem, GlSprintf, GlTabs, GlTab, GlButton, GlTable, } from '@gitlab/ui'; -import createFlash from '~/flash'; import { s__ } from '~/locale'; import query from '../graphql/queries/details.query.graphql'; import { fetchPolicies } from '~/lib/graphql'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import { ALERTS_SEVERITY_LABELS } from '../constants'; -import updateAlertStatus from '../graphql/mutations/update_alert_status.graphql'; +import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user'; +import initUserPopovers from '~/user_popovers'; +import { ALERTS_SEVERITY_LABELS, trackAlertsDetailsViewsOptions } from '../constants'; +import createIssueQuery from '../graphql/mutations/create_issue_from_alert.graphql'; +import { visitUrl, joinPaths } from '~/lib/utils/url_utility'; +import Tracking from '~/tracking'; +import { toggleContainerClasses } from '~/lib/utils/dom_utils'; +import SystemNote from './system_notes/system_note.vue'; +import AlertSidebar from './alert_sidebar.vue'; + +const containerEl = document.querySelector('.page-with-contextual-sidebar'); export default { - statuses: { - TRIGGERED: s__('AlertManagement|Triggered'), - ACKNOWLEDGED: s__('AlertManagement|Acknowledged'), - RESOLVED: s__('AlertManagement|Resolved'), - }, i18n: { errorMsg: s__( 'AlertManagement|There was an error displaying the alert. Please refresh the page to try again.', @@ -38,19 +39,19 @@ export default { }, severityLabels: ALERTS_SEVERITY_LABELS, components: { + GlBadge, GlAlert, GlIcon, GlLoadingIcon, GlSprintf, - GlDropdown, - GlDropdownItem, GlTab, GlTabs, GlButton, GlTable, TimeAgoTooltip, + AlertSidebar, + SystemNote, }, - mixins: [glFeatureFlagsMixin()], props: { alertId: { type: String, @@ -60,7 +61,7 @@ export default { type: String, required: true, }, - newIssuePath: { + projectIssuesPath: { type: String, required: true, }, @@ -85,7 +86,15 @@ export default { }, }, data() { - return { alert: null, errored: false, isErrorDismissed: false }; + return { + alert: null, + errored: false, + isErrorDismissed: false, + createIssueError: '', + issueCreationInProgress: false, + sidebarCollapsed: false, + sidebarErrorMessage: '', + }; }, computed: { loading() { @@ -100,38 +109,92 @@ export default { return this.errored && !this.isErrorDismissed; }, }, + mounted() { + this.trackPageViews(); + toggleContainerClasses(containerEl, { + 'issuable-bulk-update-sidebar': true, + 'right-sidebar-expanded': true, + }); + }, + updated() { + this.$nextTick(() => { + highlightCurrentUser(this.$el.querySelectorAll('.gfm-project_member')); + initUserPopovers(this.$el.querySelectorAll('.js-user-link')); + }); + }, methods: { dismissError() { this.isErrorDismissed = true; + this.sidebarErrorMessage = ''; }, - updateAlertStatus(status) { + toggleSidebar() { + this.sidebarCollapsed = !this.sidebarCollapsed; + toggleContainerClasses(containerEl, { + 'right-sidebar-collapsed': this.sidebarCollapsed, + 'right-sidebar-expanded': !this.sidebarCollapsed, + }); + }, + handleAlertSidebarError(errorMessage) { + this.errored = true; + this.sidebarErrorMessage = errorMessage; + }, + createIssue() { + this.issueCreationInProgress = true; + this.$apollo .mutate({ - mutation: updateAlertStatus, + mutation: createIssueQuery, variables: { - iid: this.alertId, - status: status.toUpperCase(), + iid: this.alert.iid, projectPath: this.projectPath, }, }) - .catch(() => { - createFlash( - s__( - 'AlertManagement|There was an error while updating the status of the alert. Please try again.', - ), - ); + .then(({ data: { createAlertIssue: { errors, issue } } }) => { + if (errors?.length) { + [this.createIssueError] = errors; + this.issueCreationInProgress = false; + } else if (issue) { + visitUrl(this.issuePath(issue.iid)); + } + }) + .catch(error => { + this.createIssueError = error; + this.issueCreationInProgress = false; }); }, + issuePath(issueId) { + return joinPaths(this.projectIssuesPath, issueId); + }, + trackPageViews() { + const { category, action } = trackAlertsDetailsViewsOptions; + Tracking.event(category, action); + }, + alertRefresh() { + this.$apollo.queries.alert.refetch(); + }, }, }; + diff --git a/app/assets/javascripts/alert_management/components/alert_management_list.vue b/app/assets/javascripts/alert_management/components/alert_management_list.vue index 74fc19ff3d..37901c21f9 100644 --- a/app/assets/javascripts/alert_management/components/alert_management_list.vue +++ b/app/assets/javascripts/alert_management/components/alert_management_list.vue @@ -10,23 +10,41 @@ import { GlDropdownItem, GlTabs, GlTab, + GlBadge, + GlPagination, } from '@gitlab/ui'; import createFlash from '~/flash'; import { s__ } from '~/locale'; import { joinPaths, visitUrl } from '~/lib/utils/url_utility'; +import { fetchPolicies } from '~/lib/graphql'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; -import getAlerts from '../graphql/queries/getAlerts.query.graphql'; -import { ALERTS_STATUS, ALERTS_STATUS_TABS, ALERTS_SEVERITY_LABELS } from '../constants'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import getAlerts from '../graphql/queries/get_alerts.query.graphql'; +import getAlertsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql'; +import { + ALERTS_STATUS_TABS, + ALERTS_SEVERITY_LABELS, + DEFAULT_PAGE_SIZE, + trackAlertListViewsOptions, + trackAlertStatusUpdateOptions, +} from '../constants'; import updateAlertStatus from '../graphql/mutations/update_alert_status.graphql'; -import { capitalizeFirstCharacter } from '~/lib/utils/text_utility'; +import { convertToSnakeCase } from '~/lib/utils/text_utility'; +import Tracking from '~/tracking'; -const tdClass = 'table-col d-flex d-md-table-cell align-items-center'; +const tdClass = 'table-col gl-display-flex d-md-table-cell gl-align-items-center'; +const thClass = 'gl-hover-bg-blue-50'; const bodyTrClass = - 'gl-border-1 gl-border-t-solid gl-border-gray-100 hover-bg-blue-50 hover-gl-cursor-pointer hover-gl-border-b-solid hover-gl-border-blue-200'; + 'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-bg-blue-50 gl-hover-cursor-pointer gl-hover-border-b-solid gl-hover-border-blue-200'; + +const initialPaginationState = { + currentPage: 1, + prevPageCursor: '', + nextPageCursor: '', + firstPageSize: DEFAULT_PAGE_SIZE, + lastPageSize: null, +}; export default { - bodyTrClass, i18n: { noAlertsMsg: s__( "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page.", @@ -40,40 +58,54 @@ export default { key: 'severity', label: s__('AlertManagement|Severity'), tdClass: `${tdClass} rounded-top text-capitalize`, + thClass, + sortable: true, }, { key: 'startedAt', label: s__('AlertManagement|Start time'), + thClass: `${thClass} js-started-at`, tdClass, + sortable: true, }, { key: 'endedAt', label: s__('AlertManagement|End time'), + thClass, tdClass, + sortable: true, }, { key: 'title', label: s__('AlertManagement|Alert'), - thClass: 'w-30p', + thClass: `${thClass} w-30p gl-pointer-events-none`, tdClass, + sortable: false, }, { key: 'eventCount', label: s__('AlertManagement|Events'), - thClass: 'text-right event-count', - tdClass: `${tdClass} text-md-right event-count`, + thClass: `${thClass} text-right gl-pr-9 w-3rem`, + tdClass: `${tdClass} text-md-right`, + sortable: true, + }, + { + key: 'assignees', + label: s__('AlertManagement|Assignees'), + tdClass, }, { key: 'status', - thClass: 'w-15p', + thClass: `${thClass} w-15p`, label: s__('AlertManagement|Status'), tdClass: `${tdClass} rounded-bottom`, + sortable: true, }, ], statuses: { - [ALERTS_STATUS.TRIGGERED]: s__('AlertManagement|Triggered'), - [ALERTS_STATUS.ACKNOWLEDGED]: s__('AlertManagement|Acknowledged'), - [ALERTS_STATUS.RESOLVED]: s__('AlertManagement|Resolved'), + TRIGGERED: s__('AlertManagement|Triggered'), + ACKNOWLEDGED: s__('AlertManagement|Acknowledged'), + RESOLVED: s__('AlertManagement|Resolved'), }, severityLabels: ALERTS_SEVERITY_LABELS, statusTabs: ALERTS_STATUS_TABS, @@ -89,8 +121,9 @@ export default { GlIcon, GlTabs, GlTab, + GlBadge, + GlPagination, }, - mixins: [glFeatureFlagsMixin()], props: { projectPath: { type: String, @@ -115,33 +148,63 @@ export default { }, apollo: { alerts: { + fetchPolicy: fetchPolicies.CACHE_AND_NETWORK, query: getAlerts, variables() { return { projectPath: this.projectPath, statuses: this.statusFilter, + sort: this.sort, + firstPageSize: this.pagination.firstPageSize, + lastPageSize: this.pagination.lastPageSize, + prevPageCursor: this.pagination.prevPageCursor, + nextPageCursor: this.pagination.nextPageCursor, }; }, update(data) { - return data.project.alertManagementAlerts.nodes; + const { alertManagementAlerts: { nodes: list = [], pageInfo = {} } = {} } = + data.project || {}; + + return { + list, + pageInfo, + }; }, error() { this.errored = true; }, }, + alertsCount: { + query: getAlertsCountByStatus, + variables() { + return { + projectPath: this.projectPath, + }; + }, + update(data) { + return data.project?.alertManagementAlertStatusCounts; + }, + }, }, data() { return { - alerts: null, errored: false, isAlertDismissed: false, isErrorAlertDismissed: false, - statusFilter: this.$options.statusTabs[4].filters, + sort: 'STARTED_AT_DESC', + statusFilter: [], + filteredByStatus: '', + pagination: initialPaginationState, + sortBy: 'startedAt', + sortDesc: true, + sortDirection: 'desc', }; }, computed: { showNoAlertsMsg() { - return !this.errored && !this.loading && !this.alerts?.length && !this.isAlertDismissed; + return ( + !this.errored && !this.loading && this.alertsCount?.all === 0 && !this.isAlertDismissed + ); }, showErrorMsg() { return this.errored && !this.isErrorAlertDismissed; @@ -149,12 +212,43 @@ export default { loading() { return this.$apollo.queries.alerts.loading; }, + hasAlerts() { + return this.alerts?.list?.length; + }, + tbodyTrClass() { + return !this.loading && this.hasAlerts ? bodyTrClass : ''; + }, + 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: { filterAlertsByStatus(tabIndex) { - this.statusFilter = this.$options.statusTabs[tabIndex].filters; + this.resetPagination(); + const { filters, status } = this.$options.statusTabs[tabIndex]; + this.statusFilter = filters; + this.filteredByStatus = status; + }, + fetchSortedData({ sortBy, sortDesc }) { + const sortingDirection = sortDesc ? 'DESC' : 'ASC'; + const sortingColumn = convertToSnakeCase(sortBy).toUpperCase(); + + this.resetPagination(); + this.sort = `${sortingColumn}_${sortingDirection}`; }, - capitalizeFirstCharacter, updateAlertStatus(status, iid) { this.$apollo .mutate({ @@ -166,7 +260,10 @@ export default { }, }) .then(() => { + this.trackStatusUpdate(status); this.$apollo.queries.alerts.refetch(); + this.$apollo.queries.alertsCount.refetch(); + this.resetPagination(); }) .catch(() => { createFlash( @@ -179,6 +276,42 @@ export default { 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 }); + }, + getAssignees(assignees) { + // TODO: Update to show list of assignee(s) after https://gitlab.com/gitlab-org/gitlab/-/issues/218405 + return assignees.nodes?.length > 0 + ? assignees.nodes[0]?.username + : s__('AlertManagement|Unassigned'); + }, + 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; + }, }, }; @@ -192,10 +325,13 @@ export default { {{ $options.i18n.errorMsg }} - + @@ -205,13 +341,19 @@ export default { + + + + + + +import SidebarHeader from './sidebar/sidebar_header.vue'; +import SidebarTodo from './sidebar/sidebar_todo.vue'; +import SidebarStatus from './sidebar/sidebar_status.vue'; +import SidebarAssignees from './sidebar/sidebar_assignees.vue'; + +export default { + components: { + SidebarAssignees, + SidebarHeader, + SidebarTodo, + SidebarStatus, + }, + props: { + sidebarCollapsed: { + type: Boolean, + required: true, + }, + projectPath: { + type: String, + required: true, + }, + alert: { + type: Object, + required: true, + }, + }, + computed: { + sidebarCollapsedClass() { + return this.sidebarCollapsed ? 'right-sidebar-collapsed' : 'right-sidebar-expanded'; + }, + }, +}; + + + diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue new file mode 100644 index 0000000000..df07038151 --- /dev/null +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue @@ -0,0 +1,51 @@ + + + diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue new file mode 100644 index 0000000000..453a390166 --- /dev/null +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue @@ -0,0 +1,278 @@ + + + diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue new file mode 100644 index 0000000000..047793d8ce --- /dev/null +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue @@ -0,0 +1,34 @@ + + + diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue new file mode 100644 index 0000000000..89dbbedd9c --- /dev/null +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue @@ -0,0 +1,189 @@ + + + diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue new file mode 100644 index 0000000000..87090165f8 --- /dev/null +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue @@ -0,0 +1,29 @@ + + + + diff --git a/app/assets/javascripts/alert_management/components/system_notes/system_note.vue b/app/assets/javascripts/alert_management/components/system_notes/system_note.vue new file mode 100644 index 0000000000..9042d51aec --- /dev/null +++ b/app/assets/javascripts/alert_management/components/system_notes/system_note.vue @@ -0,0 +1,46 @@ + + + diff --git a/app/assets/javascripts/alert_management/constants.js b/app/assets/javascripts/alert_management/constants.js index 9df01d9d0b..b9670466c0 100644 --- a/app/assets/javascripts/alert_management/constants.js +++ b/app/assets/javascripts/alert_management/constants.js @@ -9,38 +9,59 @@ export const ALERTS_SEVERITY_LABELS = { UNKNOWN: s__('AlertManagement|Unknown'), }; -export const ALERTS_STATUS = { - OPEN: 'OPEN', - TRIGGERED: 'TRIGGERED', - ACKNOWLEDGED: 'ACKNOWLEDGED', - RESOLVED: 'RESOLVED', - ALL: 'ALL', -}; - export const ALERTS_STATUS_TABS = [ { title: s__('AlertManagement|Open'), - status: ALERTS_STATUS.OPEN, - filters: [ALERTS_STATUS.TRIGGERED, ALERTS_STATUS.ACKNOWLEDGED], + status: 'OPEN', + filters: ['TRIGGERED', 'ACKNOWLEDGED'], }, { title: s__('AlertManagement|Triggered'), - status: ALERTS_STATUS.TRIGGERED, - filters: [ALERTS_STATUS.TRIGGERED], + status: 'TRIGGERED', + filters: 'TRIGGERED', }, { title: s__('AlertManagement|Acknowledged'), - status: ALERTS_STATUS.ACKNOWLEDGED, - filters: [ALERTS_STATUS.ACKNOWLEDGED], + status: 'ACKNOWLEDGED', + filters: 'ACKNOWLEDGED', }, { title: s__('AlertManagement|Resolved'), - status: ALERTS_STATUS.RESOLVED, - filters: [ALERTS_STATUS.RESOLVED], + status: 'RESOLVED', + filters: 'RESOLVED', }, { title: s__('AlertManagement|All alerts'), - status: ALERTS_STATUS.ALL, - filters: [ALERTS_STATUS.TRIGGERED, ALERTS_STATUS.ACKNOWLEDGED, ALERTS_STATUS.RESOLVED], + status: 'ALL', + filters: ['TRIGGERED', 'ACKNOWLEDGED', 'RESOLVED'], }, ]; + +/* eslint-disable @gitlab/require-i18n-strings */ + +/** + * Tracks snowplow event when user views alerts list + */ +export const trackAlertListViewsOptions = { + category: 'Alert Management', + action: 'view_alerts_list', +}; + +/** + * Tracks snowplow event when user views alert details + */ +export const trackAlertsDetailsViewsOptions = { + category: 'Alert Management', + action: 'view_alert_details', +}; + +/** + * Tracks snowplow event when alert status is updated + */ +export const trackAlertStatusUpdateOptions = { + category: 'Alert Management', + action: 'update_alert_status', + label: 'Status', +}; + +export const DEFAULT_PAGE_SIZE = 10; diff --git a/app/assets/javascripts/alert_management/details.js b/app/assets/javascripts/alert_management/details.js index d3523e0a29..aa8a839ea3 100644 --- a/app/assets/javascripts/alert_management/details.js +++ b/app/assets/javascripts/alert_management/details.js @@ -8,7 +8,7 @@ Vue.use(VueApollo); export default selector => { const domEl = document.querySelector(selector); - const { alertId, projectPath, newIssuePath } = domEl.dataset; + const { alertId, projectPath, projectIssuesPath } = domEl.dataset; const apolloProvider = new VueApollo({ defaultClient: createDefaultClient( @@ -39,7 +39,7 @@ export default selector => { props: { alertId, projectPath, - newIssuePath, + projectIssuesPath, }, }); }, diff --git a/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql new file mode 100644 index 0000000000..c72300e975 --- /dev/null +++ b/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql @@ -0,0 +1,16 @@ +#import "~/graphql_shared/fragments/author.fragment.graphql" + +fragment AlertNote on Note { + id + author { + id + state + ...Author + } + body + bodyHtml + createdAt + discussion { + id + } +} diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql similarity index 53% rename from app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql rename to app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql index df802616e9..cbe7e169be 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql +++ b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql @@ -1,4 +1,5 @@ -#import "./listItem.fragment.graphql" +#import "./list_item.fragment.graphql" +#import "./alert_note.fragment.graphql" fragment AlertDetailItem on AlertManagementAlert { ...AlertListItem @@ -8,4 +9,9 @@ fragment AlertDetailItem on AlertManagementAlert { description updatedAt details + notes { + nodes { + ...AlertNote + } + } } diff --git a/app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql similarity index 65% rename from app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql rename to app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql index fffe07b0cf..746c4435f3 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql +++ b/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql @@ -6,4 +6,10 @@ fragment AlertListItem on AlertManagementAlert { startedAt endedAt eventCount + issueIid + assignees { + nodes { + username + } + } } diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql new file mode 100644 index 0000000000..efeaf8fa37 --- /dev/null +++ b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql @@ -0,0 +1,15 @@ +mutation($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) { + alertSetAssignees( + input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath } + ) { + errors + alert { + iid + assignees { + nodes { + username + } + } + } + } +} diff --git a/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql b/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql new file mode 100644 index 0000000000..664596ab88 --- /dev/null +++ b/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql @@ -0,0 +1,8 @@ +mutation ($projectPath: ID!, $iid: String!) { + createAlertIssue(input: { iid: $iid, projectPath: $projectPath }) { + errors + issue { + iid + } + } +} diff --git a/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql b/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql index 009ae0b293..09151f233f 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql +++ b/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql @@ -4,6 +4,7 @@ mutation ($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) { alert { iid, status, + endedAt } } } diff --git a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql index 7c77715fad..c02b8accdd 100644 --- a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql +++ b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql @@ -1,4 +1,4 @@ -#import "../fragments/detailItem.fragment.graphql" +#import "../fragments/detail_item.fragment.graphql" query alertDetails($fullPath: ID!, $alertId: String) { project(fullPath: $fullPath) { diff --git a/app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql deleted file mode 100644 index 54b66389d5..0000000000 --- a/app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql +++ /dev/null @@ -1,11 +0,0 @@ -#import "../fragments/listItem.fragment.graphql" - -query getAlerts($projectPath: ID!, $statuses: [AlertManagementStatus!]) { - project(fullPath: $projectPath) { - alertManagementAlerts(statuses: $statuses) { - nodes { - ...AlertListItem - } - } - } -} diff --git a/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql new file mode 100644 index 0000000000..1d3c3c83cc --- /dev/null +++ b/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql @@ -0,0 +1,32 @@ +#import "../fragments/list_item.fragment.graphql" + +query getAlerts( + $projectPath: ID!, + $statuses: [AlertManagementStatus!], + $sort: AlertManagementAlertSort, + $firstPageSize: Int, + $lastPageSize: Int, + $prevPageCursor: String = "" + $nextPageCursor: String = "" +) { + project(fullPath: $projectPath, ) { + alertManagementAlerts( + statuses: $statuses, + sort: $sort, + first: $firstPageSize + last: $lastPageSize, + after: $nextPageCursor, + before: $prevPageCursor + ) { + nodes { + ...AlertListItem + }, + pageInfo { + hasNextPage + endCursor + hasPreviousPage + startCursor + } + } + } +} diff --git a/app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql new file mode 100644 index 0000000000..1143050200 --- /dev/null +++ b/app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql @@ -0,0 +1,11 @@ +query getAlertsCount($projectPath: ID!) { + project(fullPath: $projectPath) { + alertManagementAlertStatusCounts { + all + open + acknowledged + resolved + triggered + } + } +} diff --git a/app/assets/javascripts/alert_management/services/index.js b/app/assets/javascripts/alert_management/services/index.js deleted file mode 100644 index 787603d3e7..0000000000 --- a/app/assets/javascripts/alert_management/services/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import axios from '~/lib/utils/axios_utils'; - -export default { - getAlertManagementList({ endpoint }) { - return axios.get(endpoint); - }, -}; diff --git a/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue b/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue index 410c5c00e8..ac30b08687 100644 --- a/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue +++ b/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue @@ -1,26 +1,37 @@ + + diff --git a/app/assets/javascripts/batch_comments/components/draft_note.vue b/app/assets/javascripts/batch_comments/components/draft_note.vue new file mode 100644 index 0000000000..963d104b6b --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/draft_note.vue @@ -0,0 +1,113 @@ + + diff --git a/app/assets/javascripts/batch_comments/components/drafts_count.vue b/app/assets/javascripts/batch_comments/components/drafts_count.vue new file mode 100644 index 0000000000..f1180760c4 --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/drafts_count.vue @@ -0,0 +1,15 @@ + + diff --git a/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue b/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue new file mode 100644 index 0000000000..385725cd10 --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue @@ -0,0 +1,32 @@ + + + diff --git a/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue b/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue new file mode 100644 index 0000000000..68fd20e56b --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue @@ -0,0 +1,45 @@ + + + diff --git a/app/assets/javascripts/batch_comments/components/preview_dropdown.vue b/app/assets/javascripts/batch_comments/components/preview_dropdown.vue new file mode 100644 index 0000000000..195e1b7ec5 --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/preview_dropdown.vue @@ -0,0 +1,111 @@ + + + diff --git a/app/assets/javascripts/batch_comments/components/preview_item.vue b/app/assets/javascripts/batch_comments/components/preview_item.vue new file mode 100644 index 0000000000..22495eb4d7 --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/preview_item.vue @@ -0,0 +1,143 @@ + + + diff --git a/app/assets/javascripts/batch_comments/components/publish_button.vue b/app/assets/javascripts/batch_comments/components/publish_button.vue new file mode 100644 index 0000000000..f4dc0f04dc --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/publish_button.vue @@ -0,0 +1,55 @@ + + + diff --git a/app/assets/javascripts/batch_comments/components/review_bar.vue b/app/assets/javascripts/batch_comments/components/review_bar.vue new file mode 100644 index 0000000000..b0e8b80670 --- /dev/null +++ b/app/assets/javascripts/batch_comments/components/review_bar.vue @@ -0,0 +1,70 @@ + + diff --git a/app/assets/javascripts/batch_comments/constants.js b/app/assets/javascripts/batch_comments/constants.js new file mode 100644 index 0000000000..b309c339fc --- /dev/null +++ b/app/assets/javascripts/batch_comments/constants.js @@ -0,0 +1,3 @@ +export const CHANGES_TAB = 'diffs'; +export const DISCUSSION_TAB = 'notes'; +export const SHOW_TAB = 'show'; diff --git a/app/assets/javascripts/batch_comments/index.js b/app/assets/javascripts/batch_comments/index.js new file mode 100644 index 0000000000..e06285c0b3 --- /dev/null +++ b/app/assets/javascripts/batch_comments/index.js @@ -0,0 +1,24 @@ +import Vue from 'vue'; +import { mapActions } from 'vuex'; +import store from '~/mr_notes/stores'; +import ReviewBar from './components/review_bar.vue'; + +// eslint-disable-next-line import/prefer-default-export +export const initReviewBar = () => { + const el = document.getElementById('js-review-bar'); + + // eslint-disable-next-line no-new + new Vue({ + el, + store, + mounted() { + this.fetchDrafts(); + }, + methods: { + ...mapActions('batchComments', ['fetchDrafts']), + }, + render(createElement) { + return createElement(ReviewBar); + }, + }); +}; diff --git a/app/assets/javascripts/batch_comments/mixins/resolved_status.js b/app/assets/javascripts/batch_comments/mixins/resolved_status.js index 3bbbaa86b5..2517fb198f 100644 --- a/app/assets/javascripts/batch_comments/mixins/resolved_status.js +++ b/app/assets/javascripts/batch_comments/mixins/resolved_status.js @@ -1,9 +1,58 @@ -import { sprintf, __ } from '~/locale'; +import { mapGetters } from 'vuex'; +import { sprintf, s__, __ } from '~/locale'; export default { + props: { + discussionId: { + type: String, + required: false, + default: null, + }, + resolveDiscussion: { + type: Boolean, + required: false, + default: false, + }, + isDraft: { + type: Boolean, + required: false, + default: false, + }, + }, computed: { + ...mapGetters(['isDiscussionResolved']), + resolvedStatusMessage() { + let message; + const discussionResolved = this.isDiscussionResolved( + this.draft ? this.draft.discussion_id : this.discussionId, + ); + const discussionToBeResolved = this.draft + ? this.draft.resolve_discussion + : this.resolveDiscussion; + + if (discussionToBeResolved && discussionResolved && !this.$options.showStaysResolved) { + return undefined; + } + + if (discussionToBeResolved) { + message = discussionResolved + ? s__('MergeRequests|Thread stays resolved') + : s__('MergeRequests|Thread will be resolved'); + } else if (discussionResolved) { + message = s__('MergeRequests|Thread will be unresolved'); + } else if (this.$options.showStaysResolved) { + message = s__('MergeRequests|Thread stays unresolved'); + } + + return message; + }, + componentClasses() { + return this.resolveDiscussion ? 'is-resolving-discussion' : 'is-unresolving-discussion'; + }, resolveButtonTitle() { - let title = __('Mark comment as resolved'); + if (this.isDraft || this.discussionId) return this.resolvedStatusMessage; + + let title = __('Mark as resolved'); if (this.resolvedBy) { title = sprintf(__('Resolved by %{name}'), { name: this.resolvedBy.name }); @@ -12,4 +61,5 @@ export default { return title; }, }, + showStaysResolved: true, }; diff --git a/app/assets/javascripts/batch_comments/services/drafts_service.js b/app/assets/javascripts/batch_comments/services/drafts_service.js new file mode 100644 index 0000000000..36d2f8df61 --- /dev/null +++ b/app/assets/javascripts/batch_comments/services/drafts_service.js @@ -0,0 +1,33 @@ +import axios from '~/lib/utils/axios_utils'; + +export default { + createNewDraft(endpoint, data) { + const postData = { ...data, draft_note: data.note }; + delete postData.note; + + return axios.post(endpoint, postData); + }, + deleteDraft(endpoint, draftId) { + return axios.delete(`${endpoint}/${draftId}`); + }, + publishDraft(endpoint, draftId) { + return axios.post(endpoint, { id: draftId }); + }, + addDraftToDiscussion(endpoint, data) { + return axios.post(endpoint, data); + }, + fetchDrafts(endpoint) { + return axios.get(endpoint); + }, + publish(endpoint) { + return axios.post(endpoint); + }, + discard(endpoint) { + return axios.delete(endpoint); + }, + update(endpoint, { draftId, note, resolveDiscussion, position }) { + return axios.put(`${endpoint}/${draftId}`, { + draft_note: { note, resolve_discussion: resolveDiscussion, position }, + }); + }, +}; diff --git a/app/assets/javascripts/batch_comments/stores/index.js b/app/assets/javascripts/batch_comments/stores/index.js new file mode 100644 index 0000000000..08dc9ea70f --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/index.js @@ -0,0 +1,14 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import batchComments from './modules/batch_comments'; + +Vue.use(Vuex); + +export const createStore = () => + new Vuex.Store({ + modules: { + batchComments: batchComments(), + }, + }); + +export default createStore(); diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js new file mode 100644 index 0000000000..1ef012696c --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js @@ -0,0 +1,151 @@ +import flash from '~/flash'; +import { __ } from '~/locale'; +import { scrollToElement } from '~/lib/utils/common_utils'; +import service from '../../../services/drafts_service'; +import * as types from './mutation_types'; +import { CHANGES_TAB, DISCUSSION_TAB, SHOW_TAB } from '../../../constants'; + +export const saveDraft = ({ dispatch }, draft) => + dispatch('saveNote', { ...draft, isDraft: true }, { root: true }); + +export const addDraftToDiscussion = ({ commit }, { endpoint, data }) => + service + .addDraftToDiscussion(endpoint, data) + .then(res => res.data) + .then(res => { + commit(types.ADD_NEW_DRAFT, res); + return res; + }) + .catch(() => { + flash(__('An error occurred adding a draft to the thread.')); + }); + +export const createNewDraft = ({ commit }, { endpoint, data }) => + service + .createNewDraft(endpoint, data) + .then(res => res.data) + .then(res => { + commit(types.ADD_NEW_DRAFT, res); + return res; + }) + .catch(() => { + flash(__('An error occurred adding a new draft.')); + }); + +export const deleteDraft = ({ commit, getters }, draft) => + service + .deleteDraft(getters.getNotesData.draftsPath, draft.id) + .then(() => { + commit(types.DELETE_DRAFT, draft.id); + }) + .catch(() => flash(__('An error occurred while deleting the comment'))); + +export const fetchDrafts = ({ commit, getters }) => + service + .fetchDrafts(getters.getNotesData.draftsPath) + .then(res => res.data) + .then(data => commit(types.SET_BATCH_COMMENTS_DRAFTS, data)) + .catch(() => flash(__('An error occurred while fetching pending comments'))); + +export const publishSingleDraft = ({ commit, dispatch, getters }, draftId) => { + commit(types.REQUEST_PUBLISH_DRAFT, draftId); + + service + .publishDraft(getters.getNotesData.draftsPublishPath, draftId) + .then(() => dispatch('updateDiscussionsAfterPublish')) + .then(() => commit(types.RECEIVE_PUBLISH_DRAFT_SUCCESS, draftId)) + .catch(() => commit(types.RECEIVE_PUBLISH_DRAFT_ERROR, draftId)); +}; + +export const publishReview = ({ commit, dispatch, getters }) => { + commit(types.REQUEST_PUBLISH_REVIEW); + + return service + .publish(getters.getNotesData.draftsPublishPath) + .then(() => dispatch('updateDiscussionsAfterPublish')) + .then(() => commit(types.RECEIVE_PUBLISH_REVIEW_SUCCESS)) + .catch(() => commit(types.RECEIVE_PUBLISH_REVIEW_ERROR)); +}; + +export const updateDiscussionsAfterPublish = ({ dispatch, getters, rootGetters }) => + dispatch('fetchDiscussions', { path: getters.getNotesData.discussionsPath }, { root: true }).then( + () => + dispatch('diffs/assignDiscussionsToDiff', rootGetters.discussionsStructuredByLineCode, { + root: true, + }), + ); + +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 = ( + { commit, getters }, + { note, noteText, resolveDiscussion, position, callback }, +) => + service + .update(getters.getNotesData.draftsPath, { + draftId: note.id, + note: noteText, + resolveDiscussion, + position: JSON.stringify(position), + }) + .then(res => res.data) + .then(data => commit(types.RECEIVE_DRAFT_UPDATE_SUCCESS, data)) + .then(callback) + .catch(() => flash(__('An error occurred while updating the comment'))); + +export const scrollToDraft = ({ dispatch, rootGetters }, draft) => { + const discussion = draft.discussion_id && rootGetters.getDiscussion(draft.discussion_id); + const tab = + draft.file_hash || (discussion && discussion.diff_discussion) ? CHANGES_TAB : SHOW_TAB; + const tabEl = tab === CHANGES_TAB ? CHANGES_TAB : DISCUSSION_TAB; + const draftID = `note_${draft.id}`; + const el = document.querySelector(`#${tabEl} #${draftID}`); + + dispatch('closeReviewDropdown'); + + window.location.hash = draftID; + + if (window.mrTabs.currentAction !== tab) { + window.mrTabs.tabShown(tab); + } + + if (discussion) { + dispatch('expandDiscussion', { discussionId: discussion.id }, { root: true }); + } + + if (el) { + setTimeout(() => scrollToElement(el.closest('.draft-note-component'))); + } +}; + +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 }) => + state.drafts + .filter(draft => draft.discussion_id) + .forEach(draft => { + dispatch('expandDiscussion', { discussionId: draft.discussion_id }, { root: true }); + }); + +export const toggleResolveDiscussion = ({ commit }, draftId) => { + commit(types.TOGGLE_RESOLVE_DISCUSSION, draftId); +}; + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js new file mode 100644 index 0000000000..43f43c983a --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js @@ -0,0 +1,87 @@ +import { parallelLineKey, showDraftOnSide } from '../../../utils'; + +export const draftsCount = state => state.drafts.length; + +export const getNotesData = (state, getters, rootState, rootGetters) => rootGetters.getNotesData; + +export const hasDrafts = state => state.drafts.length > 0; + +export const draftsPerDiscussionId = state => + state.drafts.reduce((acc, draft) => { + if (draft.discussion_id) { + acc[draft.discussion_id] = draft; + } + + return acc; + }, {}); + +export const draftsPerFileHashAndLine = state => + state.drafts.reduce((acc, draft) => { + if (draft.file_hash) { + if (!acc[draft.file_hash]) { + acc[draft.file_hash] = {}; + } + + acc[draft.file_hash][draft.line_code] = draft; + } + + return acc; + }, {}); + +export const shouldRenderDraftRow = (state, getters) => (diffFileSha, line) => + Boolean( + diffFileSha in getters.draftsPerFileHashAndLine && + getters.draftsPerFileHashAndLine[diffFileSha][line.line_code], + ); + +export const shouldRenderParallelDraftRow = (state, getters) => (diffFileSha, line) => { + const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha]; + const [lkey, rkey] = [parallelLineKey(line, 'left'), parallelLineKey(line, 'right')]; + + return draftsForFile ? Boolean(draftsForFile[lkey] || draftsForFile[rkey]) : false; +}; + +export const hasParallelDraftLeft = (state, getters) => (diffFileSha, line) => { + const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha]; + const lkey = parallelLineKey(line, 'left'); + + return draftsForFile ? Boolean(draftsForFile[lkey]) : false; +}; + +export const hasParallelDraftRight = (state, getters) => (diffFileSha, line) => { + const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha]; + const rkey = parallelLineKey(line, 'left'); + + return draftsForFile ? Boolean(draftsForFile[rkey]) : false; +}; + +export const shouldRenderDraftRowInDiscussion = (state, getters) => discussionId => + typeof getters.draftsPerDiscussionId[discussionId] !== 'undefined'; + +export const draftForDiscussion = (state, getters) => discussionId => + getters.draftsPerDiscussionId[discussionId] || {}; + +export const draftForLine = (state, getters) => (diffFileSha, line, side = null) => { + const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha]; + + const key = side !== null ? parallelLineKey(line, side) : line.line_code; + + if (draftsForFile) { + const draft = draftsForFile[key]; + if (draft && showDraftOnSide(line, side)) { + return draft; + } + } + return {}; +}; + +export const draftsForFile = state => diffFileSha => + state.drafts.filter(draft => draft.file_hash === diffFileSha); + +export const isPublishingDraft = state => draftId => + state.currentlyPublishingDrafts.indexOf(draftId) !== -1; + +export const sortedDrafts = state => [...state.drafts].sort((a, b) => a.id > b.id); + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js new file mode 100644 index 0000000000..81dab0566c --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import mutations from './mutations'; +import * as actions from './actions'; +import * as getters from './getters'; + +export default () => ({ + namespaced: true, + state: state(), + mutations, + actions, + getters, +}); diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js new file mode 100644 index 0000000000..c8f0658c21 --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js @@ -0,0 +1,23 @@ +export const ENABLE_BATCH_COMMENTS = 'ENABLE_BATCH_COMMENTS'; +export const ADD_NEW_DRAFT = 'ADD_NEW_DRAFT'; +export const DELETE_DRAFT = 'DELETE_DRAFT'; +export const SET_BATCH_COMMENTS_DRAFTS = 'SET_BATCH_COMMENTS_DRAFTS'; + +export const REQUEST_PUBLISH_DRAFT = 'REQUEST_PUBLISH_DRAFT'; +export const RECEIVE_PUBLISH_DRAFT_SUCCESS = 'RECEIVE_PUBLISH_DRAFT_SUCCESS'; +export const RECEIVE_PUBLISH_DRAFT_ERROR = 'RECEIVE_PUBLISH_DRAFT_ERROR'; + +export const REQUEST_PUBLISH_REVIEW = 'REQUEST_PUBLISH_REVIEW'; +export const RECEIVE_PUBLISH_REVIEW_SUCCESS = 'RECEIVE_PUBLISH_REVIEW_SUCCESS'; +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 OPEN_REVIEW_DROPDOWN = 'OPEN_REVIEW_DROPDOWN'; +export const CLOSE_REVIEW_DROPDOWN = 'CLOSE_REVIEW_DROPDOWN'; + +export const TOGGLE_RESOLVE_DISCUSSION = 'TOGGLE_RESOLVE_DISCUSSION'; diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js new file mode 100644 index 0000000000..81ceef7b16 --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js @@ -0,0 +1,81 @@ +import * as types from './mutation_types'; + +const processDraft = draft => ({ + ...draft, + isDraft: true, +}); + +export default { + [types.ADD_NEW_DRAFT](state, draft) { + state.drafts.push(processDraft(draft)); + }, + + [types.DELETE_DRAFT](state, draftId) { + state.drafts = state.drafts.filter(draft => draft.id !== draftId); + }, + + [types.SET_BATCH_COMMENTS_DRAFTS](state, drafts) { + state.drafts = drafts.map(processDraft); + }, + + [types.REQUEST_PUBLISH_DRAFT](state, draftId) { + state.currentlyPublishingDrafts.push(draftId); + }, + [types.RECEIVE_PUBLISH_DRAFT_SUCCESS](state, draftId) { + state.currentlyPublishingDrafts = state.currentlyPublishingDrafts.filter( + publishingDraftId => publishingDraftId !== draftId, + ); + state.drafts = state.drafts.filter(d => d.id !== draftId); + }, + [types.RECEIVE_PUBLISH_DRAFT_ERROR](state, draftId) { + state.currentlyPublishingDrafts = state.currentlyPublishingDrafts.filter( + publishingDraftId => publishingDraftId !== draftId, + ); + }, + + [types.REQUEST_PUBLISH_REVIEW](state) { + state.isPublishing = true; + }, + [types.RECEIVE_PUBLISH_REVIEW_SUCCESS](state) { + state.isPublishing = false; + state.drafts = []; + }, + [types.RECEIVE_PUBLISH_REVIEW_ERROR](state) { + 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) { + const index = state.drafts.findIndex(draft => draft.id === data.id); + + if (index >= 0) { + 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) { + state.drafts = state.drafts.map(draft => { + if (draft.id === draftId) { + return { + ...draft, + resolve_discussion: !draft.resolve_discussion, + }; + } + + return draft; + }); + }, +}; diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js new file mode 100644 index 0000000000..80c710deab --- /dev/null +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js @@ -0,0 +1,9 @@ +export default () => ({ + withBatchComments: true, + isDraftsFetched: false, + drafts: [], + isPublishing: false, + currentlyPublishingDrafts: [], + isDiscarding: false, + showPreviewDropdown: false, +}); diff --git a/app/assets/javascripts/batch_comments/utils.js b/app/assets/javascripts/batch_comments/utils.js new file mode 100644 index 0000000000..cf4f7af0eb --- /dev/null +++ b/app/assets/javascripts/batch_comments/utils.js @@ -0,0 +1,35 @@ +import { getFormData } from '~/diffs/store/utils'; + +export const getDraftReplyFormData = data => ({ + endpoint: data.notesData.draftsPath, + data, +}); + +export const getDraftFormData = params => ({ + endpoint: params.notesData.draftsPath, + data: getFormData(params), +}); + +export const parallelLineKey = (line, side) => (line[side] ? line[side].line_code : ''); + +export const showDraftOnSide = (line, side) => { + // inline mode + if (side === null) { + return true; + } + + // parallel + if (side === 'left' || side === 'right') { + const otherSide = side === 'left' ? 'right' : 'left'; + const thisCode = (line[side] && line[side].line_code) || ''; + const otherCode = (line[otherSide] && line[otherSide].line_code) || ''; + + // either the lineCodes are different + // or if they're the same, only show on the left side + if (thisCode !== otherCode || (side === 'left' && thisCode === otherCode)) { + return true; + } + } + + return false; +}; diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js index 057cdb6cc4..e4c69a114e 100644 --- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js +++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js @@ -25,9 +25,10 @@ function importMermaidModule() { return import(/* webpackChunkName: 'mermaid' */ 'mermaid') .then(mermaid => { let theme = 'neutral'; + const ideDarkThemes = ['dark', 'solarized-dark']; if ( - window.gon?.user_color_scheme === 'dark' && + ideDarkThemes.includes(window.gon?.user_color_scheme) && // if on the Web IDE page document.querySelector('.ide') ) { diff --git a/app/assets/javascripts/blob/components/blob_content.vue b/app/assets/javascripts/blob/components/blob_content.vue index 4f433bd8df..eb7f45cba6 100644 --- a/app/assets/javascripts/blob/components/blob_content.vue +++ b/app/assets/javascripts/blob/components/blob_content.vue @@ -66,6 +66,7 @@ export default { ref="contentViewer" :content="content" :type="activeViewer.fileType" + data-qa-selector="file_content" /> diff --git a/app/assets/javascripts/blob/components/blob_header.vue b/app/assets/javascripts/blob/components/blob_header.vue index e5e01caa9a..76c5779f3a 100644 --- a/app/assets/javascripts/blob/components/blob_header.vue +++ b/app/assets/javascripts/blob/components/blob_header.vue @@ -30,6 +30,11 @@ export default { required: false, default: SIMPLE_BLOB_VIEWER, }, + hasRenderError: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -75,6 +80,7 @@ export default { v-if="showDefaultActions" :raw-path="blob.rawPath" :active-viewer="viewer" + :has-render-error="hasRenderError" @copy="proxyCopyRequest" /> diff --git a/app/assets/javascripts/blob/components/blob_header_default_actions.vue b/app/assets/javascripts/blob/components/blob_header_default_actions.vue index 63ae70a37f..62fef108b4 100644 --- a/app/assets/javascripts/blob/components/blob_header_default_actions.vue +++ b/app/assets/javascripts/blob/components/blob_header_default_actions.vue @@ -27,6 +27,11 @@ export default { default: SIMPLE_BLOB_VIEWER, required: false, }, + hasRenderError: { + type: Boolean, + required: false, + default: false, + }, }, computed: { downloadUrl() { @@ -44,11 +49,13 @@ export default { diff --git a/app/assets/javascripts/boards/components/board_column.vue b/app/assets/javascripts/boards/components/board_column.vue index fb854616a0..0ed7579e8e 100644 --- a/app/assets/javascripts/boards/components/board_column.vue +++ b/app/assets/javascripts/boards/components/board_column.vue @@ -1,33 +1,22 @@ + + diff --git a/app/assets/javascripts/boards/components/board_delete.js b/app/assets/javascripts/boards/components/board_delete.js index cc15dc82db..b74234a2e3 100644 --- a/app/assets/javascripts/boards/components/board_delete.js +++ b/app/assets/javascripts/boards/components/board_delete.js @@ -1,8 +1,15 @@ import $ from 'jquery'; import Vue from 'vue'; +import { GlButton, GlTooltipDirective } from '@gitlab/ui'; import { __ } from '~/locale'; export default Vue.extend({ + components: { + GlButton, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, props: { list: { type: Object, diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue index c4e2c398d4..4270ad5783 100644 --- a/app/assets/javascripts/boards/components/board_list.vue +++ b/app/assets/javascripts/boards/components/board_list.vue @@ -104,7 +104,7 @@ export default { }, }, created() { - eventHub.$on(`hide-issue-form-${this.list.id}`, this.toggleForm); + eventHub.$on(`toggle-issue-form-${this.list.id}`, this.toggleForm); eventHub.$on(`scroll-board-list-${this.list.id}`, this.scrollToTop); }, mounted() { @@ -381,7 +381,7 @@ export default { this.$refs.list.addEventListener('scroll', this.onScroll); }, beforeDestroy() { - eventHub.$off(`hide-issue-form-${this.list.id}`, this.toggleForm); + eventHub.$off(`toggle-issue-form-${this.list.id}`, this.toggleForm); eventHub.$off(`scroll-board-list-${this.list.id}`, this.scrollToTop); this.$refs.list.removeEventListener('scroll', this.onScroll); }, diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue new file mode 100644 index 0000000000..eb12617a66 --- /dev/null +++ b/app/assets/javascripts/boards/components/board_list_header.vue @@ -0,0 +1,291 @@ + + + diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue index deebe12210..c72fb7b30f 100644 --- a/app/assets/javascripts/boards/components/board_new_issue.vue +++ b/app/assets/javascripts/boards/components/board_new_issue.vue @@ -92,7 +92,7 @@ export default { }, cancel() { this.title = ''; - eventHub.$emit(`hide-issue-form-${this.list.id}`); + eventHub.$emit(`toggle-issue-form-${this.list.id}`); }, setSelectedProject(selectedProject) { this.selectedProject = selectedProject; diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js index c895315881..056a7b4821 100644 --- a/app/assets/javascripts/boards/components/board_sidebar.js +++ b/app/assets/javascripts/boards/components/board_sidebar.js @@ -54,7 +54,7 @@ export default Vue.extend({ return this.issue.milestone ? this.issue.milestone.title : __('No milestone'); }, canRemove() { - return !this.list.preset; + return !this.list?.preset; }, hasLabels() { return this.issue.labels && this.issue.labels.length; diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue index a589fb325b..f2e198eaed 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.vue +++ b/app/assets/javascripts/boards/components/issue_card_inner.vue @@ -147,7 +147,7 @@ export default {