diff --git a/.eslintrc.yml b/.eslintrc.yml
index 4a7197e3bd5..75dc079cf6e 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -117,6 +117,10 @@ rules:
message: 'Migrate to GlSkeletonLoader, or import GlDeprecatedSkeletonLoading.'
- selector: ImportSpecifier[imported.name='GlSafeHtmlDirective']
message: 'Use directive at ~/vue_shared/directives/safe_html.js instead.'
+ # TODO: Remove this rule once GitLab UI no longer exports the deprecated alias.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/382424.
+ - selector: ImportSpecifier[imported.name='GlListbox']
+ message: 'Import GlCollapsibleListbox instead. The GlListbox name is deprecated.'
# See https://gitlab.com/gitlab-org/gitlab/-/issues/360551
vue/multi-word-component-names: off
unicorn/prefer-dom-node-dataset:
diff --git a/.gitlab/ci/as-if-jh.gitlab-ci.yml b/.gitlab/ci/as-if-jh.gitlab-ci.yml
index 6bd46bee770..73247984589 100644
--- a/.gitlab/ci/as-if-jh.gitlab-ci.yml
+++ b/.gitlab/ci/as-if-jh.gitlab-ci.yml
@@ -35,12 +35,11 @@ prepare-as-if-jh-branch:
- .shared-as-if-jh
- .as-if-jh:rules:prepare-as-if-jh
stage: prepare
+ variables:
+ GIT_DEPTH: "0" # clone the full history so we can push
needs:
- add-jh-files
script:
- # Fetch for the history of the branch so it does not cause the following error:
- # ! [remote rejected] ref -> ref (shallow update not allowed)
- - git fetch --unshallow --filter=tree:0 origin "${CI_COMMIT_SHA}"
- git checkout -b "${AS_IF_JH_BRANCH}"
- git add ${JH_FILES_TO_COMMIT}
- git commit -m 'Add JH files' # TODO: Mark which SHA we add
diff --git a/.gitlab/ci/package-and-test/main.gitlab-ci.yml b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
index 62907acfd57..ff96b077d8d 100644
--- a/.gitlab/ci/package-and-test/main.gitlab-ci.yml
+++ b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
@@ -125,6 +125,7 @@ trigger-omnibus-env:
echo "OMNIBUS_GITLAB_RUBY2_BUILD=${OMNIBUS_GITLAB_RUBY2_BUILD:-false}" >> $BUILD_ENV
echo "OMNIBUS_GITLAB_CACHE_EDITION=${OMNIBUS_GITLAB_CACHE_EDITION:-GITLAB}" >> $BUILD_ENV
echo "GITLAB_ASSETS_TAG=$(assets_image_tag)" >> $BUILD_ENV
+ echo "EE=$([[ $FOSS_ONLY == 'true' ]] && echo 'false' || echo 'true')" >> $BUILD_ENV
echo "Built environment file for omnibus build:"
cat $BUILD_ENV
artifacts:
@@ -156,7 +157,7 @@ trigger-omnibus:
RUBY2_BUILD: $OMNIBUS_GITLAB_RUBY2_BUILD
CACHE_EDITION: $OMNIBUS_GITLAB_CACHE_EDITION
SKIP_QA_TEST: "true"
- ee: "true"
+ ee: $EE
trigger:
project: gitlab-org/build/omnibus-gitlab-mirror
strategy: depend
@@ -203,7 +204,7 @@ cache-gems:
# Run manual quarantine job
# this job requires passing QA_SCENARIO variable
# and optionally QA_TESTS to run specific quarantined tests
-_ee:quarantine:
+_quarantine:
extends:
- .qa
- .rules:test:manual
@@ -216,7 +217,7 @@ _ee:quarantine:
# Temporary test job to support the effort of migrating to Super Sidebar
# https://gitlab.com/groups/gitlab-org/-/epics/9044
-_ee:super-sidebar-nav:
+_super-sidebar-nav:
extends:
- .qa
- .parallel
@@ -239,7 +240,7 @@ _ee:super-sidebar-nav:
# ------------------------------------------
# Run specs with feature flags set to the opposite of the default state
-ee:instance-ff-inverse:
+instance-ff-inverse:
extends:
- .qa
- .parallel
@@ -253,23 +254,23 @@ ee:instance-ff-inverse:
# ------------------------------------------
# Jobs with parallel variant
# ------------------------------------------
-ee:instance-selective:
+instance-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:instance:
+instance:
extends:
- .parallel
- - ee:instance-selective
+ - instance-selective
rules:
- - !reference [.rules:test:feature-flags-set, rules] # always run ee:instance to validate ff change
+ - !reference [.rules:test:feature-flags-set, rules] # always run instance to validate ff change
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:praefect-selective:
+praefect-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Praefect
@@ -277,30 +278,30 @@ ee:praefect-selective:
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:praefect:
+praefect:
extends:
- .parallel
- - ee:praefect-selective
+ - praefect-selective
rules:
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:relative-url-selective:
+relative-url-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::RelativeUrl
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:relative-url:
+relative-url:
extends:
- .parallel
- - ee:relative-url-selective
+ - relative-url-selective
rules:
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:decomposition-single-db-selective:
+decomposition-single-db-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
@@ -308,15 +309,15 @@ ee:decomposition-single-db-selective:
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:decomposition-single-db:
+decomposition-single-db:
extends:
- .parallel
- - ee:decomposition-single-db-selective
+ - decomposition-single-db-selective
rules:
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:decomposition-multiple-db-selective:
+decomposition-multiple-db-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
@@ -325,15 +326,15 @@ ee:decomposition-multiple-db-selective:
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:decomposition-multiple-db:
+decomposition-multiple-db:
extends:
- .parallel
- - ee:decomposition-multiple-db-selective
+ - decomposition-multiple-db-selective
rules:
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
-ee:object-storage-selective:
+object-storage-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
@@ -342,42 +343,42 @@ ee:object-storage-selective:
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::ObjectStorage/
-ee:object-storage:
- extends: ee:object-storage-selective
+object-storage:
+ extends: object-storage-selective
parallel: 2
rules:
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::ObjectStorage/
-ee:object-storage-aws-selective:
- extends: ee:object-storage-selective
+object-storage-aws-selective:
+ extends: object-storage-selective
variables:
AWS_S3_ACCESS_KEY: $QA_AWS_S3_ACCESS_KEY
AWS_S3_BUCKET_NAME: $QA_AWS_S3_BUCKET_NAME
AWS_S3_KEY_ID: $QA_AWS_S3_KEY_ID
AWS_S3_REGION: $QA_AWS_S3_REGION
GITLAB_QA_OPTS: --omnibus-config object_storage_aws
-ee:object-storage-aws:
- extends: ee:object-storage-aws-selective
+object-storage-aws:
+ extends: object-storage-aws-selective
parallel: 2
rules:
- - !reference [ee:object-storage, rules]
+ - !reference [object-storage, rules]
-ee:object-storage-gcs-selective:
- extends: ee:object-storage-selective
+object-storage-gcs-selective:
+ extends: object-storage-selective
variables:
GCS_BUCKET_NAME: $QA_GCS_BUCKET_NAME
GOOGLE_PROJECT: $QA_GOOGLE_PROJECT
GOOGLE_JSON_KEY: $QA_GOOGLE_JSON_KEY
GOOGLE_CLIENT_EMAIL: $QA_GOOGLE_CLIENT_EMAIL
GITLAB_QA_OPTS: --omnibus-config object_storage_gcs
-ee:object-storage-gcs:
- extends: ee:object-storage-gcs-selective
+object-storage-gcs:
+ extends: object-storage-gcs-selective
parallel: 2
rules:
- - !reference [ee:object-storage, rules]
+ - !reference [object-storage, rules]
-ee:packages-selective:
+packages-selective:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
@@ -386,8 +387,8 @@ ee:packages-selective:
rules:
- !reference [.rules:test:qa-selective, rules]
- if: $QA_SUITES =~ /Test::Instance::Packages/
-ee:packages:
- extends: ee:packages-selective
+packages:
+ extends: packages-selective
parallel: 2
rules:
- !reference [.rules:test:qa-parallel, rules]
@@ -396,7 +397,7 @@ ee:packages:
# ------------------------------------------
# Non parallel jobs
# ------------------------------------------
-ee:update-minor:
+update-minor:
extends:
- .qa
- .update-script
@@ -404,11 +405,12 @@ ee:update-minor:
UPDATE_TYPE: minor
QA_RSPEC_TAGS: --tag smoke
rules:
+ - !reference [.rules:test:ee-only, rules]
- !reference [.rules:test:update, rules]
- if: $QA_SUITES =~ /Test::Instance::Smoke/
- !reference [.rules:test:manual, rules]
-ee:update-major:
+update-major:
extends:
- .qa
- .update-script
@@ -416,11 +418,12 @@ ee:update-major:
UPDATE_TYPE: major
QA_RSPEC_TAGS: --tag smoke
rules:
+ - !reference [.rules:test:ee-only, rules]
- !reference [.rules:test:update, rules]
- if: $QA_SUITES =~ /Test::Instance::Smoke/
- !reference [.rules:test:manual, rules]
-ee:gitlab-pages:
+gitlab-pages:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::GitlabPages
@@ -429,7 +432,7 @@ ee:gitlab-pages:
- if: $QA_SUITES =~ /Test::Instance::GitlabPages/
- !reference [.rules:test:manual, rules]
-ee:gitaly-cluster:
+gitaly-cluster:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::GitalyCluster
@@ -438,16 +441,17 @@ ee:gitaly-cluster:
- if: $QA_SUITES =~ /Test::Integration::GitalyCluster/
- !reference [.rules:test:manual, rules]
-ee:group-saml:
+group-saml:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::GroupSAML
rules:
+ - !reference [.rules:test:ee-only, rules]
- !reference [.rules:test:qa, rules]
- if: $QA_SUITES =~ /Test::Integration::GroupSAML/
- !reference [.rules:test:manual, rules]
-ee:instance-saml:
+instance-saml:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::InstanceSAML
@@ -456,7 +460,7 @@ ee:instance-saml:
- if: $QA_SUITES =~ /Test::Integration::InstanceSAML/
- !reference [.rules:test:manual, rules]
-ee:jira:
+jira:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Jira
@@ -467,7 +471,7 @@ ee:jira:
- if: $QA_SUITES =~ /Test::Integration::Jira/
- !reference [.rules:test:manual, rules]
-ee:integrations:
+integrations:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Integrations
@@ -476,7 +480,7 @@ ee:integrations:
- if: $QA_SUITES =~ /Test::Integration::Integrations/
- !reference [.rules:test:manual, rules]
-ee:ldap-no-server:
+ldap-no-server:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::LDAPNoServer
@@ -485,7 +489,7 @@ ee:ldap-no-server:
- if: $QA_SUITES =~ /Test::Integration::LDAPNoServer/
- !reference [.rules:test:manual, rules]
-ee:ldap-tls:
+ldap-tls:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::LDAPTLS
@@ -494,7 +498,7 @@ ee:ldap-tls:
- if: $QA_SUITES =~ /Test::Integration::LDAPTLS/
- !reference [.rules:test:manual, rules]
-ee:ldap-no-tls:
+ldap-no-tls:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::LDAPNoTLS
@@ -503,7 +507,7 @@ ee:ldap-no-tls:
- if: $QA_SUITES =~ /Test::Integration::LDAPNoTLS/
- !reference [.rules:test:manual, rules]
-ee:mtls:
+mtls:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::MTLS
@@ -512,7 +516,7 @@ ee:mtls:
- if: $QA_SUITES =~ /Test::Integration::Mtls/
- !reference [.rules:test:manual, rules]
-ee:mattermost:
+mattermost:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Mattermost
@@ -521,7 +525,7 @@ ee:mattermost:
- if: $QA_SUITES =~ /Test::Integration::Mattermost/
- !reference [.rules:test:manual, rules]
-ee:registry:
+registry:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Registry
@@ -530,7 +534,7 @@ ee:registry:
- if: $QA_SUITES =~ /Test::Integration::Registry/
- !reference [.rules:test:manual, rules]
-ee:registry-with-cdn:
+registry-with-cdn:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::RegistryWithCDN
@@ -547,7 +551,7 @@ ee:registry-with-cdn:
- if: $QA_SUITES =~ /Test::Integration::RegistryWithCDN/
- !reference [.rules:test:manual, rules]
-ee:repository-storage:
+repository-storage:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::RepositoryStorage
@@ -556,7 +560,7 @@ ee:repository-storage:
- if: $QA_SUITES =~ /Test::Instance::RepositoryStorage/
- !reference [.rules:test:manual, rules]
-ee:service-ping-disabled:
+service-ping-disabled:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::ServicePingDisabled
@@ -565,7 +569,7 @@ ee:service-ping-disabled:
- if: $QA_SUITES =~ /Test::Integration::ServicePingDisabled/
- !reference [.rules:test:manual, rules]
-ee:smtp:
+smtp:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::SMTP
@@ -574,7 +578,7 @@ ee:smtp:
- if: $QA_SUITES =~ /Test::Integration::SMTP/
- !reference [.rules:test:manual, rules]
-ee:cloud-activation:
+cloud-activation:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
@@ -584,7 +588,7 @@ ee:cloud-activation:
- if: $QA_SUITES =~ /Test::Instance::CloudActivation/
- !reference [.rules:test:manual, rules]
-ee:large-setup:
+large-setup:
extends: .qa
variables:
QA_SCENARIO: Test::Instance::Image
@@ -594,7 +598,7 @@ ee:large-setup:
- if: $QA_SUITES =~ /Test::Instance::LargeSetup/
- !reference [.rules:test:manual, rules]
-ee:metrics:
+metrics:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Metrics
@@ -603,26 +607,27 @@ ee:metrics:
- if: $QA_SUITES =~ /Test::Instance::Metrics/
- !reference [.rules:test:manual, rules]
-ee:elasticsearch:
+elasticsearch:
extends: .qa
variables:
QA_SCENARIO: "Test::Integration::Elasticsearch"
before_script:
- !reference [.qa, before_script]
rules:
+ - !reference [.rules:test:ee-only, rules]
- !reference [.rules:test:qa, rules]
- if: $QA_SUITES =~ /Test::Integration::Elasticsearch/
- !reference [.rules:test:manual, rules]
-ee:registry-object-storage-tls:
- extends: ee:object-storage-aws-selective
+registry-object-storage-tls:
+ extends: object-storage-aws-selective
variables:
QA_SCENARIO: Test::Integration::RegistryTLS
QA_RSPEC_TAGS: ""
GITLAB_TLS_CERTIFICATE: $QA_GITLAB_TLS_CERTIFICATE
GITLAB_QA_OPTS: --omnibus-config registry_object_storage
-ee:importers:
+importers:
extends: .qa
variables:
QA_SCENARIO: Test::Integration::Import
@@ -655,7 +660,7 @@ e2e-test-report-super-sidebar:
- .generate-allure-report-base
stage: report
needs:
- - _ee:super-sidebar-nav
+ - _super-sidebar-nav
variables:
ALLURE_JOB_NAME: e2e-super-sidebar
ALLURE_RESULTS_GLOB: gitlab-qa-run-*/**/allure-results-super-sidebar
diff --git a/.gitlab/ci/package-and-test/rules.gitlab-ci.yml b/.gitlab/ci/package-and-test/rules.gitlab-ci.yml
index 50b07589040..a371939b536 100644
--- a/.gitlab/ci/package-and-test/rules.gitlab-ci.yml
+++ b/.gitlab/ci/package-and-test/rules.gitlab-ci.yml
@@ -123,6 +123,11 @@
when: never
- !reference [.rules:test:qa, rules]
+.rules:test:ee-only:
+ rules:
+ - if: $FOSS_ONLY == "true"
+ when: never
+
# ------------------------------------------
# Report
# ------------------------------------------
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index aea85dfd084..95ae215d134 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -65,7 +65,7 @@ qa:update-qa-cache:
script:
- echo "Cache has been updated and ready to be uploaded."
-e2e:package-and-test:
+e2e:package-and-test-ee:
extends:
- .production # this makes sure GITLAB_ALLOW_SEPARATE_CI_DATABASE is passed to the child pipeline
- .qa:rules:package-and-test
@@ -82,6 +82,8 @@ e2e:package-and-test:
GITLAB_QA_IMAGE: "${CI_REGISTRY_IMAGE}/gitlab-ee-qa:${CI_COMMIT_SHA}"
RUN_WITH_BUNDLE: "true" # instructs pipeline to install and run gitlab-qa gem via bundler
QA_PATH: qa # sets the optional path for bundler to run from
+ ALLURE_JOB_NAME: e2e-package-and-test
+ QA_RUN_TYPE: e2e-package-and-test
inherit:
variables:
- CHROME_VERSION
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml
index 146522c5e76..75b7808e17e 100644
--- a/.rubocop_todo/layout/argument_alignment.yml
+++ b/.rubocop_todo/layout/argument_alignment.yml
@@ -514,23 +514,6 @@ Layout/ArgumentAlignment:
- 'app/graphql/types/work_items/widgets/start_and_due_date_update_input_type.rb'
- 'app/graphql/types/x509_certificate_type.rb'
- 'app/graphql/types/x509_issuer_type.rb'
- - 'app/helpers/application_helper.rb'
- - 'app/helpers/application_settings_helper.rb'
- - 'app/helpers/blob_helper.rb'
- - 'app/helpers/ci/status_helper.rb'
- - 'app/helpers/commits_helper.rb'
- - 'app/helpers/dashboard_helper.rb'
- - 'app/helpers/events_helper.rb'
- - 'app/helpers/feature_flags_helper.rb'
- - 'app/helpers/issuables_helper.rb'
- - 'app/helpers/mirror_helper.rb'
- - 'app/helpers/notes_helper.rb'
- - 'app/helpers/projects/error_tracking_helper.rb'
- - 'app/helpers/snippets_helper.rb'
- - 'app/helpers/todos_helper.rb'
- - 'app/helpers/users/group_callouts_helper.rb'
- - 'app/helpers/users_helper.rb'
- - 'app/helpers/visibility_level_helper.rb'
- 'app/mailers/emails/projects.rb'
- 'app/mailers/notify.rb'
- 'app/models/abuse_report.rb'
@@ -1182,9 +1165,6 @@ Layout/ArgumentAlignment:
- 'ee/app/graphql/types/work_items/widgets/status_filter_input_type.rb'
- 'ee/app/graphql/types/work_items/widgets/status_input_type.rb'
- 'ee/app/graphql/types/work_items/widgets/weight_input_type.rb'
- - 'ee/app/helpers/billing_plans_helper.rb'
- - 'ee/app/helpers/ee/feature_flags_helper.rb'
- - 'ee/app/helpers/ee/search_helper.rb'
- 'ee/app/mailers/ee/emails/projects.rb'
- 'ee/app/mailers/emails/namespace_storage_usage_mailer.rb'
- 'ee/app/models/approval_wrapped_rule.rb'
diff --git a/.rubocop_todo/rake/require.yml b/.rubocop_todo/rake/require.yml
index 04a474b5fe7..6dc5bfa7abc 100644
--- a/.rubocop_todo/rake/require.yml
+++ b/.rubocop_todo/rake/require.yml
@@ -2,11 +2,6 @@
Rake/Require:
Details: grace period
Exclude:
- - 'lib/tasks/gitlab/docs/redirect.rake'
- - 'lib/tasks/gitlab/graphql.rake'
- - 'lib/tasks/gitlab/lfs/migrate.rake'
- - 'lib/tasks/gitlab/metrics_exporter.rake'
- - 'lib/tasks/gitlab/openapi.rake'
- 'lib/tasks/gitlab/packages/events.rake'
- 'lib/tasks/gitlab/refresh_project_statistics_build_artifacts_size.rake'
- 'lib/tasks/tokens.rake'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index feaf0e9997a..8d00761e265 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,15 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 15.9.3 (2023-03-09)
+
+### Fixed (4 changes)
+
+- [Fix foreign_key_exists? migration helper](gitlab-org/gitlab@7b51239b18779acfe9876fb9467f1231f56d47b4) ([merge request](gitlab-org/gitlab!114005))
+- [Enable Geo::RepositoryRegistrySyncWorker on Geo secondary site](gitlab-org/gitlab@57b542b4377bcc991b65f34a37397ac1d08846d9) ([merge request](gitlab-org/gitlab!114005)) **GitLab Enterprise Edition**
+- [Guard against dropped columns when finalizing user details migration](gitlab-org/gitlab@939d646e2cbbbabf870e15fae384c0380d371111) ([merge request](gitlab-org/gitlab!114005))
+- [Fix object deletion not working with Azure Blob Storage](gitlab-org/gitlab@9515c7a334a43c0e580543029a8da5061bdc19ce) ([merge request](gitlab-org/gitlab!114005))
+
## 15.9.2 (2023-03-02)
### Security (12 changes)
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index ee4721c3ee3..d865354881a 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -2,6 +2,7 @@ import { last } from 'lodash';
import recentSearchesStorageKeys from 'ee_else_ce/filtered_search/recent_searches_storage_keys';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import { createAlert } from '~/alert';
+import { WORKSPACE_PROJECT } from '~/issues/constants';
import {
ENTER_KEY_CODE,
BACKSPACE_KEY_CODE,
@@ -82,7 +83,7 @@ export default class FilteredSearchManager {
);
const fullPath = this.searchHistoryDropdownElement
? this.searchHistoryDropdownElement.dataset.fullPath
- : 'project';
+ : WORKSPACE_PROJECT;
const recentSearchesKey = `${fullPath}-${recentSearchesStorageKeys[this.page]}`;
this.recentSearchesService = new RecentSearchesService(recentSearchesKey);
}
diff --git a/app/assets/javascripts/groups/store/utils.js b/app/assets/javascripts/groups/store/utils.js
index 371b3aa9d52..d4b583483bd 100644
--- a/app/assets/javascripts/groups/store/utils.js
+++ b/app/assets/javascripts/groups/store/utils.js
@@ -1,3 +1,5 @@
+import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
+
export const getGroupItemMicrodata = ({ type }) => {
const defaultMicrodata = {
itemscope: true,
@@ -9,14 +11,14 @@ export const getGroupItemMicrodata = ({ type }) => {
};
switch (type) {
- case 'group':
+ case WORKSPACE_GROUP:
return {
...defaultMicrodata,
itemtype: 'https://schema.org/Organization',
itemprop: 'subOrganization',
imageItemprop: 'logo',
};
- case 'project':
+ case WORKSPACE_PROJECT:
return {
...defaultMicrodata,
itemtype: 'https://schema.org/SoftwareSourceCode',
diff --git a/app/assets/javascripts/issuable/popover/components/mr_popover.vue b/app/assets/javascripts/issuable/popover/components/mr_popover.vue
index 92994809362..af93430963e 100644
--- a/app/assets/javascripts/issuable/popover/components/mr_popover.vue
+++ b/app/assets/javascripts/issuable/popover/components/mr_popover.vue
@@ -1,14 +1,12 @@
@@ -51,7 +54,9 @@ export default {
- {{ item.namespace.fullPath }}
+
+ {{ namespaceFallback(item.namespace) }}
+
diff --git a/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue b/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue
index bc6b5d3176f..0f8ff5291a4 100644
--- a/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue
+++ b/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue
@@ -1,5 +1,5 @@
-
-
+
diff --git a/app/assets/javascripts/vue_shared/plugins/global_toast.js b/app/assets/javascripts/vue_shared/plugins/global_toast.js
index fb52b31c2c8..bfea2bedd40 100644
--- a/app/assets/javascripts/vue_shared/plugins/global_toast.js
+++ b/app/assets/javascripts/vue_shared/plugins/global_toast.js
@@ -2,7 +2,7 @@ import { GlToast } from '@gitlab/ui';
import Vue from 'vue';
Vue.use(GlToast);
-export const instance = new Vue();
+const instance = new Vue();
export default function showGlobalToast(...args) {
return instance.$toast.show(...args);
diff --git a/app/assets/stylesheets/page_bundles/incidents.scss b/app/assets/stylesheets/page_bundles/incidents.scss
index 493add1ea0f..fde35ab3d39 100644
--- a/app/assets/stylesheets/page_bundles/incidents.scss
+++ b/app/assets/stylesheets/page_bundles/incidents.scss
@@ -57,8 +57,6 @@
}
.timeline-entry:not(:last-child) {
- @include gl-pb-0;
-
.timeline-event-border {
@include gl-pb-3;
@include gl-border-gray-50;
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 3639b7f1eea..0dbed262a75 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -1,4 +1,4 @@
-$system-note-icon-size: 2rem;
+$system-note-icon-size: 1.5rem;
$system-note-svg-size: 1rem;
@mixin vertical-line($left) {
@@ -36,6 +36,15 @@ $system-note-svg-size: 1rem;
&.timeline > .timeline-entry {
margin: $gl-padding 0;
+ &.system-note {
+ margin-top: $gl-spacing-scale-1;
+ margin-bottom: 0;
+
+ .note-header-info {
+ padding-left: $gl-spacing-scale-4;
+ }
+ }
+
&.system-note,
&.note-form {
border: 0;
@@ -447,7 +456,7 @@ $system-note-svg-size: 1rem;
height: $system-note-icon-size;
border: 1px solid $gray-50;
border-radius: $system-note-icon-size;
- margin: -6px 0 0;
+ margin: -$gl-spacing-scale-1 0 0 $gl-spacing-scale-2;
svg {
width: $system-note-svg-size;
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index d822a297856..d0602952f9a 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -181,14 +181,14 @@ module ApplicationHelper
css_classes << html_class unless html_class.blank?
content_tag :time, l(time, format: "%b %d, %Y"),
- class: css_classes.join(' '),
- title: l(time.to_time.in_time_zone, format: :timeago_tooltip),
- datetime: time.to_time.getutc.iso8601,
- data: {
- toggle: 'tooltip',
- placement: placement,
- container: 'body'
- }
+ class: css_classes.join(' '),
+ title: l(time.to_time.in_time_zone, format: :timeago_tooltip),
+ datetime: time.to_time.getutc.iso8601,
+ data: {
+ toggle: 'tooltip',
+ placement: placement,
+ container: 'body'
+ }
end
def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', exclude_author: false)
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index dd5f4f17ee2..fde3da77250 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -4,11 +4,11 @@ module ApplicationSettingsHelper
extend self
delegate :allow_signup?,
- :gravatar_enabled?,
- :password_authentication_enabled_for_web?,
- :akismet_enabled?,
- :spam_check_endpoint_enabled?,
- to: :'Gitlab::CurrentSettings.current_application_settings'
+ :gravatar_enabled?,
+ :password_authentication_enabled_for_web?,
+ :akismet_enabled?,
+ :spam_check_endpoint_enabled?,
+ to: :'Gitlab::CurrentSettings.current_application_settings'
def user_oauth_applications?
Gitlab::CurrentSettings.user_oauth_applications
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 281d5c923d0..bb6fd6c3dad 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -2,9 +2,7 @@
module BlobHelper
def edit_blob_path(project = @project, ref = @ref, path = @path, options = {})
- project_edit_blob_path(project,
- tree_join(ref, path),
- options[:link_opts])
+ project_edit_blob_path(project, tree_join(ref, path), options[:link_opts])
end
def ide_edit_path(project = @project, ref = @ref, path = @path)
@@ -52,9 +50,11 @@ module BlobHelper
def fork_path_for_current_user(project, path, with_notice: true)
return unless current_user
- project_forks_path(project,
- namespace_key: current_user.namespace&.id,
- continue: edit_blob_fork_params(path, with_notice: with_notice))
+ project_forks_path(
+ project,
+ namespace_key: current_user.namespace&.id,
+ continue: edit_blob_fork_params(path, with_notice: with_notice)
+ )
end
def encode_ide_path(path)
@@ -66,12 +66,14 @@ module BlobHelper
common_classes = "btn gl-button btn-confirm js-edit-blob gl-ml-3 #{options[:extra_class]}"
- edit_button_tag(blob,
- common_classes,
- _('Edit'),
- edit_blob_path(project, ref, path, options),
- project,
- ref)
+ edit_button_tag(
+ blob,
+ common_classes,
+ _('Edit'),
+ edit_blob_path(project, ref, path, options),
+ project,
+ ref
+ )
end
def can_modify_blob?(blob, project = @project, ref = @ref)
@@ -282,8 +284,8 @@ module BlobHelper
fork_path = project_forks_path(project, namespace_key: current_user.namespace.id, continue: params)
button_tag label,
- class: "#{common_classes} js-edit-blob-link-fork-toggler",
- data: { action: action, fork_path: fork_path }
+ class: "#{common_classes} js-edit-blob-link-fork-toggler",
+ data: { action: action, fork_path: fork_path }
end
def edit_disabled_button_tag(button_text, common_classes)
diff --git a/app/helpers/ci/status_helper.rb b/app/helpers/ci/status_helper.rb
index bca49324a19..ea5b613cb78 100644
--- a/app/helpers/ci/status_helper.rb
+++ b/app/helpers/ci/status_helper.rb
@@ -131,10 +131,10 @@ module Ci
if path
link_to ci_icon_for_status(status, size: icon_size), path,
- class: klass, title: title, data: data
+ class: klass, title: title, data: data
else
content_tag :span, ci_icon_for_status(status, size: icon_size),
- class: klass, title: title, data: data
+ class: klass, title: title, data: data
end
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index f4893a83304..519508f1c02 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -27,12 +27,11 @@ module CommitsHelper
end
def commit_to_html(commit, ref, project)
- render partial: 'projects/commits/commit', formats: :html,
- locals: {
- commit: commit,
- ref: ref,
- project: project
- }
+ render partial: 'projects/commits/commit', formats: :html, locals: {
+ commit: commit,
+ ref: ref,
+ project: project
+ }
end
# Breadcrumb links for a Project and, if applicable, a tree path
@@ -194,10 +193,12 @@ module CommitsHelper
entity = mode == 'raw' ? 'rawButton' : 'renderedButton'
title = "Display #{mode} diff"
- link_to("##{mode}-diff-#{file_hash}",
- class: "btn gl-button btn-default btn-file-option has-tooltip btn-show-#{mode}-diff",
- title: title,
- data: { file_hash: file_hash, diff_toggle_entity: entity }) do
+ link_to(
+ "##{mode}-diff-#{file_hash}",
+ class: "btn gl-button btn-default btn-file-option has-tooltip btn-show-#{mode}-diff",
+ title: title,
+ data: { file_hash: file_hash, diff_toggle_entity: entity }
+ ) do
sprite_icon(icon)
end
end
diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb
index f0e1f252917..7bb382e14df 100644
--- a/app/helpers/dashboard_helper.rb
+++ b/app/helpers/dashboard_helper.rb
@@ -40,9 +40,14 @@ module DashboardHelper
end)
if doc_href.present?
- link_to_doc = link_to(sprite_icon('question'), doc_href,
- class: 'gl-ml-2', title: _('Documentation'),
- target: '_blank', rel: 'noopener noreferrer')
+ link_to_doc = link_to(
+ sprite_icon('question'),
+ doc_href,
+ class: 'gl-ml-2',
+ title: _('Documentation'),
+ target: '_blank',
+ rel: 'noopener noreferrer'
+ )
concat(link_to_doc)
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index bef2da495b0..795d35ec81f 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -29,10 +29,11 @@ module EventsHelper
opened: s_('Event|opened'),
updated: s_('Event|updated'),
'removed due to membership expiration from': s_('Event|removed due to membership expiration from')
- }.merge(localized_push_action_name_map,
- localized_created_project_action_name_map,
- localized_design_action_names
- ).freeze
+ }.merge(
+ localized_push_action_name_map,
+ localized_created_project_action_name_map,
+ localized_design_action_names
+ ).freeze
end
def localized_push_action_name_map
@@ -183,13 +184,11 @@ module EventsHelper
def event_feed_url(event)
if event.issue?
- project_issue_url(event.project,
- event.issue)
+ project_issue_url(event.project, event.issue)
elsif event.merge_request?
project_merge_request_url(event.project, event.merge_request)
elsif event.commit_note?
- project_commit_url(event.project,
- event.note_target)
+ project_commit_url(event.project, event.note_target)
elsif event.note?
if event.note_target
event_note_target_url(event)
@@ -204,16 +203,12 @@ module EventsHelper
def push_event_feed_url(event)
if event.push_with_commits? && event.md_ref?
if event.commits_count > 1
- project_compare_url(event.project,
- from: event.commit_from, to:
- event.commit_to)
+ project_compare_url(event.project, from: event.commit_from, to: event.commit_to)
else
- project_commit_url(event.project,
- id: event.commit_to)
+ project_commit_url(event.project, id: event.commit_to)
end
elsif event.ref_name
- project_commits_url(event.project,
- event.ref_name)
+ project_commits_url(event.project, event.ref_name)
end
end
@@ -241,26 +236,31 @@ module EventsHelper
elsif event.design_note?
design_url(event.note_target, anchor: dom_id(event.note))
else
- polymorphic_url([event.project, event.note_target],
- anchor: dom_id(event.target))
+ polymorphic_url([event.project, event.note_target], anchor: dom_id(event.target))
end
end
def event_wiki_title_html(event)
capture do
concat content_tag(:span, _('wiki page'), class: "event-target-type gl-mr-2")
- concat link_to(event.target_title, event_wiki_page_target_url(event),
- title: event.target_title,
- class: 'has-tooltip event-target-link gl-mr-2')
+ concat link_to(
+ event.target_title,
+ event_wiki_page_target_url(event),
+ title: event.target_title,
+ class: 'has-tooltip event-target-link gl-mr-2'
+ )
end
end
def event_design_title_html(event)
capture do
concat content_tag(:span, _('design'), class: "event-target-type gl-mr-2")
- concat link_to(event.design.reference_link_text, design_url(event.design),
- title: event.target_title,
- class: 'has-tooltip event-design event-target-link gl-mr-2')
+ concat link_to(
+ event.design.reference_link_text,
+ design_url(event.design),
+ title: event.target_title,
+ class: 'has-tooltip event-design event-target-link gl-mr-2'
+ )
end
end
diff --git a/app/helpers/feature_flags_helper.rb b/app/helpers/feature_flags_helper.rb
index 3dde29dce91..fe8d8e6b5d9 100644
--- a/app/helpers/feature_flags_helper.rb
+++ b/app/helpers/feature_flags_helper.rb
@@ -18,8 +18,10 @@ module FeatureFlagsHelper
feature_flags_path: project_feature_flags_path(@project),
environments_endpoint: search_project_environments_path(@project, format: :json),
strategy_type_docs_page_path: help_page_path('operations/feature_flags', anchor: 'feature-flag-strategies'),
- environments_scope_docs_path: help_page_path('ci/environments/index.md',
- anchor: 'limit-the-environment-scope-of-a-cicd-variable')
+ environments_scope_docs_path: help_page_path(
+ 'ci/environments/index.md',
+ anchor: 'limit-the-environment-scope-of-a-cicd-variable'
+ )
}
end
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 0d93aff2bae..9c68f54f42e 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -380,8 +380,10 @@ module IssuablesHelper
end
def hidden_issuable_icon(issuable)
- title = format(_('This %{issuable} is hidden because its author has been banned'),
- issuable: issuable.is_a?(Issue) ? _('issue') : _('merge request'))
+ title = format(
+ _('This %{issuable} is hidden because its author has been banned'),
+ issuable: issuable.is_a?(Issue) ? _('issue') : _('merge request')
+ )
content_tag(:span, class: 'has-tooltip', title: title) do
sprite_icon('spam', css_class: 'gl-vertical-align-text-bottom')
end
diff --git a/app/helpers/mirror_helper.rb b/app/helpers/mirror_helper.rb
index 3dfd30f07db..06deaeb5e9e 100644
--- a/app/helpers/mirror_helper.rb
+++ b/app/helpers/mirror_helper.rb
@@ -13,7 +13,7 @@ module MirrorHelper
docs_link_start = ''.html_safe % { url: docs_link_url }
html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) %
- { docs_link_start: docs_link_start, docs_link_end: ''.html_safe, strong_open: ''.html_safe, strong_close: ''.html_safe }
+ { docs_link_start: docs_link_start, docs_link_end: ''.html_safe, strong_open: ''.html_safe, strong_close: ''.html_safe }
end
end
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index b47f4633348..3df9d68b03e 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -77,8 +77,10 @@ module NotesHelper
line_type: line_type
}
- button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
- data: data, title: 'Add a reply'
+ button_tag 'Reply...',
+ class: 'btn btn-text-field js-discussion-reply-button',
+ data: data,
+ title: 'Add a reply'
end
def note_max_access_for_user(note)
diff --git a/app/helpers/projects/error_tracking_helper.rb b/app/helpers/projects/error_tracking_helper.rb
index 471565d162c..fc4ad10db21 100644
--- a/app/helpers/projects/error_tracking_helper.rb
+++ b/app/helpers/projects/error_tracking_helper.rb
@@ -5,8 +5,7 @@ module Projects::ErrorTrackingHelper
error_tracking_enabled = !!project.error_tracking_setting&.enabled?
{
- 'index-path' => project_error_tracking_index_path(project,
- format: :json),
+ 'index-path' => project_error_tracking_index_path(project, format: :json),
'user-can-enable-error-tracking' => can?(current_user, :admin_operations, project).to_s,
'enable-error-tracking-link' => project_settings_operations_path(project),
'error-tracking-enabled' => error_tracking_enabled.to_s,
diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb
index 8558c664977..2f9117a74be 100644
--- a/app/helpers/snippets_helper.rb
+++ b/app/helpers/snippets_helper.rb
@@ -45,30 +45,35 @@ module SnippetsHelper
def embedded_raw_snippet_button(snippet, blob)
return if blob.empty? || blob.binary? || blob.stored_externally?
- link_to(external_snippet_icon('doc-code'),
- gitlab_raw_snippet_blob_url(snippet, blob.path),
- class: 'gl-button btn btn-default',
- target: '_blank',
- rel: 'noopener noreferrer',
- title: 'Open raw')
+ link_to(
+ external_snippet_icon('doc-code'),
+ gitlab_raw_snippet_blob_url(snippet, blob.path),
+ class: 'gl-button btn btn-default',
+ target: '_blank',
+ rel: 'noopener noreferrer',
+ title: 'Open raw'
+ )
end
def embedded_snippet_download_button(snippet, blob)
- link_to(external_snippet_icon('download'),
- gitlab_raw_snippet_blob_url(snippet, blob.path, nil, inline: false),
- class: 'gl-button btn btn-default',
- target: '_blank',
- title: 'Download',
- rel: 'noopener noreferrer')
+ link_to(
+ external_snippet_icon('download'),
+ gitlab_raw_snippet_blob_url(snippet, blob.path, nil, inline: false),
+ class: 'gl-button btn btn-default',
+ target: '_blank',
+ title: 'Download',
+ rel: 'noopener noreferrer'
+ )
end
def embedded_copy_snippet_button(blob)
return unless blob.rendered_as_text?(ignore_errors: false)
- content_tag(:button,
- class: 'gl-button btn btn-default copy-to-clipboard-btn',
- title: 'Copy snippet contents',
- onclick: "copyToClipboard('.blob-content[data-blob-id=\"#{blob.id}\"] > pre')"
+ content_tag(
+ :button,
+ class: 'gl-button btn btn-default copy-to-clipboard-btn',
+ title: 'Copy snippet contents',
+ onclick: "copyToClipboard('.blob-content[data-blob-id=\"#{blob.id}\"] > pre')"
) do
external_snippet_icon('copy-to-clipboard')
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 4a9dd30a5a2..9b0810f3d17 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -232,13 +232,15 @@ module TodosHelper
''
end
+ due_date =
+ if is_due_today
+ _("today")
+ else
+ l(todo.target.due_date, format: Date::DATE_FORMATS[:medium])
+ end
+
content = content_tag(:span, class: css_class) do
- format(s_("Todos|Due %{due_date}"), due_date: if is_due_today
- _("today")
- else
- l(todo.target.due_date,
- format: Date::DATE_FORMATS[:medium])
- end)
+ format(s_("Todos|Due %{due_date}"), due_date: due_date)
end
"#{content} ·".html_safe
diff --git a/app/helpers/users/group_callouts_helper.rb b/app/helpers/users/group_callouts_helper.rb
index 0aa4eb89499..92cf41400e7 100644
--- a/app/helpers/users/group_callouts_helper.rb
+++ b/app/helpers/users/group_callouts_helper.rb
@@ -17,9 +17,11 @@ module Users
def user_dismissed_for_group(feature_name, group, ignore_dismissal_earlier_than = nil)
return false unless current_user
- current_user.dismissed_callout_for_group?(feature_name: feature_name,
- group: group,
- ignore_dismissal_earlier_than: ignore_dismissal_earlier_than)
+ current_user.dismissed_callout_for_group?(
+ feature_name: feature_name,
+ group: group,
+ ignore_dismissal_earlier_than: ignore_dismissal_earlier_than
+ )
end
def just_created?
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index 4c8765618d0..e0cf7aa61ee 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -16,9 +16,7 @@ module UsersHelper
end
def user_link(user)
- link_to(user.name, user_path(user),
- title: user.email,
- class: 'has-tooltip commit-committer-link')
+ link_to(user.name, user_path(user), title: user.email, class: 'has-tooltip commit-committer-link')
end
def user_email_help_text(user)
@@ -86,9 +84,9 @@ module UsersHelper
return unless user.status
content_tag :span,
- class: 'user-status-emoji has-tooltip',
- title: user.status.message_html,
- data: { html: true, placement: 'top' } do
+ class: 'user-status-emoji has-tooltip',
+ title: user.status.message_html,
+ data: { html: true, placement: 'top' } do
emoji_icon user.status.emoji
end
end
diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb
index 5ed341ee5e5..c577e2da1bb 100644
--- a/app/helpers/visibility_level_helper.rb
+++ b/app/helpers/visibility_level_helper.rb
@@ -44,9 +44,8 @@ module VisibilityLevelHelper
Gitlab::CurrentSettings.restricted_visibility_levels || []
end
- delegate :default_project_visibility,
- :default_group_visibility,
- to: :'Gitlab::CurrentSettings.current_application_settings'
+ delegate :default_project_visibility, :default_group_visibility,
+ to: :'Gitlab::CurrentSettings.current_application_settings'
def disallowed_visibility_level?(form_model, level)
return false unless form_model.respond_to?(:visibility_level_allowed?)
diff --git a/config/feature_flags/development/enforce_max_attachment_size_upload_api.yml b/config/feature_flags/development/enforce_max_attachment_size_upload_api.yml
deleted file mode 100644
index 25e193aa590..00000000000
--- a/config/feature_flags/development/enforce_max_attachment_size_upload_api.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: enforce_max_attachment_size_upload_api
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57250
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/325787
-milestone: '13.11'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 426fd50b98b..ac0c3ea7201 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -331,8 +331,21 @@ module.exports = {
test: /\.(js|cjs)$/,
exclude: (modulePath) =>
/node_modules|vendor[\\/]assets/.test(modulePath) && !/\.vue\.js/.test(modulePath),
- loader: 'babel-loader',
- options: defaultJsOptions,
+ use: [
+ {
+ loader: 'thread-loader',
+ options: {
+ workerParallelJobs: 20,
+ poolRespawn: false,
+ poolParallelJobs: 200,
+ poolTimeout: DEV_SERVER_LIVERELOAD ? Infinity : 5000,
+ },
+ },
+ {
+ loader: 'babel-loader',
+ options: defaultJsOptions,
+ },
+ ],
},
WEBPACK_USE_ESBUILD_LOADER && {
test: /\.(js|cjs)$/,
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index ff0b8ecf178..c4e2c352e9b 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -8,6 +8,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Uploads represent all user data that may be sent to GitLab as a single file. For example, avatars and note attachments are uploads. Uploads are integral to GitLab functionality and therefore cannot be disabled.
+NOTE:
+Attachments added to comments or descriptions are deleted **only** when the parent project or group
+is deleted. Attachments remain in file storage even when the comment or resource (like issue, merge
+request, epic) where they were uploaded is deleted.
+
## Using local storage
This is the default configuration. To change the location where the uploads are
diff --git a/doc/api/projects.md b/doc/api/projects.md
index c8755e020a7..24d06caf84b 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -2245,9 +2245,12 @@ POST /projects/:id/restore
## Upload a file
+> - Maximum attachment size enforcement [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57250) in GitLab 13.11 [with a flag](../administration/feature_flags.md) named `enforce_max_attachment_size_upload_api`. Disabled by default.
+> - Maximum attachment size [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62542) in GitLab 13.11.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112450) in GitLab 15.10. Feature flag `enforce_max_attachment_size_upload_api` removed.
+
Uploads a file to the specified project to be used in an issue or merge request
-description, or a comment. GitLab versions 14.0 and later
-[enforce](#max-attachment-size-enforcement) this limit.
+description, or a comment.
```plaintext
POST /projects/:id/uploads
@@ -2283,42 +2286,6 @@ The returned `url` is relative to the project path. The returned `full_path` is
the absolute path to the file. In Markdown contexts, the link is expanded when
the format in `markdown` is used.
-### Max attachment size enforcement
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57250) in GitLab 13.11.
-
-GitLab 13.11 added enforcement of the [maximum attachment size limit](../user/admin_area/settings/account_and_limit_settings.md#max-attachment-size) behind the `enforce_max_attachment_size_upload_api` feature flag. GitLab 14.0 enables this by default.
-To disable this enforcement:
-
-**In Omnibus installations:**
-
-1. Enter the Rails console:
-
- ```shell
- sudo gitlab-rails console
- ```
-
-1. Disable the feature flag:
-
- ```ruby
- Feature.disable(:enforce_max_attachment_size_upload_api)
- ```
-
-**In installations from source:**
-
-1. Enter the Rails console:
-
- ```shell
- cd /home/git/gitlab
- sudo -u git -H bundle exec rails console -e production
- ```
-
-1. Disable the feature flag:
-
- ```ruby
- Feature.disable(:enforce_max_attachment_size_upload_api)
- ```
-
## Upload a project avatar
Uploads an avatar to the specified project.
diff --git a/doc/user/analytics/value_streams_dashboard.md b/doc/user/analytics/value_streams_dashboard.md
index a17d9cb090b..71931639b0b 100644
--- a/doc/user/analytics/value_streams_dashboard.md
+++ b/doc/user/analytics/value_streams_dashboard.md
@@ -51,7 +51,7 @@ that are the largest value contributors, overperforming, or underperforming.
You can also drill down the metrics for further analysis.
When you hover over a metric, a tooltip displays an explanation of the metric and a link to the related documentation page.
-## Customize the dashboard widgets
+## Customize the dashboard panels
You can customize the Value Streams Dashboard and configure what subgroups and projects to include in the page.
@@ -59,7 +59,7 @@ A view can display maximum four subgroups or projects.
To display multiple subgroups and projects, specify their path as a URL parameter.
-For example, the parameter `query=gitlab-org/gitlab-foss,gitlab-org/gitlab,gitlab-org/gitlab-design,gitlab-org/gitlab-docs` displays three separate widgets, one each for the:
+For example, the parameter `query=gitlab-org/gitlab-foss,gitlab-org/gitlab,gitlab-org/gitlab-design,gitlab-org/gitlab-docs` displays three separate panels, one each for the:
- `gitlab-org` group
- `gitlab-ui` project
diff --git a/doc/user/clusters/agent/gitops/flux_tutorial.md b/doc/user/clusters/agent/gitops/flux_tutorial.md
index 3c30e466110..b3ef9d174d9 100644
--- a/doc/user/clusters/agent/gitops/flux_tutorial.md
+++ b/doc/user/clusters/agent/gitops/flux_tutorial.md
@@ -64,31 +64,31 @@ Next, create a repository for your Kubernetes manifests:
1. In GitLab, create a new repository called `web-app-manifests`.
1. Add a file to `web-app-manifests` named `nginx-deployment.yaml` with the following contents:
-```yaml
-apiVersion: apps/v1
+ ```yaml
+ apiVersion: apps/v1
-kind: Deployment
+ kind: Deployment
-metadata:
- name: nginx-deployment
- labels:
- app: nginx
-spec:
- replicas: 3
- selector:
- matchLabels:
- app: nginx
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:1.14.2
- ports:
- - containerPort: 80
-```
+ metadata:
+ name: nginx-deployment
+ labels:
+ app: nginx
+ spec:
+ replicas: 3
+ selector:
+ matchLabels:
+ app: nginx
+ template:
+ metadata:
+ labels:
+ app: nginx
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:1.14.2
+ ports:
+ - containerPort: 80
+ ```
1. In the new repository, [create a deploy token](../../../project/deploy_tokens/index.md#create-a-deploy-token) with only the **read_repository** scope.
1. Store your deploy token username and password somewhere safe.
diff --git a/doc/user/img/observability_copy_shortened_link.png b/doc/user/img/observability_copy_shortened_link.png
new file mode 100644
index 00000000000..217e56972cc
Binary files /dev/null and b/doc/user/img/observability_copy_shortened_link.png differ
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 057e080dff0..00eec78e896 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -673,11 +673,23 @@ For example, a reference like `#123+s` is rendered as
URL references like `https://gitlab.com/gitlab-org/gitlab/-/issues/1234+s` are also expanded.
-### Embedding metrics in GitLab Flavored Markdown
+### Embedding metrics
Metric charts can be embedded in GitLab Flavored Markdown. Read
[Embedding Metrics in GitLab flavored Markdown](../operations/metrics/embed.md) for more details.
+### Embedding Observability dashboards
+
+You can embed GitLab Observability UI dashboards descriptions and comments, for example in epics, issues, and MRs.
+
+To embed an Observability dashboard URL:
+
+1. In GitLab Observability UI, in the upper-right corner, select **Copy shortened link**.
+
+ 
+
+1. Paste your link wherever you want to embed your dashboard. GitLab Flavored Markdown recognizes the URL and displays the source.
+
## Features extended from standard Markdown
All standard Markdown formatting should work as expected in GitLab. Some standard
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index b39444f642f..c32f61c6704 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -80,9 +80,8 @@ module API
# Temporarily introduced for upload API: https://gitlab.com/gitlab-org/gitlab/-/issues/325788
def project_attachment_size(user_project)
return PROJECT_ATTACHMENT_SIZE_EXEMPT if exempt_from_global_attachment_size?(user_project)
- return user_project.max_attachment_size if Feature.enabled?(:enforce_max_attachment_size_upload_api, user_project)
- PROJECT_ATTACHMENT_SIZE_EXEMPT
+ user_project.max_attachment_size
end
# This is to help determine which projects to use in https://gitlab.com/gitlab-org/gitlab/-/issues/325788
diff --git a/lib/tasks/gitlab/docs/redirect.rake b/lib/tasks/gitlab/docs/redirect.rake
index 2d234fcdb36..35e0d083210 100644
--- a/lib/tasks/gitlab/docs/redirect.rake
+++ b/lib/tasks/gitlab/docs/redirect.rake
@@ -1,12 +1,13 @@
# frozen_string_literal: true
-require 'date'
-require 'pathname'
-require "yaml"
#
# https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page
#
namespace :gitlab do
+ require 'date'
+ require 'pathname'
+ require 'yaml'
+
namespace :docs do
desc 'GitLab | Docs | Create a doc redirect'
task :redirect, [:old_path, :new_path] do |_, args|
diff --git a/lib/tasks/gitlab/graphql.rake b/lib/tasks/gitlab/graphql.rake
index a05b749a60e..f54579bd939 100644
--- a/lib/tasks/gitlab/graphql.rake
+++ b/lib/tasks/gitlab/graphql.rake
@@ -2,10 +2,10 @@
return if Rails.env.production?
-require 'graphql/rake_task'
-require_relative '../../../tooling/graphql/docs/renderer'
-
namespace :gitlab do
+ require 'graphql/rake_task'
+ require_relative '../../../tooling/graphql/docs/renderer'
+
OUTPUT_DIR = Rails.root.join("doc/api/graphql/reference")
TEMP_SCHEMA_DIR = Rails.root.join('tmp/tests/graphql')
TEMPLATES_DIR = 'tooling/graphql/docs/templates/'
diff --git a/lib/tasks/gitlab/lfs/migrate.rake b/lib/tasks/gitlab/lfs/migrate.rake
index 47f9e1dfb32..19de45dca17 100644
--- a/lib/tasks/gitlab/lfs/migrate.rake
+++ b/lib/tasks/gitlab/lfs/migrate.rake
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require 'logger'
-
desc "GitLab | LFS | Migrate LFS objects to remote storage"
namespace :gitlab do
+ require 'logger'
+
namespace :lfs do
task migrate: :environment do
logger = Logger.new($stdout)
diff --git a/lib/tasks/gitlab/metrics_exporter.rake b/lib/tasks/gitlab/metrics_exporter.rake
index d9dd80b8eeb..70719648fc5 100644
--- a/lib/tasks/gitlab/metrics_exporter.rake
+++ b/lib/tasks/gitlab/metrics_exporter.rake
@@ -1,8 +1,9 @@
# frozen_string_literal: true
-require_relative Rails.root.join('metrics_server', 'dependencies')
-require_relative Rails.root.join('metrics_server', 'metrics_server')
namespace :gitlab do
+ require_relative Rails.root.join('metrics_server', 'dependencies')
+ require_relative Rails.root.join('metrics_server', 'metrics_server')
+
namespace :metrics_exporter do
REPO = 'https://gitlab.com/gitlab-org/gitlab-metrics-exporter.git'
diff --git a/lib/tasks/gitlab/openapi.rake b/lib/tasks/gitlab/openapi.rake
index dee365de11c..c9aec6a112a 100644
--- a/lib/tasks/gitlab/openapi.rake
+++ b/lib/tasks/gitlab/openapi.rake
@@ -1,13 +1,13 @@
# frozen_string_literal: true
-require 'logger'
-
if Rails.env.development?
require 'grape-swagger/rake/oapi_tasks'
GrapeSwagger::Rake::OapiTasks.new('::API::API')
end
namespace :gitlab do
+ require 'logger'
+
namespace :openapi do
task :validate do
raise 'This task can only be run in the development environment' unless Rails.env.development?
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ff18f75eafe..26759e42d64 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -15961,6 +15961,9 @@ msgstr ""
msgid "Enter Admin Mode"
msgstr ""
+msgid "Enter a name for your saved reply"
+msgstr ""
+
msgid "Enter a number"
msgstr ""
diff --git a/package.json b/package.json
index c4d738429d3..dc30f13cfc4 100644
--- a/package.json
+++ b/package.json
@@ -178,6 +178,7 @@
"string-hash": "1.1.3",
"style-loader": "^2.0.0",
"swagger-ui-dist": "4.12.0",
+ "thread-loader": "^3.0.4",
"three": "^0.143.0",
"timeago.js": "^4.0.2",
"tippy.js": "^6.3.7",
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
index f92bdf74695..e726f7a316f 100644
--- a/qa/qa/runtime/allure_report.rb
+++ b/qa/qa/runtime/allure_report.rb
@@ -25,9 +25,6 @@ module QA
#
# @return [void]
def configure_allure
- # Match job names like ee:relative, ce:update etc. and set as execution environment
- env_matcher = /^(?\w{2}:\S+)/
-
AllureRspec.configure do |config|
config.results_directory = ENV['QA_ALLURE_RESULTS_DIRECTORY'] || 'tmp/allure-results'
config.clean_results_directory = true
@@ -38,11 +35,11 @@ module QA
config.issue_tag = :issue
config.link_issue_pattern = '{}'
- config.environment_properties = environment_info if Env.running_in_ci?
-
- # Set custom environment name to separate same specs executed on different environments
- if Env.running_in_ci? && Env.ci_job_name.match?(env_matcher)
- config.environment = Env.ci_job_name.match(env_matcher).named_captures['env']
+ if Env.running_in_ci?
+ config.environment_properties = environment_info
+ # Set custom environment name to separate same specs executed in different jobs
+ # Drop number postfixes from parallel jobs by only matching non whitespace characters
+ config.environment = Env.ci_job_name.match(/^\S+/)[0]
end
end
end
diff --git a/scripts/generate-e2e-pipeline b/scripts/generate-e2e-pipeline
index ab9c432f459..1d4ecf6619d 100755
--- a/scripts/generate-e2e-pipeline
+++ b/scripts/generate-e2e-pipeline
@@ -44,8 +44,6 @@ echo "$variables" >>"$REVIEW_PIPELINE_YML"
cp .gitlab/ci/package-and-test/main.gitlab-ci.yml "$OMNIBUS_PIPELINE_YML"
echo "$variables" >>"$OMNIBUS_PIPELINE_YML"
-echo " ALLURE_JOB_NAME: e2e-package-and-test" >>"$OMNIBUS_PIPELINE_YML"
-echo " QA_RUN_TYPE: e2e-package-and-test" >>"$OMNIBUS_PIPELINE_YML"
echo "Successfully generated review-app and package-and-test pipeline with following variables section:"
echo "$variables"
diff --git a/spec/frontend/ci/pipeline_new/components/refs_dropdown_spec.js b/spec/frontend/ci/pipeline_new/components/refs_dropdown_spec.js
index bec9e6947f3..60ace483712 100644
--- a/spec/frontend/ci/pipeline_new/components/refs_dropdown_spec.js
+++ b/spec/frontend/ci/pipeline_new/components/refs_dropdown_spec.js
@@ -1,4 +1,4 @@
-import { GlListbox, GlListboxItem } from '@gitlab/ui';
+import { GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -19,7 +19,7 @@ describe('Pipeline New Form', () => {
let wrapper;
let mock;
- const findDropdown = () => wrapper.findComponent(GlListbox);
+ const findDropdown = () => wrapper.findComponent(GlCollapsibleListbox);
const findRefsDropdownItems = () => wrapper.findAllComponents(GlListboxItem);
const findSearchBox = () => wrapper.findByTestId('listbox-search-input');
const findListboxGroups = () => wrapper.findAll('ul[role="group"]');
diff --git a/spec/frontend/issues/show/components/fields/type_spec.js b/spec/frontend/issues/show/components/fields/type_spec.js
index cb1be142f75..e655cf3b37d 100644
--- a/spec/frontend/issues/show/components/fields/type_spec.js
+++ b/spec/frontend/issues/show/components/fields/type_spec.js
@@ -1,4 +1,4 @@
-import { GlFormGroup, GlListbox, GlIcon } from '@gitlab/ui';
+import { GlFormGroup, GlCollapsibleListbox, GlIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
@@ -32,7 +32,7 @@ describe('Issue type field component', () => {
},
};
- const findListBox = () => wrapper.findComponent(GlListbox);
+ const findListBox = () => wrapper.findComponent(GlCollapsibleListbox);
const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const findAllIssueItems = () => wrapper.findAll('[data-testid="issue-type-list-item"]');
const findIssueItemAt = (at) => findAllIssueItems().at(at);
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
index 058fed302c9..51445942eaa 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
@@ -4,13 +4,13 @@ import Vue from 'vue';
import { last } from 'lodash';
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import PackagesList from '~/packages_and_registries/infrastructure_registry/list/components/packages_list.vue';
import PackagesListRow from '~/packages_and_registries/infrastructure_registry/shared/package_list_row.vue';
import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue';
import DeletePackageModal from '~/packages_and_registries/shared/components/delete_package_modal.vue';
import { TRACKING_ACTIONS } from '~/packages_and_registries/shared/constants';
import { TRACK_CATEGORY } from '~/packages_and_registries/infrastructure_registry/shared/constants';
-import Tracking from '~/tracking';
import { packageList } from '../../mock_data';
Vue.use(Vuex);
@@ -174,23 +174,23 @@ describe('packages_list', () => {
});
describe('tracking', () => {
- let eventSpy;
+ let trackingSpy = null;
beforeEach(() => {
mountComponent();
- eventSpy = jest.spyOn(Tracking, 'event');
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ itemToBeDeleted: { package_type: 'conan' } });
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
});
- it('deleteItemConfirmation calls event', () => {
- wrapper.vm.deleteItemConfirmation();
- expect(eventSpy).toHaveBeenCalledWith(
- TRACK_CATEGORY,
- TRACKING_ACTIONS.DELETE_PACKAGE,
- expect.any(Object),
- );
+ afterEach(() => {
+ unmockTracking();
+ });
+
+ it('deleteItemConfirmation calls event', async () => {
+ await findPackageListDeleteModal().vm.$emit('ok');
+
+ expect(trackingSpy).toHaveBeenCalledWith(TRACK_CATEGORY, TRACKING_ACTIONS.DELETE_PACKAGE, {
+ category: TRACK_CATEGORY,
+ });
});
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
index 75a9770d5dd..60bb055b1db 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
@@ -4,14 +4,13 @@ import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
+import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import ListPage from '~/packages_and_registries/package_registry/pages/list.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue';
import PackageSearch from '~/packages_and_registries/package_registry/components/list/package_search.vue';
import OriginalPackageList from '~/packages_and_registries/package_registry/components/list/packages_list.vue';
import DeletePackages from '~/packages_and_registries/package_registry/components/functional/delete_packages.vue';
import {
- PROJECT_RESOURCE_TYPE,
- GROUP_RESOURCE_TYPE,
GRAPHQL_PAGE_SIZE,
EMPTY_LIST_HELP_URL,
PACKAGE_HELP_URL,
@@ -167,14 +166,14 @@ describe('PackagesListApp', () => {
});
describe.each`
- type | sortType
- ${PROJECT_RESOURCE_TYPE} | ${'sort'}
- ${GROUP_RESOURCE_TYPE} | ${'groupSort'}
+ type | sortType
+ ${WORKSPACE_PROJECT} | ${'sort'}
+ ${WORKSPACE_GROUP} | ${'groupSort'}
`('$type query', ({ type, sortType }) => {
let provide;
let resolver;
- const isGroupPage = type === GROUP_RESOURCE_TYPE;
+ const isGroupPage = type === WORKSPACE_GROUP;
beforeEach(() => {
provide = { ...defaultProvide, isGroupPage };
diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
index ecf88dbed08..882730d90ae 100644
--- a/spec/frontend/pages/projects/graphs/code_coverage_spec.js
+++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
@@ -1,4 +1,4 @@
-import { GlAlert, GlListbox, GlListboxItem } from '@gitlab/ui';
+import { GlAlert, GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
@@ -22,7 +22,7 @@ describe('Code Coverage', () => {
const findAlert = () => wrapper.findComponent(GlAlert);
const findAreaChart = () => wrapper.findComponent(GlAreaChart);
- const findListBox = () => wrapper.findComponent(GlListbox);
+ const findListBox = () => wrapper.findComponent(GlCollapsibleListbox);
const findListBoxItems = () => wrapper.findAllComponents(GlListboxItem);
const findFirstListBoxItem = () => findListBoxItems().at(0);
const findSecondListBoxItem = () => findListBoxItems().at(1);
@@ -37,7 +37,7 @@ describe('Code Coverage', () => {
graphRef,
graphCsvPath,
},
- stubs: { GlListbox },
+ stubs: { GlCollapsibleListbox },
});
};
diff --git a/spec/frontend/pipelines/nav_controls_spec.js b/spec/frontend/pipelines/nav_controls_spec.js
index f789df74f92..15de7dc51f1 100644
--- a/spec/frontend/pipelines/nav_controls_spec.js
+++ b/spec/frontend/pipelines/nav_controls_spec.js
@@ -1,19 +1,20 @@
-import { shallowMount } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NavControls from '~/pipelines/components/pipelines_list/nav_controls.vue';
describe('Pipelines Nav Controls', () => {
let wrapper;
const createComponent = (props) => {
- wrapper = shallowMount(NavControls, {
+ wrapper = shallowMountExtended(NavControls, {
propsData: {
...props,
},
});
};
- const findRunPipeline = () => wrapper.find('.js-run-pipeline');
+ const findRunPipelineButton = () => wrapper.findByTestId('run-pipeline-button');
+ const findCiLintButton = () => wrapper.findByTestId('ci-lint-button');
+ const findClearCacheButton = () => wrapper.findByTestId('clear-cache-button');
it('should render link to create a new pipeline', () => {
const mockData = {
@@ -24,9 +25,9 @@ describe('Pipelines Nav Controls', () => {
createComponent(mockData);
- const runPipeline = findRunPipeline();
- expect(runPipeline.text()).toContain('Run pipeline');
- expect(runPipeline.attributes('href')).toBe(mockData.newPipelinePath);
+ const runPipelineButton = findRunPipelineButton();
+ expect(runPipelineButton.text()).toContain('Run pipeline');
+ expect(runPipelineButton.attributes('href')).toBe(mockData.newPipelinePath);
});
it('should not render link to create pipeline if no path is provided', () => {
@@ -38,7 +39,7 @@ describe('Pipelines Nav Controls', () => {
createComponent(mockData);
- expect(findRunPipeline().exists()).toBe(false);
+ expect(findRunPipelineButton().exists()).toBe(false);
});
it('should render link for CI lint', () => {
@@ -50,9 +51,10 @@ describe('Pipelines Nav Controls', () => {
};
createComponent(mockData);
+ const ciLintButton = findCiLintButton();
- expect(wrapper.find('.js-ci-lint').text().trim()).toContain('CI lint');
- expect(wrapper.find('.js-ci-lint').attributes('href')).toBe(mockData.ciLintPath);
+ expect(ciLintButton.text()).toContain('CI lint');
+ expect(ciLintButton.attributes('href')).toBe(mockData.ciLintPath);
});
describe('Reset Runners Cache', () => {
@@ -66,16 +68,13 @@ describe('Pipelines Nav Controls', () => {
});
it('should render button for resetting runner caches', () => {
- expect(wrapper.find('.js-clear-cache').text().trim()).toContain('Clear runner caches');
+ expect(findClearCacheButton().text()).toContain('Clear runner caches');
});
- it('should emit postAction event when reset runner cache button is clicked', async () => {
- jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
+ it('should emit postAction event when reset runner cache button is clicked', () => {
+ findClearCacheButton().vm.$emit('click');
- wrapper.find('.js-clear-cache').vm.$emit('click');
- await nextTick();
-
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('resetRunnersCache', 'foo');
+ expect(wrapper.emitted('resetRunnersCache')).toEqual([['foo']]);
});
});
});
diff --git a/spec/frontend/token_access/token_projects_table_spec.js b/spec/frontend/token_access/token_projects_table_spec.js
index b51d8b3ccea..7654aa09b0a 100644
--- a/spec/frontend/token_access/token_projects_table_spec.js
+++ b/spec/frontend/token_access/token_projects_table_spec.js
@@ -6,14 +6,19 @@ import { mockProjects, mockFields } from './mock_data';
describe('Token projects table', () => {
let wrapper;
- const createComponent = () => {
+ const defaultProps = {
+ tableFields: mockFields,
+ projects: mockProjects,
+ };
+
+ const createComponent = (props) => {
wrapper = mountExtended(TokenProjectsTable, {
provide: {
fullPath: 'root/ci-project',
},
propsData: {
- tableFields: mockFields,
- projects: mockProjects,
+ ...defaultProps,
+ ...props,
},
});
};
@@ -25,31 +30,52 @@ describe('Token projects table', () => {
const findProjectNameCell = () => wrapper.findByTestId('token-access-project-name');
const findProjectNamespaceCell = () => wrapper.findByTestId('token-access-project-namespace');
- beforeEach(() => {
- createComponent();
- });
-
it('displays a table', () => {
+ createComponent();
+
expect(findTable().exists()).toBe(true);
});
it('displays the correct amount of table rows', () => {
+ createComponent();
+
expect(findAllTableRows()).toHaveLength(mockProjects.length);
});
it('delete project button emits event with correct project to delete', async () => {
+ createComponent();
+
await findDeleteProjectBtn().trigger('click');
expect(wrapper.emitted('removeProject')).toEqual([[mockProjects[0].fullPath]]);
});
it('does not show the remove icon if the project is locked', () => {
+ createComponent();
+
// currently two mock projects with one being a locked project
expect(findAllDeleteProjectBtn()).toHaveLength(1);
});
it('displays project and namespace cells', () => {
+ createComponent();
+
expect(findProjectNameCell().text()).toBe('merge-train-stuff');
expect(findProjectNamespaceCell().text()).toBe('root');
});
+
+ it('displays empty string for namespace when namespace is null', () => {
+ const nullNamespace = {
+ id: '1',
+ name: 'merge-train-stuff',
+ namespace: null,
+ fullPath: 'root/merge-train-stuff',
+ isLocked: false,
+ __typename: 'Project',
+ };
+
+ createComponent({ projects: [nullNamespace] });
+
+ expect(findProjectNamespaceCell().text()).toBe('');
+ });
});
diff --git a/spec/frontend/vue_shared/components/listbox_input/listbox_input_spec.js b/spec/frontend/vue_shared/components/listbox_input/listbox_input_spec.js
index 7ed6a59c844..4e83f3e1c06 100644
--- a/spec/frontend/vue_shared/components/listbox_input/listbox_input_spec.js
+++ b/spec/frontend/vue_shared/components/listbox_input/listbox_input_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import { GlFormGroup, GlListbox } from '@gitlab/ui';
+import { GlFormGroup, GlCollapsibleListbox } from '@gitlab/ui';
import ListboxInput from '~/vue_shared/components/listbox_input/listbox_input.vue';
describe('ListboxInput', () => {
@@ -27,7 +27,7 @@ describe('ListboxInput', () => {
// Finders
const findGlFormGroup = () => wrapper.findComponent(GlFormGroup);
- const findGlListbox = () => wrapper.findComponent(GlListbox);
+ const findGlListbox = () => wrapper.findComponent(GlCollapsibleListbox);
const findInput = () => wrapper.find('input');
const createComponent = (propsData) => {
@@ -153,7 +153,7 @@ describe('ListboxInput', () => {
expect(findGlListbox().props('searchable')).toBe(true);
});
- it('passes all items to GlListbox by default', () => {
+ it('passes all items to GlCollapsibleListbox by default', () => {
createComponent();
expect(findGlListbox().props('items')).toStrictEqual(items);
diff --git a/spec/frontend/vue_shared/plugins/global_toast_spec.js b/spec/frontend/vue_shared/plugins/global_toast_spec.js
index 322586a772c..0bf2737fb2b 100644
--- a/spec/frontend/vue_shared/plugins/global_toast_spec.js
+++ b/spec/frontend/vue_shared/plugins/global_toast_spec.js
@@ -1,14 +1,16 @@
-import toast, { instance } from '~/vue_shared/plugins/global_toast';
+import toast from '~/vue_shared/plugins/global_toast';
+
+const mockSpy = jest.fn();
+jest.mock('@gitlab/ui', () => ({
+ GlToast: (Vue) => {
+ // eslint-disable-next-line no-param-reassign
+ Vue.prototype.$toast = { show: (...args) => mockSpy(...args) };
+ },
+}));
describe('Global toast', () => {
- let spyFunc;
-
- beforeEach(() => {
- spyFunc = jest.spyOn(instance.$toast, 'show').mockImplementation(() => {});
- });
-
afterEach(() => {
- spyFunc.mockRestore();
+ mockSpy.mockRestore();
});
it("should call GitLab UI's toast method", () => {
@@ -17,7 +19,7 @@ describe('Global toast', () => {
toast(arg1, arg2);
- expect(instance.$toast.show).toHaveBeenCalledTimes(1);
- expect(instance.$toast.show).toHaveBeenCalledWith(arg1, arg2);
+ expect(mockSpy).toHaveBeenCalledTimes(1);
+ expect(mockSpy).toHaveBeenCalledWith(arg1, arg2);
});
});
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 615fe08f5a2..d755a4231da 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -2066,19 +2066,6 @@ RSpec.describe API::Projects, feature_category: :projects do
end
end
- context 'with upload size enforcement disabled' do
- before do
- stub_feature_flags(enforce_max_attachment_size_upload_api: false)
- end
-
- it "returns 200" do
- post api("/projects/#{project.id}/uploads/authorize", user), headers: headers
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['MaximumSize']).to eq(1.gigabyte)
- end
- end
-
context 'with no Workhorse headers' do
it "returns 403" do
post api("/projects/#{project.id}/uploads/authorize", user)
@@ -2155,14 +2142,6 @@ RSpec.describe API::Projects, feature_category: :projects do
it_behaves_like 'capped upload attachments', true
end
-
- context 'with upload size enforcement disabled' do
- before do
- stub_feature_flags(enforce_max_attachment_size_upload_api: false)
- end
-
- it_behaves_like 'capped upload attachments', false
- end
end
describe "GET /projects/:id/groups" do
diff --git a/vendor/gems/cloud_profiler_agent/cloud_profiler_agent.gemspec b/vendor/gems/cloud_profiler_agent/cloud_profiler_agent.gemspec
index cf84c100fc3..82e5041491d 100644
--- a/vendor/gems/cloud_profiler_agent/cloud_profiler_agent.gemspec
+++ b/vendor/gems/cloud_profiler_agent/cloud_profiler_agent.gemspec
@@ -13,8 +13,6 @@ Gem::Specification.new do |spec|
spec.homepage = 'https://github.com/remind101/ruby-cloud-profiler'
spec.license = 'BSD-2-Clause'
- spec.required_ruby_version = '>= 3.0.0'
-
spec.files = ['lib/profile_pb.rb',
'lib/cloud_profiler_agent.rb',
'lib/cloud_profiler_agent/agent.rb',
diff --git a/yarn.lock b/yarn.lock
index b02d803a9a3..51b1723bd28 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8158,6 +8158,11 @@ loader-runner@^2.4.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
+loader-runner@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
+ integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
+
loader-utils@^1.0.0, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
@@ -9378,7 +9383,7 @@ negotiator@0.6.3:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-neo-async@^2.5.0, neo-async@^2.6.1:
+neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
@@ -11808,6 +11813,17 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+thread-loader@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-3.0.4.tgz#c392e4c0241fbc80430eb680e4886819b504a31b"
+ integrity sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==
+ dependencies:
+ json-parse-better-errors "^1.0.2"
+ loader-runner "^4.1.0"
+ loader-utils "^2.0.0"
+ neo-async "^2.6.2"
+ schema-utils "^3.0.0"
+
three@^0.143.0:
version "0.143.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.143.0.tgz#1455bca132cc2b20beb7f41d313e10c29e5ed9df"