diff --git a/.eslintrc.yml b/.eslintrc.yml index 1e6df6f5a7..a764f74978 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -43,6 +43,18 @@ rules: promise/always-return: off promise/no-callback-in-promise: off "@gitlab/no-global-event-off": error + + # BEGIN eslint-plugin-vue@7 overrides + # TODO: Remove these rules as part of + # https://gitlab.com/groups/gitlab-org/-/epics/5142. These are setting + # various vue lint rules as they were in eslint-plugin-vue@6, or disabling + # new ones, to ease migration to v7, so violations of each can be fixed + # separately. + vue/no-mutating-props: off + vue/one-component-per-file: off + vue/no-lone-template: off + vue/component-definition-name-casing: off + # END eslint-plugin-vue@7 overrides overrides: - files: - '**/spec/**/*' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5e54f9cde3..b41d7bcd34 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -64,7 +64,7 @@ variables: BUILD_ASSETS_IMAGE: "false" ES_JAVA_OPTS: "-Xms256m -Xmx256m" ELASTIC_URL: "http://elastic:changeme@elasticsearch:9200" - DOCKER_VERSION: "19.03.0" + DOCKER_VERSION: "20.10.1" CACHE_CLASSES: "true" # Preparing custom clone path to reduce space used by all random forks @@ -110,3 +110,4 @@ include: - local: .gitlab/ci/notify.gitlab-ci.yml - local: .gitlab/ci/dast.gitlab-ci.yml - local: .gitlab/ci/workhorse.gitlab-ci.yml + - local: .gitlab/ci/graphql.gitlab-ci.yml diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 70d9dbc9ad..df81d05eec 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -250,10 +250,10 @@ Dangerfile @gl-quality/eng-prod /ee/spec/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh /doc/user/project/code_owners.md @reprazent @kerrizor @garyh -[Product Analytics] -/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product_analytics/engineers -/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/product_analytics/engineers -/lib/gitlab/grafana_embed_usage_data.rb @gitlab-org/growth/product_analytics/engineers -/lib/gitlab/usage_data.rb @gitlab-org/growth/product_analytics/engineers -/lib/gitlab/cycle_analytics/usage_data.rb @gitlab-org/growth/product_analytics/engineers -/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product_analytics/engineers +[Product Intelligence] +/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers +/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/product-intelligence/engineers +/lib/gitlab/grafana_embed_usage_data.rb @gitlab-org/growth/product-intelligence/engineers +/lib/gitlab/usage_data.rb @gitlab-org/growth/product_intelligence/engineers +/lib/gitlab/cycle_analytics/usage_data.rb @gitlab-org/growth/product-intelligence/engineers +/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers diff --git a/.gitlab/ci/dev-fixtures.gitlab-ci.yml b/.gitlab/ci/dev-fixtures.gitlab-ci.yml index c19dce7e4a..1848283f92 100644 --- a/.gitlab/ci/dev-fixtures.gitlab-ci.yml +++ b/.gitlab/ci/dev-fixtures.gitlab-ci.yml @@ -15,7 +15,6 @@ # SEED_NESTED_GROUPS: "false" # requires network connection .run-dev-fixtures-script: &run-dev-fixtures-script - - run_timed_command "scripts/gitaly-test-build" - run_timed_command "scripts/gitaly-test-spawn" - run_timed_command "RAILS_ENV=test bundle exec rake db:seed_fu" diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml index d6dc709a11..955f44c621 100644 --- a/.gitlab/ci/docs.gitlab-ci.yml +++ b/.gitlab/ci/docs.gitlab-ci.yml @@ -43,7 +43,7 @@ docs-lint markdown: - .default-retry - .docs:rules:docs-lint # When updating the image version here, update it in /scripts/lint-doc.sh too. - image: "registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.12-vale-2.6.1-markdownlint-0.24.0" + image: "registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.12-vale-2.8.0-markdownlint-0.26.0" stage: test needs: [] script: @@ -84,16 +84,3 @@ ui-docs-links lint: needs: [] script: - bundle exec haml-lint -i DocumentationLinks - -graphql-reference-verify: - extends: - - .default-retry - - .rails-cache - - .default-before_script - - .docs:rules:graphql-reference-verify - - .use-pg11 - stage: test - needs: ["setup-test-env"] - script: - - bundle exec rake gitlab:graphql:check_docs - - bundle exec rake gitlab:graphql:check_schema diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index 0b921309ce..c87305cab1 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -103,7 +103,6 @@ update-yarn-cache: WEBPACK_VENDOR_DLL: "true" script: - run_timed_command "gem install knapsack --no-document" - - run_timed_command "scripts/gitaly-test-build" - run_timed_command "scripts/gitaly-test-spawn" - source ./scripts/rspec_helpers.sh - rspec_paralellized_job "--tag frontend_fixture" @@ -236,6 +235,8 @@ coverage-frontend: - *yarn-install script: - run_timed_command "yarn node scripts/frontend/merge_coverage_frontend.js" + # Removing the individual coverage results, as we just merged them. + - rm -r coverage-frontend/jest-* coverage: '/^Statements\s*:\s*?(\d+(?:\.\d+)?)%/' artifacts: name: coverage-frontend diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml index 0fafd5869d..355607c17a 100644 --- a/.gitlab/ci/global.gitlab-ci.yml +++ b/.gitlab/ci/global.gitlab-ci.yml @@ -112,7 +112,7 @@ .use-kaniko: image: - name: gcr.io/kaniko-project/executor:debug-v0.20.0 + name: gcr.io/kaniko-project/executor:debug-v1.3.0 entrypoint: [""] before_script: - source scripts/utils.sh diff --git a/.gitlab/ci/graphql.gitlab-ci.yml b/.gitlab/ci/graphql.gitlab-ci.yml new file mode 100644 index 0000000000..4aff0ef630 --- /dev/null +++ b/.gitlab/ci/graphql.gitlab-ci.yml @@ -0,0 +1,14 @@ +graphql-verify: + variables: + SETUP_DB: "false" + extends: + - .default-retry + - .rails-cache + - .default-before_script + - .graphql:rules:graphql-verify + stage: test + needs: [] + script: + - bundle exec rake gitlab:graphql:validate + - bundle exec rake gitlab:graphql:check_docs + - bundle exec rake gitlab:graphql:check_schema diff --git a/.gitlab/ci/pages.gitlab-ci.yml b/.gitlab/ci/pages.gitlab-ci.yml index a66e0d88db..4961bd508d 100644 --- a/.gitlab/ci/pages.gitlab-ci.yml +++ b/.gitlab/ci/pages.gitlab-ci.yml @@ -14,7 +14,6 @@ pages: - 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 - cp .public/assets/application-*.css.gz public/application.css.gz || true artifacts: diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 2818b6be17..a2a16424f4 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -10,7 +10,6 @@ # Only install knapsack after bundle install! Otherwise oddly some native # gems could not be found under some circumstance. No idea why, hours wasted. - run_timed_command "gem install knapsack --no-document" - - run_timed_command "scripts/gitaly-test-build" - run_timed_command "scripts/gitaly-test-spawn" - source ./scripts/rspec_helpers.sh @@ -150,20 +149,35 @@ setup-test-env: script: - run_timed_command "bundle exec ruby -I. -e 'require \"config/environment\"; TestEnv.init'" - run_timed_command "scripts/gitaly-test-build" # Do not use 'bundle exec' here - - rm tmp/tests/gitaly/.ruby-bundle # This file prevents gems from being installed even if vendor/gitaly-ruby is missing artifacts: expire_in: 7d paths: - config/secrets.yml - - tmp/tests/gitaly - - tmp/tests/gitlab-elasticsearch-indexer - - tmp/tests/gitlab-shell - - tmp/tests/gitlab-test-fork - - tmp/tests/gitlab-test-fork_bare - - tmp/tests/gitlab-test - - tmp/tests/gitlab-workhorse - - tmp/tests/repositories - - tmp/tests/second_storage + - tmp/tests/gitaly/config.toml + - tmp/tests/gitaly/gitaly + - tmp/tests/gitaly/gitaly2.config.toml + - tmp/tests/gitaly/gitaly-git2go + - tmp/tests/gitaly/gitaly-hooks + - tmp/tests/gitaly/gitaly-lfs-smudge + - tmp/tests/gitaly/gitaly-ssh + - tmp/tests/gitaly/internal/ + - tmp/tests/gitaly/internal_sockets/ + - tmp/tests/gitaly/Makefile + - tmp/tests/gitaly/praefect + - tmp/tests/gitaly/praefect.config.toml + - tmp/tests/gitaly/ruby/ + - tmp/tests/gitlab-elasticsearch-indexer/bin/gitlab-elasticsearch-indexer + - tmp/tests/gitlab-shell/ + - tmp/tests/gitlab-test-fork/ + - tmp/tests/gitlab-test-fork_bare/ + - tmp/tests/gitlab-test/ + - tmp/tests/gitlab-workhorse/gitlab-zip-metadata + - tmp/tests/gitlab-workhorse/gitlab-zip-cat + - tmp/tests/gitlab-workhorse/gitlab-workhorse + - tmp/tests/gitlab-workhorse/gitlab-resize-image + - tmp/tests/gitlab-workhorse/config.toml + - tmp/tests/repositories/ + - tmp/tests/second_storage/ when: always update-rails-cache: @@ -286,6 +300,16 @@ rspec system pg11 minimal: - .minimal-rspec-tests - .rails:rules:ee-and-foss-system:minimal +# Dedicated job to test DB library code against PG12. +# Note that these are already tested against PG11 in the `rspec unit pg11` / `rspec-ee unit pg11` jobs. +rspec db-library-code pg12: + extends: + - .rspec-base-pg12 + - .rails:rules:ee-and-foss-db-library-code + script: + - *base-script + - rspec_db_library_code + rspec fast_spec_helper: extends: - .rspec-base-pg11 @@ -311,6 +335,14 @@ db:check-schema: script: - source scripts/schema_changed.sh +db:check-migrations: + extends: + - .db-job-base + - .rails:rules:ee-and-foss-mr-with-migration + script: + - scripts/validate_migration_schema + allow_failure: true + db:migrate-from-v12.10.0: extends: .db-job-base variables: @@ -376,6 +408,38 @@ db:backup_and_restore: rules: - changes: ["lib/backup/**/*"] +rspec:deprecations: + extends: + - .default-retry + - .default-before_script + - .static-analysis-cache + - .rails:rules:deprecations + stage: post-test + allow_failure: true + # We cannot use needs since it would mean needing 84 jobs (since most are parallelized) + # so we use `dependencies` here. + dependencies: + - rspec migration pg11 + - rspec unit pg11 + - rspec integration pg11 + - rspec system pg11 + - rspec-ee migration pg11 + - rspec-ee unit pg11 + - rspec-ee integration pg11 + - rspec-ee system pg11 + - rspec-ee unit pg11 geo + - rspec-ee integration pg11 geo + - rspec-ee system pg11 geo + variables: + SETUP_DB: "false" + script: + - run_timed_command "bundle exec rubocop --only Lint/LastKeywordArgument --parallel" + artifacts: + expire_in: 31d + when: always + paths: + - deprecations/ + rspec:coverage: extends: - .coverage-base @@ -549,33 +613,36 @@ rspec-ee unit pg11 geo: - .rails:rules:ee-only-unit - .rspec-ee-unit-geo-parallel -rspec-ee unit pg11 geo minimal: - extends: - - rspec-ee unit pg11 geo - - .minimal-rspec-tests - - .rails:rules:ee-only-unit:minimal +# FIXME: Temporarily disable geo minimal rspec jobs https://gitlab.com/gitlab-org/gitlab/-/issues/294212 +#rspec-ee unit pg11 geo minimal: +# extends: +# - rspec-ee unit pg11 geo +# - .minimal-rspec-tests +# - .rails:rules:ee-only-unit:minimal rspec-ee integration pg11 geo: extends: - .rspec-ee-base-geo-pg11 - .rails:rules:ee-only-integration -rspec-ee integration pg11 geo minimal: - extends: - - rspec-ee integration pg11 geo - - .minimal-rspec-tests - - .rails:rules:ee-only-integration:minimal +# FIXME: Temporarily disable geo minimal rspec jobs https://gitlab.com/gitlab-org/gitlab/-/issues/294212 +#rspec-ee integration pg11 geo minimal: +# extends: +# - rspec-ee integration pg11 geo +# - .minimal-rspec-tests +# - .rails:rules:ee-only-integration:minimal rspec-ee system pg11 geo: extends: - .rspec-ee-base-geo-pg11 - .rails:rules:ee-only-system -rspec-ee system pg11 geo minimal: - extends: - - rspec-ee system pg11 geo - - .minimal-rspec-tests - - .rails:rules:ee-only-system:minimal +# FIXME: Temporarily disable geo minimal rspec jobs https://gitlab.com/gitlab-org/gitlab/-/issues/294212 +#rspec-ee system pg11 geo minimal: +# extends: +# - rspec-ee system pg11 geo +# - .minimal-rspec-tests +# - .rails:rules:ee-only-system:minimal db:rollback geo: extends: diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml index 85aec07055..77ada89aa6 100644 --- a/.gitlab/ci/reports.gitlab-ci.yml +++ b/.gitlab/ci/reports.gitlab-ci.yml @@ -4,9 +4,9 @@ # - template: Security/Dependency-Scanning.gitlab-ci.yml # - template: Security/DAST.gitlab-ci.yml -# 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. +# We need to duplicate this job's definition because the rules +# defined in the extended jobs rely on local YAML anchors +# (`*if-default-refs`) code_quality: extends: - .default-retry @@ -36,9 +36,9 @@ code_quality: - gl-code-quality-report.json # GitLab-specific 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. +# We need to duplicate this job's definition because the rules +# defined in the extended jobs rely on local YAML anchors +# (`*if-default-refs`) .sast: extends: - .default-retry @@ -89,74 +89,58 @@ secrets-sast: sast: gl-secret-detection-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. -dependency_scanning: +# We need to duplicate this job's definition because the rules +# defined in the extended jobs rely on local YAML anchors +# (`*if-default-refs`) +.dependency_scanning: extends: - .default-retry - .reports:rules:dependency_scanning - - .use-docker-in-docker stage: test needs: [] variables: DS_MAJOR_VERSION: 2 - DS_EXCLUDED_PATHS: "qa/qa/ee/fixtures/secure_premade_reports,spec,ee/spec" # GitLab-specific - script: - - | - if ! docker info &>/dev/null; then - if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then - export DOCKER_HOST='tcp://localhost:2375' - fi - fi - - | # this is required to avoid undesirable reset of Docker image ENV variables being set on build stage - function propagate_env_vars() { - CURRENT_ENV=$(printenv) - - for VAR_NAME; do - echo $CURRENT_ENV | grep "${VAR_NAME}=" > /dev/null && echo "--env $VAR_NAME " - done - } - - | - docker run \ - $(propagate_env_vars \ - DS_ANALYZER_IMAGES \ - DS_ANALYZER_IMAGE_PREFIX \ - DS_ANALYZER_IMAGE_TAG \ - DS_DEFAULT_ANALYZERS \ - DS_EXCLUDED_PATHS \ - DS_DOCKER_CLIENT_NEGOTIATION_TIMEOUT \ - DS_PULL_ANALYZER_IMAGE_TIMEOUT \ - DS_RUN_ANALYZER_TIMEOUT \ - DS_PYTHON_VERSION \ - DS_PIP_VERSION \ - DS_PIP_DEPENDENCY_PATH \ - GEMNASIUM_DB_LOCAL_PATH \ - GEMNASIUM_DB_REMOTE_URL \ - GEMNASIUM_DB_REF_NAME \ - PIP_INDEX_URL \ - PIP_EXTRA_INDEX_URL \ - PIP_REQUIREMENTS_FILE \ - MAVEN_CLI_OPTS \ - BUNDLER_AUDIT_UPDATE_DISABLED \ - BUNDLER_AUDIT_ADVISORY_DB_URL \ - BUNDLER_AUDIT_ADVISORY_DB_REF_NAME \ - ) \ - --volume "$PWD:/code" \ - --volume /var/run/docker.sock:/var/run/docker.sock \ - "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$DS_MAJOR_VERSION" /code - # Post-processing: This will be an after_script once this job will use the Dependency Scanning CI template - - apk add jq - # Lower execa severity based on https://gitlab.com/gitlab-org/gitlab/-/issues/223859#note_452922390 - - jq '(.vulnerabilities[] | select (.cve == "yarn.lock:execa:gemnasium:05cfa2e8-2d0c-42c1-8894-638e2f12ff3d")).severity = "Medium"' gl-dependency-scanning-report.json > temp.json && mv temp.json gl-dependency-scanning-report.json + DS_EXCLUDED_PATHS: "qa/qa/ee/fixtures/secure_premade_reports, spec, ee/spec" # GitLab-specific + SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers" artifacts: paths: - gl-dependency-scanning-report.json # GitLab-specific reports: dependency_scanning: gl-dependency-scanning-report.json expire_in: 1 week # GitLab-specific + script: + - /analyzer run -# The job below analysis dependencies for malicous behavior +dependency_scanning gemnasium: + extends: .dependency_scanning + image: + name: "$SECURE_ANALYZERS_PREFIX/gemnasium:$DS_MAJOR_VERSION" + before_script: + # git-lfs is needed for auto-remediation + - apk add git-lfs + after_script: + # Post-processing + - apk add jq + # Lower execa severity based on https://gitlab.com/gitlab-org/gitlab/-/issues/223859#note_452922390 + - jq '(.vulnerabilities[] | select (.cve == "yarn.lock:execa:gemnasium:05cfa2e8-2d0c-42c1-8894-638e2f12ff3d")).severity = "Medium"' gl-dependency-scanning-report.json > temp.json && mv temp.json gl-dependency-scanning-report.json + +dependency_scanning bundler-audit: + extends: .dependency_scanning + image: + name: "$SECURE_ANALYZERS_PREFIX/bundler-audit:$DS_MAJOR_VERSION" + +dependency_scanning retire-js: + extends: .dependency_scanning + image: + name: "$SECURE_ANALYZERS_PREFIX/retire.js:$DS_MAJOR_VERSION" + +dependency_scanning gemnasium-python: + extends: .dependency_scanning + image: + name: "$SECURE_ANALYZERS_PREFIX/gemnasium-python:$DS_MAJOR_VERSION" + +# Analyze dependencies for malicious behavior +# See https://gitlab.com/gitlab-com/gl-security/security-research/package-hunter package_hunter: extends: - .reports:schedule-dast diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml index f1bd173ff6..b7d9f18dcb 100644 --- a/.gitlab/ci/review.gitlab-ci.yml +++ b/.gitlab/ci/review.gitlab-ci.yml @@ -38,7 +38,7 @@ review-build-cng: - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng # When the job is manual, review-deploy is also manual and we don't want people # to have to manually start the jobs in sequence, so we do it for them. - - '[ -z $CI_JOB_MANUAL ] || scripts/api/play_job --job-name "review-deploy"' + - '[ -z $CI_JOB_MANUAL ] || scripts/api/play_job.rb --job-name "review-deploy"' .review-workflow-base: extends: @@ -48,7 +48,7 @@ review-build-cng: HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}" REVIEW_APPS_DOMAIN: "temp.gitlab-review.app" # FIXME: using temporary domain DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}" - GITLAB_HELM_CHART_REF: "v4.3.0" + GITLAB_HELM_CHART_REF: "v4.6.3" environment: name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY} url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN} @@ -78,8 +78,8 @@ review-deploy: - disable_sign_ups || (delete_release && 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 ] || scripts/api/play_job --job-name "review-qa-smoke"' - - '[ -z $CI_JOB_MANUAL ] || scripts/api/play_job --job-name "review-performance"' + - '[ -z $CI_JOB_MANUAL ] || scripts/api/play_job.rb --job-name "review-qa-smoke"' + - '[ -z $CI_JOB_MANUAL ] || scripts/api/play_job.rb --job-name "review-performance"' after_script: # Run seed-dast-test-data.sh only when DAST_RUN is set to true. This is to pupulate review app with data for DAST scan. # Set DAST_RUN to true when jobs are manually scheduled. diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 159defc83c..5e8cdf0daa 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -155,9 +155,15 @@ - "{,ee/}{,spec/}lib/{,ee/}gitlab/database{,_spec}.rb" - "{,ee/}{,spec/}lib/{,ee/}gitlab/background_migration/**/*" - "{,ee/}{,spec/}lib/{,ee/}gitlab/background_migration{,_spec}.rb" + - "{,ee/}spec/support/helpers/database/**/*" - "config/prometheus/common_metrics.yml" # Used by Gitlab::DatabaseImporters::CommonMetrics::Importer - "{,ee/}app/models/project_statistics.rb" # Used to calculate sizes in migration specs +.db-library-patterns: &db-library-patterns + - "{,ee/}{,spec/}lib/{,ee/}gitlab/database/**/*" + - "{,ee/}{,spec/}lib/{,ee/}gitlab/database{,_spec}.rb" + - "{,ee/}spec/support/helpers/database/**/*" + .backstage-patterns: &backstage-patterns - "Dangerfile" - "danger/**/*" @@ -349,7 +355,11 @@ changes: *docs-patterns when: on_success -.docs:rules:graphql-reference-verify: +################## +# GraphQL rules # +################## + +.graphql:rules:graphql-verify: rules: - <<: *if-not-ee when: never @@ -507,6 +517,12 @@ - <<: *if-merge-request changes: *db-patterns +.rails:rules:ee-and-foss-mr-with-migration: + rules: + - <<: *if-merge-request + changes: *db-patterns + - <<: *if-merge-request-title-run-all-rspec + .rails:rules:ee-and-foss-unit: rules: - changes: *backend-patterns @@ -765,6 +781,11 @@ - <<: *if-merge-request-title-as-if-foss changes: *code-backstage-patterns +.rails:rules:ee-and-foss-db-library-code: + rules: + - changes: *db-library-patterns + - <<: *if-merge-request-title-run-all-rspec + .rails:rules:ee-mr-and-master-only: rules: - <<: *if-not-ee @@ -825,6 +846,13 @@ - <<: *if-merge-request changes: *code-backstage-patterns +.rails:rules:deprecations: + rules: + - <<: *if-not-ee + when: never + - <<: *if-master-schedule-nightly + - <<: *if-merge-request-title-run-all-rspec + .rails:rules:rspec-coverage: rules: - <<: *if-not-ee diff --git a/.gitlab/issue_templates/Acceptance Testing.md b/.gitlab/issue_templates/Acceptance Testing.md index 5a6c35f28a..5289638255 100644 --- a/.gitlab/issue_templates/Acceptance Testing.md +++ b/.gitlab/issue_templates/Acceptance Testing.md @@ -27,7 +27,7 @@ Then leave running while monitoring and performing some testing through web, api - [ ] [Inspect logs in ELK](https://log.gitlab.net/app/kibana) - [ ] [Check for errors in GitLab Dev Sentry](https://sentry.gitlab.net/gitlab/devgitlaborg/?query=is%3Aunresolved) -## 2. Staging Trial +## 3. Staging Trial #### Check Staging Server Versions - [ ] GitLab: https://staging.gitlab.com/help diff --git a/.gitlab/issue_templates/Design Sprint.md b/.gitlab/issue_templates/Design Sprint.md new file mode 100644 index 0000000000..787c4469b8 --- /dev/null +++ b/.gitlab/issue_templates/Design Sprint.md @@ -0,0 +1,203 @@ + + +## Design Sprint Focus +* [ ] Have you [determined that a Design Sprint is appropriate for this project](#anchor-tag-to-handbook-page)? + + +## Objectives + + + +## Outputs + +- [ ] A User testing flow. +- [ ] A Prototype to be tested with users. +- [ ] User testing analysis. +- [ ] (If the solution is viable) An epic or issue that describes the direction in details and the next steps +- [ ] Necessary updates to the Handbook. + +## Design Sprint Details + +| Start | End | +| ------ | ------ | +| YYYY-MM-DD | YYYY-MM-DD | +| TT:TT PST | TT:TT PST | + + +### WHEN + +**Start date:** + +**End date:** + +**Reference time zone:** + +### WHERE + +**Zoom link:** + +### WHO + + - `Name` `gitlab handle` - Facilitator + - `Name` `gitlab handle` - Decider (usually the Product Manager) + - `Name` `gitlab handle` - Co-decider (optional) + - `Name` `gitlab handle` - Sprint team member + - `Name` `gitlab handle` - Sprint team member + - `Name` `gitlab handle` - Sprint team member + - `Name` `gitlab handle` - Sprint team member + - `Name` `gitlab handle` - Sprint team member + - `Name` `gitlab handle` - Sprint team member + - `Name` `gitlab handle` - Co-facilitator (optional) + +## Tools +Here is the list of tools for the Sprint preparation, collaboration and documentation. Prior to the Sprint make sure you have access to all of the following: + +* **GitLab**
+Each Sprint day outcomes and material will be documented in a separate issue under the Design Sprint epic. + +* **Mural** (You can join as anonymous but we need to be able to identify input against names, so please create an account beforehand.
+We will use Mural for most of the Sprint collaboration. Some of the things we will do in Mural: + * Create artifacts like affinity diagrams from participants' input + * Use post-its to comment on each other's points and to add notes + * Vote on ideas and solutions + * Create the first draft of the prototype. +The Mural link to the collaboration project will be provided in the issue before the start of the Design Sprint. + +* **Video and/or screen recording tool** (Loom, Quicktime, Zoom or another tool you are using).
+As part of the pre-Sprint homework, you will be asked to record a short Lightning Walkthrough video. You can use any tool you feel comfortable with as long as it can capture your screen, mouse pointer and your audio. + +* **A4/Letter sized paper (preferably white blank), Sharpies/Pens** (please don't use a pencil because it doesn't create enough contrast for photos).
+Day 2 of the sprint involves some (async) ideation via sketching so you will need a writing utensil (Sharpies are preferred because they force you to draw at a lower fidelity because the small details aren't necessary at this point) and some paper. This is the most fun part of the Sprint where you get into a design thinking mindset and can appeal to your creative self. Don't worry, it's not about artistry, it's about ideas and collaboration. + +* **Camera (phone or other) or scanner**
+You will need to upload sketches as images for the facilitator to prepare the material before the next sync meeting. You can take a photo with your phone or use a scanner if available. + +* **Post-it notes (Optional)**
+If you enjoy taking notes using post-it notes make sure you have available some of them as well. The upside is that they will make you feel more like you are in a workshop and will help the ideas flow (I find that typing is distracting while ideating). The downside is that you will have to digitalise the ones you want to share with the team in Mural. + +## Artefacts & Pre-Read Material + + + +### Handbook pages + + +### Competitor resources + + + +### Articles on Design Sprints + * [The Design Sprint](https://www.gv.com/sprint/) + * [The Ultimate Guide To Remote Design Sprints](https://drive.google.com/file/d/16bwrAqHVf8qxovd87Q7LdzqwAgy7a6Rx/view?usp=sharing) + +## Asyncronus tasks + +### Design Sprint preparation + + + +- [ ] Finalise participant list - `decider` and `facilitator` +- [ ] Create [participation form](https://docs.google.com/forms/d/e/1FAIpQLSc0_BNltvRW8yXXaJd8sIKzgDmrSGqILMfkoCJrAj6sFcsMcg/viewform?usp=sf_link) and send to participants (**deadline**: [date]) - `facilitator` +- [ ] Promote this issue to an epic - `facilitator` +- [ ] Create issues under the epic for the pre-workshop tasks: Expert interviews ([example](https://gitlab.com/groups/gitlab-org/configure/-/epics/3#note_332412524)), Lightning walkthroughs and How might we.. notetaking assignment ([example](https://gitlab.com/gitlab-org/configure/general/-/issues/52)), Voting How might we... notes assignment ([example](https://gitlab.com/gitlab-org/configure/general/-/issues/54)) - `facilitator` +- [ ] Create sync meetings in calendar and invite all participants (**deadline**: [date]) - `decider` or `facilitator` +- [ ] Block 2 hours for Sprint activities in calendar for the Sprint week - `all participants` +- [ ] Prepare material and tools (eg. presentation templates, Google folders, Instructions videos etc) and Mural board from the [Mural template ](https://app.mural.co/invitation/mural/gitlab2474/1586990879319?sender=jmandell0210&key=03c25e92-9a43-4a3d-8907-6f0c3b094ab8) - facilitator +- [ ] Finalize Agenda - `facilitator` +- [ ] Run a test with material and tools - `facilitator` +- [ ] Start user recruiting for prototype user testing (EOD 1) - `facilitator` or `decider` + +### Pre-Sprint activities (Homework exercises) + +Each exercise should be explained and documented in a separate issue. You can use the example issues above as templates. + +- [ ] Fill form and submit (**deadline**: [date]) - `all participants except the facilitator` +- [ ] Expert interview analysis - `facilitator` +- [ ] Lightning walkthrough videos (**deadline**: [date]) - `all participants except the facilitator` +- [ ] How might we... notetaking assignment (**deadline**: [date]) - `all participants except the facilitator` +- [ ] Voting How might we... notes assignment (**deadline**: [date]) - `all participants except the facilitator` +- [ ] Add all required material to the Mural board (**deadline**: [date]) - `facilitator` + +### During Sprint activities + +- [ ] Organise user testing sessions - `facilitator` or `decider` +- [ ] Create the Prototype to be tested and task list (End of Day 3) - `Product designer` or `Front end developer` +- [ ] Run user testing sessions - `facilitator` or `decider` + +### Post-Sprint activities + +- [ ] Create a feedback issue for the Design Sprint - `facilitator` or `decider` +- [ ] Analyse user testing results - `facilitator` or `decider` +- [ ] Create report and share with the Design Sprint participants and wider team - `facilitator` or `decider` + +## Personas + +Deciding which persona we are focusing on will be part of the Day 1 discussions in the workshop. The personas we are going to consider are: + + + +## Agenda +### Day 1 + + | Activity | Duration | Tool | Description | +|---|---|---|---| +| Warm-up exercise | 5 mins | Mural | Write 1 post-it answering the questions:
"My name is…"
"My role is…"
“Something about myself you may not know is…”
"My wish for this workshop is…" | +| Summarise the async activities & complete Map | 20 mins | Mural | The Map is intended to show the focus of the Sprint and doesn't need to be complete or detailed. Steps:
Go through the Map and the top voted How might we’s tree as a warm-up/reminder.
• Make appropriate adjustments and additions to the map based on the reviews from the team.
• Add the most voted HMWs to the most relevant area on the Map. If a HMW can go to more than one place, add it to the most left area. | +| Long term goals/Deciding the Sprint goal | 15 mins | Mural | • Long term goal: Everyone spends 5 minutes in silence and writes one (max 2) long term goal post-it note for the Sprint. (5 mins )
• One by one everyone will read their goal aloud to the team. (5 mins)
Everyone besides the decider will vote on the goal of the Sprint (1 dot). (4 minutes)
The decider then makes the final decision on the long term goal of the Sprint. (1 min) | + | Sprint questions | 20 mins | Mural | • Referencing the Long Term goal, everyone will write 2-3 post-it note Sprint questions for the biggest challenges they think might stop us from achieving our long term goal (what might hold us back or hinder us from achieving this goal). The questions should start with “Can we...” (similarly to the HMW). (7 mins)
• One by one everyone will read their Sprint questions aloud to the team. (5 mins)
• Everyone (including the decider) votes on the top 3 questions they think we should focus on as Sprint challenges (3 dots). (5 mins)
• Separate the 3 most voted questions and keep them on the side. (1 min)
• Finally, the decider chooses one Sprint question that will be the question we will focus on more during the Sprint by placing a green smiley sticker on it. (1 min)
• Move the long term goal and the Sprint questions to the dedicated Mural space, highlighting the ultimate Sprint question that the decider chose. (1 min) | +| Recap day.
Short intro to next day and share the video with the next day exercise instructions. | 5 mins | Mural, Zoom | Summarise activities of the day and decisions. Brief walkthrough of the next day's activities and wrap up the day. | + +### Day 2 + | Activity | Duration | Tool | Description | +|---|---|---|---| +| Summary of Day 1 outcomes | 5 mins | Mural | Go through the previous day's activities, the Long term goal and the top voted Sprint questions, highlighting the ultimate Sprint question, and summarise the concept solution sketching homework exercise. | +| Concept gallery review | 20 mins | Mural | • Everyone takes some time to read through and look at every aspect of each of the sketches in the Concept Gallery. The concept sketches are anonymous to avoid bias (15 mins).
• The team will then vote on their favorite concepts and/or components of a concept via the red dots. When they see something that interests them and they think it will help solve the long term goal/challenges they can add one or more dots. They can use as many red dots as they want. Be frivolous when adding dots but if you really like or think something is important, add more to draw attention to it (5 mins).
Note: If anyone has any questions about a concept sketch create a red sticky and write that question down placing it under the concept sketches. | +| Speed critique | 5 mins | Mural | • The facilitator walks through each of the concepts, briefly summarizing each concept (to the best of their ability) with a focus on the areas that have been dotted.
• During this time the facilitator will also try to answer any of the red post-it questions.
• When the facilitator believes they’ve reached the end of their summary for that concept, ask the team if there was a concept that was voted on but not discussed or if the point of the red dot vote was missed in the discussion. +| Straw Poll | ~15 mins | Mural | • All the participants, besides the Decider, vote using the larger green dot by adding their initials to it and placing it on the concept sketch they believe is the best one that will best fulfill the long term goal and challenges of this sprint and is worthy of being prototyped (2 mins)
• Each participant will create a post-it note that explains their reasoning for choosing the concept. (5 mins)
• Each participant will then get 1 minute to read through their post-it and attempt to sell their preferred concept to the Decider and the other participants. (5-10 mins) | +| Super Vote (The Decider) | 10 mins | Mural | • The Decider makes their final decision of which of the concepts is the one to move forward with.
• The decider can discuss their thought process and any questions with the rest of the participants.
• They will get 2 green smiley stickers to vote with. Placing one on the concept they want to move forward with and the second, optional smiley, can be used to mark any other area of any other concept they think should also be incorporated into the prototype. | + + +### Day 3 + | Activity | Duration | Tool | Description | +|---|---|---|---| +| User test flow | 25 mins | Mural | • Each participant writes (on separate post-its) 6 steps/actions that represent a step of a flow (you can think of a high-level prototype flow) from start to finish. Place them in the appropriate location on the User Test section. (10 mins)
• Each participant takes 1 minute to walk the team through their flows one-by-one (5-10 mins total). Note: It's best to have the Decider go last.
• Voting: All the Sprint participants get one red dot (the Decider gets 2) to vote on the flow row they think is the best foundation for the prototype.
• After everyone has voted the Decider will vote on the row they think is best with one dot using the second dot to, optionally, vote on an element of another flow they think should be incorporated into the prototype. (5 mins)
• If the second dot is used copy the specific sticky into the main flow voted by the Decider. | +| Storyboard | 45 mins | Mural | • Copy the winning flow from the User Test Flow exercise to the Storyboard/Prototype section placing each individual post-it note into its own container.
• Look at the sketch concepts and move over any relevant screens that fulfill the needs of the sticky note in that container. You can move the entire concept or screen capture cut/paste parts of concepts. Note: Don’t add any unnecessary details or ideas that aren’t needed for the end result prototype
• Fill in the details that are required for each step described in the sticky. | +| Recap day | 5 mins | Mural, Zoom | Summarise activities of the day and decisions. Brief walkthrough of the next day's activities and wrap up the day. | + +### Day 4 + | Activity | Duration | Tool | Description | +|---|---|---|---| +| Validate Prototype | 30 mins | Mural | • Go through the Prototype created by the Product designer or Front end developer and discuss any inaccuracies or missing content. | +| Wrap up the Sprint | 15 mins | Zoom, GitLab | • Recap the Sprint and discuss next steps. Create user testing issues. | + +### Day 5 + | Activity | Duration | Tool | Description | +|---|---|---|---| +| Prototype testing with 5 users | ~45 mins | Figma or code/Zoom | • Test the prototype with users. | + +## Ground Rules +* Honor the Facilitator's directions. They're the guide for the entire process. +* Minimise distractions: During the week you will need to dedicate some hours to the Sprint for async tasks and sync video conferences. During this time we recommend blocking time in your calendar and having devices or apps with notifications turned off during that time. +* All opinions are valid and are equally important, however, the Decider has the ultimate, final decision. +* Everyone is an active participant in a sync activity (with the exception of the Observers). +* One conversation at a time. +* Document as much as you can: We should have concrete outputs to share with broader team. Also interesting ideas or fixes should be documented to be transferred in issues for our backlog. +* Stick to scheduled breaks during sync calls. The Facilitator will guide each session and set break times. +* The Sprint is one of the few chances we get to work so closely together. Have fun! diff --git a/.gitlab/issue_templates/Feature proposal.md b/.gitlab/issue_templates/Feature proposal.md index 5ab46bfa26..66450c37a2 100644 --- a/.gitlab/issue_templates/Feature proposal.md +++ b/.gitlab/issue_templates/Feature proposal.md @@ -77,6 +77,15 @@ Please list the test areas (unit, integration and end-to-end) that needs to be a See the test engineering planning process and reach out to your counterpart Software Engineer in Test for assistance: https://about.gitlab.com/handbook/engineering/quality/test-engineering/#test-planning --> +### Available Tier + + + ### What does success look like, and how can we measure that? -
- - - {{ $options.i18n.integrationFormSteps.opsgenie.info }} - - - - - - - - {{ $options.i18n.integrationFormSteps.prometheusFormUrl.help }} - - -
-
+
{{ s__('AlertSettings|Save integration') }} - {{ s__('AlertSettings|Save and test payload') }} - {{ __('Cancel') }} + {{ __('Cancel') }}
diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue index a55e63c3bc..d0cac066ff 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue @@ -1,5 +1,4 @@ + + diff --git a/app/assets/javascripts/authentication/u2f/authenticate.js b/app/assets/javascripts/authentication/u2f/authenticate.js index f9b5ca3e5b..f5217e9c9b 100644 --- a/app/assets/javascripts/authentication/u2f/authenticate.js +++ b/app/assets/javascripts/authentication/u2f/authenticate.js @@ -37,7 +37,7 @@ export default class U2FAuthenticate { // Note: The server library fixes this behaviour in (unreleased) version 1.0.0. // This can be removed once we upgrade. // https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4 - this.signRequests = u2fParams.sign_requests.map(request => omit(request, 'challenge')); + this.signRequests = u2fParams.sign_requests.map((request) => omit(request, 'challenge')); this.templates = { inProgress: '#js-authenticate-token-2fa-in-progress', @@ -48,7 +48,7 @@ export default class U2FAuthenticate { start() { return importU2FLibrary() - .then(utils => { + .then((utils) => { this.u2fUtils = utils; this.renderInProgress(); }) @@ -60,7 +60,7 @@ export default class U2FAuthenticate { this.appId, this.challenge, this.signRequests, - response => { + (response) => { if (response.errorCode) { const error = new U2FError(response.errorCode, 'authenticate'); return this.renderError(error); diff --git a/app/assets/javascripts/authentication/u2f/register.js b/app/assets/javascripts/authentication/u2f/register.js index 9773a9185f..52940e1c30 100644 --- a/app/assets/javascripts/authentication/u2f/register.js +++ b/app/assets/javascripts/authentication/u2f/register.js @@ -34,7 +34,7 @@ export default class U2FRegister { start() { return importU2FLibrary() - .then(utils => { + .then((utils) => { this.u2fUtils = utils; this.renderSetup(); }) @@ -46,7 +46,7 @@ export default class U2FRegister { this.appId, this.registerRequests, this.signRequests, - response => { + (response) => { if (response.errorCode) { const error = new U2FError(response.errorCode, 'register'); return this.renderError(error); diff --git a/app/assets/javascripts/authentication/webauthn/authenticate.js b/app/assets/javascripts/authentication/webauthn/authenticate.js index 42c4c2b63b..47cb7a40f7 100644 --- a/app/assets/javascripts/authentication/webauthn/authenticate.js +++ b/app/assets/javascripts/authentication/webauthn/authenticate.js @@ -39,11 +39,11 @@ export default class WebAuthnAuthenticate { authenticate() { navigator.credentials .get({ publicKey: this.webauthnParams }) - .then(resp => { + .then((resp) => { const convertedResponse = convertGetResponse(resp); this.renderAuthenticated(JSON.stringify(convertedResponse)); }) - .catch(err => { + .catch((err) => { this.flow.renderError(new WebAuthnError(err, 'authenticate')); }); } diff --git a/app/assets/javascripts/authentication/webauthn/register.js b/app/assets/javascripts/authentication/webauthn/register.js index 06e4ffd6f3..62ebf85abe 100644 --- a/app/assets/javascripts/authentication/webauthn/register.js +++ b/app/assets/javascripts/authentication/webauthn/register.js @@ -39,8 +39,8 @@ export default class WebAuthnRegister { .create({ publicKey: this.webauthnOptions, }) - .then(cred => this.renderRegistered(JSON.stringify(convertCreateResponse(cred)))) - .catch(err => this.flow.renderError(new WebAuthnError(err, 'register'))); + .then((cred) => this.renderRegistered(JSON.stringify(convertCreateResponse(cred)))) + .catch((err) => this.flow.renderError(new WebAuthnError(err, 'register'))); } renderSetup() { diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index d937060536..22717a3f84 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -56,13 +56,13 @@ export class AwardsHandler { } }, ); - this.registerEventListener('on', $parentEl, 'click', this.toggleButtonSelector, e => { + this.registerEventListener('on', $parentEl, 'click', this.toggleButtonSelector, (e) => { e.stopPropagation(); e.preventDefault(); this.showEmojiMenu($(e.currentTarget)); }); - this.registerEventListener('on', $('html'), 'click', e => { + this.registerEventListener('on', $('html'), 'click', (e) => { const $target = $(e.target); if (!$target.closest(`.${this.menuClass}`).length) { $('.js-awards-block.current').removeClass('current'); @@ -74,7 +74,7 @@ export class AwardsHandler { }); const emojiButtonSelector = `.js-awards-block .js-emoji-btn, .${this.menuClass} .js-emoji-btn`; - this.registerEventListener('on', $parentEl, 'click', emojiButtonSelector, e => { + this.registerEventListener('on', $parentEl, 'click', emojiButtonSelector, (e) => { e.preventDefault(); const $target = $(e.currentTarget); const $glEmojiElement = $target.find('gl-emoji'); @@ -98,10 +98,7 @@ export class AwardsHandler { showEmojiMenu($addBtn) { if ($addBtn.hasClass('js-note-emoji')) { - $addBtn - .closest('.note') - .find('.js-awards-block') - .addClass('current'); + $addBtn.closest('.note').find('.js-awards-block').addClass('current'); } else { $addBtn.closest('.js-awards-block').addClass('current'); } @@ -193,7 +190,7 @@ export class AwardsHandler { (promiseChain, categoryNameKey) => promiseChain.then( () => - new Promise(resolve => { + new Promise((resolve) => { const emojisInCategory = categoryMap[categoryNameKey]; const categoryMarkup = this.renderCategory( categoryLabelMap[categoryNameKey], @@ -216,7 +213,7 @@ export class AwardsHandler { menu.dispatchEvent(new CustomEvent('build-emoji-menu-finish')); } }) - .catch(err => { + .catch((err) => { emojiContentElement.insertAdjacentHTML( 'beforeend', '

We encountered an error while adding the remaining categories

', @@ -233,7 +230,7 @@ export class AwardsHandler {
@@ -198,7 +198,7 @@ export default { required @input="debouncedPreview" /> -
{{ s__('Badges|Please fill in a valid URL') }}
+
{{ s__('Badges|Enter a valid URL') }}
{{ badgeImageUrlExample }} diff --git a/app/assets/javascripts/badges/components/badge_settings.vue b/app/assets/javascripts/badges/components/badge_settings.vue index 1978178310..73c63a72b1 100644 --- a/app/assets/javascripts/badges/components/badge_settings.vue +++ b/app/assets/javascripts/badges/components/badge_settings.vue @@ -42,7 +42,7 @@ export default { .then(() => { createFlash(s__('Badges|The badge was deleted.'), 'notice'); }) - .catch(error => { + .catch((error) => { createFlash(s__('Badges|Deleting the badge failed, please try again.')); throw error; }); diff --git a/app/assets/javascripts/badges/store/actions.js b/app/assets/javascripts/badges/store/actions.js index 806c2423e7..3377f6c099 100644 --- a/app/assets/javascripts/badges/store/actions.js +++ b/app/assets/javascripts/badges/store/actions.js @@ -2,7 +2,7 @@ import axios from '~/lib/utils/axios_utils'; import types from './mutation_types'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -export const transformBackendBadge = badge => ({ +export const transformBackendBadge = (badge) => ({ ...convertObjectPropsToCamelCase(badge, true), isDeleting: false, }); @@ -27,11 +27,11 @@ export default { image_url: newBadge.imageUrl, link_url: newBadge.linkUrl, }) - .catch(error => { + .catch((error) => { dispatch('receiveNewBadgeError'); throw error; }) - .then(res => { + .then((res) => { dispatch('receiveNewBadge', transformBackendBadge(res.data)); }); }, @@ -50,7 +50,7 @@ export default { const endpoint = `${state.apiEndpointUrl}/${badgeId}`; return axios .delete(endpoint) - .catch(error => { + .catch((error) => { dispatch('receiveDeleteBadgeError', badgeId); throw error; }) @@ -78,11 +78,11 @@ export default { const endpoint = state.apiEndpointUrl; return axios .get(endpoint) - .catch(error => { + .catch((error) => { dispatch('receiveLoadBadgesError'); throw error; }) - .then(res => { + .then((res) => { dispatch('receiveLoadBadges', res.data.map(transformBackendBadge)); }); }, @@ -113,11 +113,11 @@ export default { const renderEndpoint = `${state.apiEndpointUrl}/render?${parameters}`; return axios .get(renderEndpoint) - .catch(error => { + .catch((error) => { dispatch('receiveRenderedBadgeError'); throw error; }) - .then(res => { + .then((res) => { dispatch('receiveRenderedBadge', transformBackendBadge(res.data)); }); }, @@ -142,11 +142,11 @@ export default { image_url: badge.imageUrl, link_url: badge.linkUrl, }) - .catch(error => { + .catch((error) => { dispatch('receiveUpdatedBadgeError'); throw error; }) - .then(res => { + .then((res) => { dispatch('receiveUpdatedBadge', transformBackendBadge(res.data)); }); }, diff --git a/app/assets/javascripts/badges/store/mutations.js b/app/assets/javascripts/badges/store/mutations.js index bd84e68c00..3f4689aeb1 100644 --- a/app/assets/javascripts/badges/store/mutations.js +++ b/app/assets/javascripts/badges/store/mutations.js @@ -1,7 +1,7 @@ import types from './mutation_types'; import { PROJECT_BADGE } from '../constants'; -const reorderBadges = badges => +const reorderBadges = (badges) => badges.sort((a, b) => { if (a.kind !== b.kind) { return a.kind === PROJECT_BADGE ? 1 : -1; @@ -31,7 +31,7 @@ export default { }, [types.RECEIVE_UPDATED_BADGE](state, updatedBadge) { - const badges = state.badges.map(badge => { + const badges = state.badges.map((badge) => { if (badge.id === updatedBadge.id) { return updatedBadge; } @@ -77,13 +77,13 @@ export default { }, [types.RECEIVE_DELETE_BADGE](state, badgeId) { - const badges = state.badges.filter(badge => badge.id !== badgeId); + const badges = state.badges.filter((badge) => badge.id !== badgeId); Object.assign(state, { badges, }); }, [types.RECEIVE_DELETE_BADGE_ERROR](state, badgeId) { - const badges = state.badges.map(badge => { + const badges = state.badges.map((badge) => { if (badge.id === badgeId) { return { ...badge, @@ -98,7 +98,7 @@ export default { }); }, [types.REQUEST_DELETE_BADGE](state, badgeId) { - const badges = state.badges.map(badge => { + const badges = state.badges.map((badge) => { if (badge.id === badgeId) { return { ...badge, diff --git a/app/assets/javascripts/batch_comments/components/preview_item.vue b/app/assets/javascripts/batch_comments/components/preview_item.vue index dca6d90fbc..3e93168f0e 100644 --- a/app/assets/javascripts/batch_comments/components/preview_item.vue +++ b/app/assets/javascripts/batch_comments/components/preview_item.vue @@ -47,7 +47,7 @@ export default { } return sprintf(__("%{authorsName}'s thread"), { - authorsName: this.discussion.notes.find(note => !note.system).author.name, + authorsName: this.discussion.notes.find((note) => !note.system).author.name, }); }, linePosition() { @@ -98,9 +98,7 @@ export default { {{ titleText }}