Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-03-09 18:08:59 +00:00
parent 0a353a9fa3
commit cc6b6a7b78
79 changed files with 489 additions and 453 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -123,6 +123,11 @@
when: never
- !reference [.rules:test:qa, rules]
.rules:test:ee-only:
rules:
- if: $FOSS_ONLY == "true"
when: never
# ------------------------------------------
# Report
# ------------------------------------------

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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)

View File

@ -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);
}

View File

@ -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',

View File

@ -1,14 +1,12 @@
<script>
/* eslint-disable @gitlab/vue-require-i18n-strings */
import { GlBadge, GlPopover, GlSkeletonLoader } from '@gitlab/ui';
import { STATUS_CLOSED, STATUS_MERGED } from '~/issues/constants';
import { __ } from '~/locale';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { mrStates, humanMRStates } from '../constants';
import query from '../queries/merge_request.query.graphql';
export default {
// name: 'MRPopover' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
name: 'MRPopover', // eslint-disable-line @gitlab/require-i18n-strings
components: {
GlBadge,
GlPopover,
@ -48,9 +46,9 @@ export default {
},
badgeVariant() {
switch (this.mergeRequest.state) {
case mrStates.merged:
case STATUS_MERGED:
return 'info';
case mrStates.closed:
case STATUS_CLOSED:
return 'danger';
default:
return 'success';
@ -58,12 +56,12 @@ export default {
},
stateHumanName() {
switch (this.mergeRequest.state) {
case mrStates.merged:
return humanMRStates.merged;
case mrStates.closed:
return humanMRStates.closed;
case STATUS_MERGED:
return __('Merged');
case STATUS_CLOSED:
return __('Closed');
default:
return humanMRStates.open;
return __('Open');
}
},
title() {
@ -101,7 +99,9 @@ export default {
<gl-badge class="gl-mr-3" :variant="badgeVariant">
{{ stateHumanName }}
</gl-badge>
<span class="gl-text-secondary">Opened <time v-text="formattedTime"></time></span>
<span class="gl-text-secondary">
{{ __('Opened') }} <time v-text="formattedTime"></time
></span>
</div>
<ci-icon v-if="detailedStatus" :status="detailedStatus" />
</div>

View File

@ -1,13 +0,0 @@
import { __ } from '~/locale';
export const mrStates = {
merged: 'merged',
closed: 'closed',
open: 'open',
};
export const humanMRStates = {
merged: __('Merged'),
closed: __('Closed'),
open: __('Open'),
};

View File

@ -1,6 +1,7 @@
import { __ } from '~/locale';
export const STATUS_CLOSED = 'closed';
export const STATUS_MERGED = 'merged';
export const STATUS_OPEN = 'opened';
export const STATUS_REOPENED = 'reopened';

View File

@ -1,5 +1,5 @@
<script>
import { GlFormGroup, GlIcon, GlListbox } from '@gitlab/ui';
import { GlFormGroup, GlIcon, GlCollapsibleListbox } from '@gitlab/ui';
import { TYPE_INCIDENT, TYPE_ISSUE } from '~/issues/constants';
import { __ } from '~/locale';
import { issuableTypes } from '../../constants';
@ -16,7 +16,7 @@ export default {
components: {
GlFormGroup,
GlIcon,
GlListbox,
GlCollapsibleListbox,
},
inject: {
canCreateIncident: {
@ -73,7 +73,7 @@ export default {
label-for="issuable-type"
class="mb-2 mb-md-0"
>
<gl-listbox
<gl-collapsible-listbox
v-model="selectedIssueType"
toggle-class="gl-mb-0"
:items="$options.issuableTypes"
@ -88,6 +88,6 @@ export default {
{{ item.text }}
</span>
</template>
</gl-listbox>
</gl-collapsible-listbox>
</gl-form-group>
</template>

View File

@ -2,6 +2,7 @@ import $ from 'jquery';
import { __ } from '~/locale';
import { fixTitle, hide } from '~/tooltips';
import { createAlert } from '~/alert';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
const tooltipTitles = {
@ -65,7 +66,7 @@ export default class GroupLabelSubscription {
static setNewTooltip($button) {
if (!$button.hasClass('js-subscribe-button')) return;
const type = $button.hasClass('js-group-level') ? 'group' : 'project';
const type = $button.hasClass('js-group-level') ? WORKSPACE_GROUP : WORKSPACE_PROJECT;
const newTitle = tooltipTitles[type];
const $el = $('.js-unsubscribe-button', $button.closest('.label-actions-list'));

View File

@ -1,6 +1,7 @@
import $ from 'jquery';
import { fixTitle } from '~/tooltips';
import { createAlert } from '~/alert';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
@ -68,7 +69,7 @@ export default class ProjectLabelSubscription {
}
static setNewTitle($button, originalTitle, newStatus) {
const type = /group/.test(originalTitle) ? 'group' : 'project';
const type = /group/.test(originalTitle) ? WORKSPACE_GROUP : WORKSPACE_PROJECT;
const newTitle = tooltipTitles[type][newStatus];
$button.attr('title', newTitle);

View File

@ -1,5 +1,5 @@
<script>
import { GlListbox } from '@gitlab/ui';
import { GlCollapsibleListbox } from '@gitlab/ui';
import { debounce } from 'lodash';
import { createAlert } from '~/alert';
import { __ } from '~/locale';
@ -7,7 +7,7 @@ import axios from '~/lib/utils/axios_utils';
export default {
components: {
GlListbox,
GlCollapsibleListbox,
},
props: {
staticData: {
@ -124,7 +124,7 @@ export default {
:name="inputName"
data-testid="target-project-input"
/>
<gl-listbox
<gl-collapsible-listbox
v-model="selected"
:items="filteredData"
:toggle-text="current.text || dropdownHeader"

View File

@ -11,6 +11,7 @@ import {
import { get } from 'lodash';
import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql';
import { createAlert } from '~/alert';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import Tracking from '~/tracking';
import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
@ -145,7 +146,7 @@ export default {
return [];
},
graphqlResource() {
return this.config.isGroupPage ? 'group' : 'project';
return this.config.isGroupPage ? WORKSPACE_GROUP : WORKSPACE_PROJECT;
},
queryVariables() {
return {

View File

@ -145,8 +145,6 @@ export const YARN_PACKAGE_MANAGER = 'yarn';
export const PROJECT_PACKAGE_ENDPOINT_TYPE = 'project';
export const INSTANCE_PACKAGE_ENDPOINT_TYPE = 'instance';
export const PROJECT_RESOURCE_TYPE = 'project';
export const GROUP_RESOURCE_TYPE = 'group';
export const GRAPHQL_PAGE_SIZE = 20;
export const LIST_KEY_NAME = 'name';

View File

@ -1,12 +1,11 @@
<script>
import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui';
import { createAlert, VARIANT_INFO } from '~/alert';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import { historyReplaceState } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages_and_registries/shared/constants';
import {
PROJECT_RESOURCE_TYPE,
GROUP_RESOURCE_TYPE,
GRAPHQL_PAGE_SIZE,
DELETE_PACKAGE_SUCCESS_MESSAGE,
EMPTY_LIST_HELP_URL,
@ -64,7 +63,7 @@ export default {
};
},
graphqlResource() {
return this.isGroupPage ? GROUP_RESOURCE_TYPE : PROJECT_RESOURCE_TYPE;
return this.isGroupPage ? WORKSPACE_GROUP : WORKSPACE_PROJECT;
},
pageInfo() {
return this.packages?.pageInfo ?? {};

View File

@ -15,6 +15,7 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import { getBulkImportsHistory } from '~/rest_api';
import ImportStatus from '~/import_entities/components/import_status.vue';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import PaginationBar from '~/vue_shared/components/pagination_bar/pagination_bar.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
@ -131,15 +132,15 @@ export default {
},
getPresentationUrl(item) {
const suffix = item.entity_type === 'group' ? '/' : '';
const suffix = item.entity_type === WORKSPACE_GROUP ? '/' : '';
return `${item.destination_full_path}${suffix}`;
},
getEntityTooltip(item) {
switch (item.entity_type) {
case 'project':
case WORKSPACE_PROJECT:
return __('Project');
case 'group':
case WORKSPACE_GROUP:
return __('Group');
default:
return '';

View File

@ -1,5 +1,5 @@
<script>
import { GlAlert, GlButton, GlListbox, GlSprintf } from '@gitlab/ui';
import { GlAlert, GlButton, GlCollapsibleListbox, GlSprintf } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { get } from 'lodash';
import { formatDate } from '~/lib/utils/datetime_utility';
@ -12,7 +12,7 @@ export default {
GlAlert,
GlAreaChart,
GlButton,
GlListbox,
GlCollapsibleListbox,
GlSprintf,
},
props: {
@ -98,7 +98,7 @@ export default {
mappedCoverages() {
return this.dailyCoverageData?.map((item, index) => ({
// A numerical index makes an item into a group header, so
// convert these to strings to get non-header GlListbox items
// convert these to strings to get non-header GlCollapsibleListbox items
value: index.toString(),
text: item.group_name,
}));
@ -182,7 +182,7 @@ export default {
{{ __('It seems that there is currently no available data for code coverage') }}
</span>
</gl-alert>
<gl-listbox
<gl-collapsible-listbox
v-if="canShowData"
:items="mappedCoverages"
:selected="selectedCoverageIndex.toString()"

View File

@ -133,7 +133,7 @@ export default {
>
<gl-form-input
v-model="updateSavedReply.name"
:placeholder="__('Name')"
:placeholder="__('Enter a name for your saved reply')"
data-testid="saved-reply-name-input"
/>
</gl-form-group>

View File

@ -1,7 +1,12 @@
<script>
import { GlDropdownForm, GlIcon, GlLoadingIcon, GlToggle, GlTooltipDirective } from '@gitlab/ui';
import { createAlert } from '~/alert';
import { TYPE_EPIC, TYPE_MERGE_REQUEST } from '~/issues/constants';
import {
TYPE_EPIC,
TYPE_MERGE_REQUEST,
WORKSPACE_GROUP,
WORKSPACE_PROJECT,
} from '~/issues/constants';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { __, sprintf } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@ -109,7 +114,7 @@ export default {
},
subscribeDisabledDescription() {
return sprintf(__('Disabled by %{parent} owner'), {
parent: this.parentIsGroup ? 'group' : 'project',
parent: this.parentIsGroup ? WORKSPACE_GROUP : WORKSPACE_PROJECT,
});
},
isLoggedIn() {

View File

@ -356,7 +356,7 @@ export function mountSidebarLabelsWidget() {
isInIssuePage() || isInIncidentPage() || isInDesignPage()
? TYPE_ISSUE
: TYPE_MERGE_REQUEST,
workspaceType: 'project',
workspaceType: WORKSPACE_PROJECT,
attrWorkspacePath: el.dataset.projectPath,
labelCreateType: WORKSPACE_PROJECT,
},

View File

@ -50,6 +50,7 @@ export default {
}
return {
href: this.item.link,
'aria-current': this.isActive ? 'page' : null,
};
},
linkClasses() {

View File

@ -29,6 +29,9 @@ export default {
removeProject(project) {
this.$emit('removeProject', project);
},
namespaceFallback(namespace) {
return namespace?.fullPath || '';
},
},
};
</script>
@ -51,7 +54,9 @@ export default {
</template>
<template #cell(namespace)="{ item }">
<span data-testid="token-access-project-namespace">{{ item.namespace.fullPath }}</span>
<span data-testid="token-access-project-namespace">
{{ namespaceFallback(item.namespace) }}
</span>
</template>
<template #cell(actions)="{ item }">

View File

@ -1,5 +1,5 @@
<script>
import { GlFormGroup, GlListbox } from '@gitlab/ui';
import { GlFormGroup, GlCollapsibleListbox } from '@gitlab/ui';
import { __ } from '~/locale';
const MIN_ITEMS_COUNT_FOR_SEARCHING = 10;
@ -10,9 +10,9 @@ export default {
},
components: {
GlFormGroup,
GlListbox,
GlCollapsibleListbox,
},
model: GlListbox.model,
model: GlCollapsibleListbox.model,
props: {
label: {
type: String,
@ -39,7 +39,7 @@ export default {
default: null,
},
items: {
type: GlListbox.props.items.type,
type: GlCollapsibleListbox.props.items.type,
required: true,
},
disabled: {
@ -116,7 +116,7 @@ export default {
<template>
<component :is="wrapperComponent" :label="label" :description="description" v-bind="$attrs">
<gl-listbox
<gl-collapsible-listbox
:selected="selected"
:toggle-text="toggleText"
:items="filteredItems"

View File

@ -1,5 +1,5 @@
<script>
import { GlListbox, GlIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
import { GlCollapsibleListbox, GlIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import savedRepliesQuery from './saved_replies.query.graphql';
@ -14,7 +14,7 @@ export default {
},
},
components: {
GlListbox,
GlCollapsibleListbox,
GlIcon,
GlButton,
},
@ -56,7 +56,7 @@ export default {
</script>
<template>
<gl-listbox
<gl-collapsible-listbox
:header-text="__('Insert saved reply')"
:items="filteredSavedReplies"
placement="right"
@ -106,5 +106,5 @@ export default {
>
</div>
</template>
</gl-listbox>
</gl-collapsible-listbox>
</template>

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -13,7 +13,7 @@ module MirrorHelper
docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.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: '</a>'.html_safe, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
{ docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
end
end

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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} &middot;".html_safe

View File

@ -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?

View File

@ -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

View File

@ -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?)

View File

@ -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

View File

@ -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)$/,

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -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**.
![Generate and copy Observability shortened link](img/observability_copy_shortened_link.png)
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

View File

@ -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

View File

@ -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|

View File

@ -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/'

View File

@ -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)

View File

@ -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'

View File

@ -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?

View File

@ -15961,6 +15961,9 @@ msgstr ""
msgid "Enter Admin Mode"
msgstr ""
msgid "Enter a name for your saved reply"
msgstr ""
msgid "Enter a number"
msgstr ""

View File

@ -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",

View File

@ -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 = /^(?<env>\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

View File

@ -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"

View File

@ -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"]');

View File

@ -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);

View File

@ -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,
});
});
});
});

View File

@ -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 };

View File

@ -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 },
});
};

View File

@ -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']]);
});
});
});

View File

@ -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('');
});
});

View File

@ -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);

View File

@ -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);
});
});

View File

@ -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

View File

@ -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',

View File

@ -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"