Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
07d9675a80
commit
a75c69379b
|
@ -249,18 +249,56 @@ Dangerfile @gl-quality/eng-prod
|
|||
|
||||
^[Growth Experiments]
|
||||
/app/experiments/ @gitlab-org/growth/experiment-devs
|
||||
/spec/experiments/ @gitlab-org/growth/experiment-devs
|
||||
/app/models/experiment.rb @gitlab-org/growth/experiment-devs
|
||||
/spec/models/experiment.rb @gitlab-org/growth/experiment-devs
|
||||
/app/models/experiment_subject.rb @gitlab-org/growth/experiment-devs
|
||||
/spec/models/experiment_subject.rb @gitlab-org/growth/experiment-devs
|
||||
/app/models/experiment_user.rb @gitlab-org/growth/experiment-devs
|
||||
/spec/models/experiment_user.rb @gitlab-org/growth/experiment-devs
|
||||
/app/workers/experiments/ @gitlab-org/growth/experiment-devs
|
||||
/spec/workers/experiments/ @gitlab-org/growth/experiment-devs
|
||||
/config/initializers/gitlab_experiment.rb @gitlab-org/growth/experiment-devs
|
||||
/config/feature_flags/experiment/ @gitlab-org/growth/experiment-devs
|
||||
/ee/config/feature_flags/experiment/ @gitlab-org/growth/experiment-devs
|
||||
/ee/lib/api/experiments.rb @gitlab-org/growth/experiment-devs
|
||||
/ee/lib/ee/api/entities/experiment.rb @gitlab-org/growth/experiment-devs
|
||||
/lib/gitlab/experimentation/ @gitlab-org/growth/experiment-devs
|
||||
/lib/gitlab/experimentation.rb @gitlab-org/growth/experiment-devs
|
||||
/lib/gitlab/experimentation_logger.rb @gitlab-org/growth/experiment-devs
|
||||
/ee/spec/requests/api/experiments_spec.rb @gitlab-org/growth/experiment-devs
|
||||
/ee/lib/ee/api/entities/experiment.rb @gitlab-org/growth/experiment-devs
|
||||
/ee/spec/lib/ee/api/entities/experiment_spec.rb @gitlab-org/growth/experiment-devs
|
||||
/lib/gitlab/experimentation/ @gitlab-org/growth/experiment-devs
|
||||
/spec/lib/gitlab/experimentation/ @gitlab-org/growth/experiment-devs
|
||||
/lib/gitlab/experimentation.rb @gitlab-org/growth/experiment-devs
|
||||
/spec/lib/gitlab/experimentation_spec.rb @gitlab-org/growth/experiment-devs
|
||||
/lib/gitlab/experimentation_logger.rb @gitlab-org/growth/experiment-devs
|
||||
|
||||
^[Growth]
|
||||
/ee/app/workers/onboarding/ @gitlab-org/growth/engineers
|
||||
/ee/spec/workers/onboarding/ @gitlab-org/growth/engineers
|
||||
/app/models/onboarding/ @gitlab-org/growth/engineers
|
||||
/spec/models/onboarding/ @gitlab-org/growth/engineers
|
||||
/app/services/onboarding/ @gitlab-org/growth/engineers
|
||||
/spec/services/onboarding/ @gitlab-org/growth/engineers
|
||||
/ee/app/controllers/registrations/ @gitlab-org/growth/engineers
|
||||
/ee/app/components/namespaces/free_user_cap/ @gitlab-org/growth/engineers
|
||||
/ee/spec/components/namespaces/free_user_cap/ @gitlab-org/growth/engineers
|
||||
/ee/app/models/namespaces/free_user_cap/ @gitlab-org/growth/engineers
|
||||
/ee/spec/models/namespaces/free_user_cap/ @gitlab-org/growth/engineers
|
||||
/app/services/users/in_product_marketing_email_records.rb @gitlab-org/growth/engineers
|
||||
/spec/services/users/in_product_marketing_email_records_spec.rb @gitlab-org/growth/engineers
|
||||
/app/workers/namespaces/in_product_marketing_emails_worker.rb @gitlab-org/growth/engineers
|
||||
/spec/workers/namespaces/in_product_marketing_emails_worker_spec.rb @gitlab-org/growth/engineers
|
||||
/ee/app/workers/ee/namespaces/in_product_marketing_emails_worker.rb @gitlab-org/growth/engineers
|
||||
/ee/spec/workers/ee/namespaces/in_product_marketing_emails_worker_spec.rb @gitlab-org/growth/engineers
|
||||
/app/models/users/in_product_marketing_email.rb @gitlab-org/growth/engineers
|
||||
/spec/models/users/in_product_marketing_email_spec.rb @gitlab-org/growth/engineers
|
||||
/app/services/namespaces/in_product_marketing_emails_service.rb @gitlab-org/growth/engineers
|
||||
/spec/services/namespaces/in_product_marketing_emails_service_spec.rb @gitlab-org/growth/engineers
|
||||
/ee/app/services/ee/namespaces/in_product_marketing_emails_service.rb @gitlab-org/growth/engineers
|
||||
/ee/spec/services/namespaces/in_product_marketing_emails_service_spec.rb @gitlab-org/growth/engineers
|
||||
/app/workers/projects/record_target_platforms_worker.rb @gitlab-org/growth/engineers
|
||||
/spec/workers/projects/record_target_platforms_worker_spec.rb @gitlab-org/growth/engineers
|
||||
/ee/app/controllers/groups/feature_discovery_moments_controller.rb @gitlab-org/growth/engineers
|
||||
/ee/spec/requests/groups/feature_discovery_moments_spec.rb @gitlab-org/growth/engineers
|
||||
|
||||
^[Legal]
|
||||
/config/dependency_decisions.yml @gitlab-org/legal-reviewers
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
# Disable warnings in browserslist which can break on backports
|
||||
# https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
|
||||
BROWSERSLIST_IGNORE_OLD_DATA: "true"
|
||||
WEBPACK_COMPILE_LOG_PATH: "tmp/webpack-output.log"
|
||||
stage: prepare
|
||||
script:
|
||||
- *yarn-install
|
||||
|
@ -31,7 +32,6 @@ compile-production-assets:
|
|||
variables:
|
||||
NODE_ENV: "production"
|
||||
RAILS_ENV: "production"
|
||||
WEBPACK_REPORT: "true"
|
||||
artifacts:
|
||||
name: webpack-report
|
||||
expire_in: 31d
|
||||
|
@ -40,7 +40,7 @@ compile-production-assets:
|
|||
# - in `build-assets-image` job to create assets image for packaging systems
|
||||
# - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1
|
||||
- public/assets/
|
||||
- webpack-report/
|
||||
- "${WEBPACK_COMPILE_LOG_PATH}"
|
||||
when: always
|
||||
before_script:
|
||||
- !reference [.default-before_script, before_script]
|
||||
|
@ -56,6 +56,7 @@ compile-test-assets:
|
|||
paths:
|
||||
- public/assets/
|
||||
- node_modules/@gitlab/svgs/dist/icons.json # app/helpers/icons_helper.rb uses this file
|
||||
- "${WEBPACK_COMPILE_LOG_PATH}"
|
||||
when: always
|
||||
|
||||
compile-test-assets as-if-foss:
|
||||
|
@ -321,24 +322,20 @@ webpack-dev-server:
|
|||
bundle-size-review:
|
||||
extends:
|
||||
- .default-retry
|
||||
- .assets-compile-cache
|
||||
- .frontend:rules:bundle-size-review
|
||||
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:danger
|
||||
stage: test
|
||||
needs: ["compile-production-assets"]
|
||||
needs: []
|
||||
script:
|
||||
- source scripts/utils.sh
|
||||
- mkdir -p bundle-size-review
|
||||
- cp webpack-report/index.html bundle-size-review/bundle-report.html
|
||||
- yarn global add https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics.git
|
||||
- |
|
||||
danger_id=$(echo -n ${DANGER_GITLAB_API_TOKEN} | md5sum | awk '{print $1}' | cut -c5-10)
|
||||
run_timed_command "danger --dangerfile=danger/Dangerfile-bundle_size --fail-on-errors=true --verbose --danger_id=bundle-size-review-${danger_id}"
|
||||
- *yarn-install
|
||||
- scripts/bundle_size_review
|
||||
artifacts:
|
||||
when: always
|
||||
name: bundle-size-review
|
||||
expire_in: 31d
|
||||
paths:
|
||||
- bundle-size-review
|
||||
- bundle-size-review/
|
||||
|
||||
.startup-css-check-base:
|
||||
extends:
|
||||
|
|
|
@ -879,6 +879,9 @@
|
|||
rules:
|
||||
- <<: *if-not-canonical-namespace
|
||||
when: never
|
||||
- <<: *if-default-branch-refs
|
||||
changes: *frontend-build-patterns
|
||||
allow_failure: true
|
||||
- if: '$DANGER_GITLAB_API_TOKEN && $CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
|
||||
changes: *frontend-build-patterns
|
||||
allow_failure: true
|
||||
|
|
|
@ -140,6 +140,7 @@ Gitlab/FeatureAvailableUsage:
|
|||
- ee/lib/ee/gitlab/tree_summary.rb
|
||||
- ee/lib/gitlab/alert_management.rb
|
||||
- ee/lib/gitlab/ci/pipeline/chain/config/content/compliance.rb
|
||||
- ee/lib/gitlab/ci/project_config/compliance.rb
|
||||
- ee/lib/gitlab/code_owners.rb
|
||||
- ee/lib/gitlab/incident_management.rb
|
||||
- ee/lib/gitlab/path_locks_finder.rb
|
||||
|
|
|
@ -404,6 +404,7 @@ Gitlab/NamespacedClass:
|
|||
- 'app/policies/project_hook_policy.rb'
|
||||
- 'app/policies/prometheus_alert_policy.rb'
|
||||
- 'app/policies/protected_branch_policy.rb'
|
||||
- 'app/policies/protected_branch_access_policy.rb'
|
||||
- 'app/policies/release_policy.rb'
|
||||
- 'app/policies/repository_policy.rb'
|
||||
- 'app/policies/resource_label_event_policy.rb'
|
||||
|
|
|
@ -186,27 +186,34 @@ export default {
|
|||
:data-username="author.username"
|
||||
>
|
||||
<span
|
||||
v-if="glFeatures.removeUserAttributes"
|
||||
v-if="glFeatures.removeUserAttributesProjects || glFeatures.removeUserAttributesGroups"
|
||||
class="note-header-author-name gl-font-weight-bold"
|
||||
>
|
||||
{{ authorName }}
|
||||
</span>
|
||||
<user-name-with-status
|
||||
v-if="!glFeatures.removeUserAttributes"
|
||||
v-else
|
||||
:name="authorName"
|
||||
:availability="userAvailability(author)"
|
||||
container-classes="note-header-author-name gl-font-weight-bold"
|
||||
/>
|
||||
</a>
|
||||
<span
|
||||
v-if="authorStatus && !glFeatures.removeUserAttributes"
|
||||
v-if="
|
||||
authorStatus &&
|
||||
!glFeatures.removeUserAttributesProjects &&
|
||||
!glFeatures.removeUserAttributesGroups
|
||||
"
|
||||
ref="authorStatus"
|
||||
v-safe-html:[$options.safeHtmlConfig]="authorStatus"
|
||||
v-on="
|
||||
authorStatusHasTooltip ? { mouseenter: removeEmojiTitle, mouseleave: addEmojiTitle } : {}
|
||||
"
|
||||
></span>
|
||||
<span v-if="!glFeatures.removeUserAttributes" class="text-nowrap author-username">
|
||||
<span
|
||||
v-if="!glFeatures.removeUserAttributesProjects && !glFeatures.removeUserAttributesGroups"
|
||||
class="text-nowrap author-username"
|
||||
>
|
||||
<a
|
||||
ref="authorUsernameLink"
|
||||
class="author-username-link"
|
||||
|
|
|
@ -65,7 +65,7 @@ export default {
|
|||
fetchArtifacts() {
|
||||
// refactor tracking based on action once this dropdown supports
|
||||
// actions other than artifacts
|
||||
this.track('click_artifacts_dropdown', { label: TRACKING_CATEGORIES.index });
|
||||
this.track('click_artifacts_dropdown', { label: TRACKING_CATEGORIES.table });
|
||||
|
||||
this.isLoading = true;
|
||||
// Replace the placeholder with the ID of the pipeline we are viewing
|
||||
|
|
|
@ -66,7 +66,7 @@ export default {
|
|||
eventHub.$emit('retryPipeline', this.pipeline.retry_path);
|
||||
},
|
||||
trackClick(action) {
|
||||
this.track(action, { label: TRACKING_CATEGORIES.index });
|
||||
this.track(action, { label: TRACKING_CATEGORIES.table });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -118,7 +118,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
trackClick(action) {
|
||||
this.track(action, { label: TRACKING_CATEGORIES.index });
|
||||
this.track(action, { label: TRACKING_CATEGORIES.table });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import { isEqual } from 'lodash';
|
|||
import createFlash from '~/flash';
|
||||
import { getParameterByName } from '~/lib/utils/url_utility';
|
||||
import { __, s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
|
||||
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
|
||||
import {
|
||||
|
@ -11,6 +12,7 @@ import {
|
|||
RAW_TEXT_WARNING,
|
||||
FILTER_TAG_IDENTIFIER,
|
||||
PipelineKeyOptions,
|
||||
TRACKING_CATEGORIES,
|
||||
} from '../../constants';
|
||||
import PipelinesMixin from '../../mixins/pipelines_mixin';
|
||||
import PipelinesService from '../../services/pipelines_service';
|
||||
|
@ -35,7 +37,7 @@ export default {
|
|||
PipelinesTableComponent,
|
||||
TablePagination,
|
||||
},
|
||||
mixins: [PipelinesMixin],
|
||||
mixins: [PipelinesMixin, Tracking.mixin()],
|
||||
props: {
|
||||
store: {
|
||||
type: Object,
|
||||
|
@ -246,6 +248,8 @@ export default {
|
|||
params = this.onChangeWithFilter(params);
|
||||
|
||||
this.updateContent(params);
|
||||
|
||||
this.track('click_filter_tabs', { label: TRACKING_CATEGORIES.tabs });
|
||||
},
|
||||
successCallback(resp) {
|
||||
// Because we are polling & the user is interacting verify if the response received
|
||||
|
|
|
@ -113,7 +113,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
onSubmit(filters) {
|
||||
this.track('click_filtered_search', { label: TRACKING_CATEGORIES.index });
|
||||
this.track('click_filtered_search', { label: TRACKING_CATEGORIES.search });
|
||||
this.$emit('filterPipelines', filters);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -77,7 +77,7 @@ export default {
|
|||
return !action.playable;
|
||||
},
|
||||
trackClick() {
|
||||
this.track('click_manual_actions', { label: TRACKING_CATEGORIES.index });
|
||||
this.track('click_manual_actions', { label: TRACKING_CATEGORIES.table });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
trackClick() {
|
||||
this.track('click_ci_status_badge', { label: TRACKING_CATEGORIES.index });
|
||||
this.track('click_ci_status_badge', { label: TRACKING_CATEGORIES.table });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -111,5 +111,7 @@ export const DEFAULT_FIELDS = [
|
|||
];
|
||||
|
||||
export const TRACKING_CATEGORIES = {
|
||||
index: 'pipelines_table_component',
|
||||
table: 'pipelines_table_component',
|
||||
tabs: 'pipelines_filter_tabs',
|
||||
search: 'pipelines_filtered_search',
|
||||
};
|
||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mr-widget-body media">
|
||||
<div class="mr-widget-body media" v-on="$listeners">
|
||||
<div v-if="isLoading" class="gl-w-full mr-conflict-loader">
|
||||
<slot name="loading">
|
||||
<div class="gl-display-flex">
|
||||
|
|
|
@ -11,7 +11,7 @@ class Projects::IncidentsController < Projects::ApplicationController
|
|||
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:work_items_hierarchy, @project)
|
||||
push_frontend_feature_flag(:remove_user_attributes, @group)
|
||||
push_frontend_feature_flag(:remove_user_attributes_projects, @project)
|
||||
end
|
||||
|
||||
feature_category :incident_management
|
||||
|
|
|
@ -42,7 +42,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:incident_timeline, project)
|
||||
push_frontend_feature_flag(:remove_user_attributes, @group)
|
||||
push_frontend_feature_flag(:remove_user_attributes_projects, project)
|
||||
end
|
||||
|
||||
before_action only: [:index, :show] do
|
||||
|
|
|
@ -45,7 +45,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
push_frontend_feature_flag(:paginated_mr_discussions, project)
|
||||
push_frontend_feature_flag(:mr_review_submit_comment, project)
|
||||
push_frontend_feature_flag(:mr_experience_survey, project)
|
||||
push_frontend_feature_flag(:remove_user_attributes, @group)
|
||||
push_frontend_feature_flag(:remove_user_attributes_projects, @project)
|
||||
end
|
||||
|
||||
before_action do
|
||||
|
|
|
@ -6,6 +6,8 @@ module Mutations
|
|||
class PromoteFromNote < Base
|
||||
graphql_name 'TimelineEventPromoteFromNote'
|
||||
|
||||
include NotesHelper
|
||||
|
||||
argument :note_id, Types::GlobalIDType[::Note],
|
||||
required: true,
|
||||
description: 'Note ID from which the timeline event promoted.'
|
||||
|
@ -20,7 +22,7 @@ module Mutations
|
|||
incident,
|
||||
current_user,
|
||||
promoted_from_note: note,
|
||||
note: note.note,
|
||||
note: build_note_string(note),
|
||||
occurred_at: note.created_at,
|
||||
editable: true
|
||||
).execute
|
||||
|
@ -38,6 +40,11 @@ module Mutations
|
|||
super
|
||||
end
|
||||
|
||||
def build_note_string(note)
|
||||
commented = _('commented')
|
||||
"@#{note.author.username} [#{commented}](#{noteable_note_url(note)}): '#{note.note}'"
|
||||
end
|
||||
|
||||
def raise_noteable_not_incident!
|
||||
raise_resource_not_available_error! 'Note does not belong to an incident'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module BranchProtections
|
||||
class BaseAccessLevelType < Types::BaseObject
|
||||
authorize :read_protected_branch
|
||||
|
||||
field :access_level,
|
||||
type: GraphQL::Types::Int,
|
||||
null: false,
|
||||
description: 'GitLab::Access level.'
|
||||
|
||||
field :access_level_description,
|
||||
type: GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'Human readable representation for this access level.',
|
||||
hash_key: 'humanize'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module BranchProtections
|
||||
class MergeAccessLevelType < BaseAccessLevelType # rubocop:disable Graphql/AuthorizeTypes
|
||||
graphql_name 'MergeAccessLevel'
|
||||
description 'Represents the merge access level of a branch protection.'
|
||||
accepts ::ProtectedBranch::MergeAccessLevel
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,6 +8,11 @@ module Types
|
|||
accepts ::ProtectedBranch
|
||||
authorize :read_protected_branch
|
||||
|
||||
field :merge_access_levels,
|
||||
type: Types::BranchProtections::MergeAccessLevelType.connection_type,
|
||||
null: true,
|
||||
description: 'Details about who can merge when this branch is the source branch.'
|
||||
|
||||
field :allow_force_push,
|
||||
type: GraphQL::Types::Boolean,
|
||||
null: false,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ProtectedBranchAccessPolicy < BasePolicy
|
||||
delegate { @subject.protected_branch }
|
||||
end
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: group_level_protected_environment_settings_permission
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92801
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/369873
|
||||
milestone: '15.3'
|
||||
name: ci_project_pipeline_config_refactoring
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97240
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372867
|
||||
milestone: '15.4'
|
||||
type: development
|
||||
group: group::release
|
||||
default_enabled: true
|
||||
group: group::pipeline authoring
|
||||
default_enabled: false
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: remove_user_attributes
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96447
|
||||
name: remove_user_attributes_groups
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97520
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372047
|
||||
milestone: '15.4'
|
||||
type: development
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: remove_user_attributes_projects
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97520
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372047
|
||||
milestone: '15.4'
|
||||
type: development
|
||||
group: group::code review
|
||||
default_enabled: false
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_partitioning_analyze_queries
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97113
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372840
|
||||
milestone: '15.4'
|
||||
type: ops
|
||||
group: group::pipeline execution
|
||||
default_enabled: false
|
|
@ -55,8 +55,17 @@ const INCREMENTAL_COMPILER_RECORD_HISTORY = IS_DEV_SERVER && !process.env.CI;
|
|||
const WEBPACK_REPORT = process.env.WEBPACK_REPORT && process.env.WEBPACK_REPORT !== 'false';
|
||||
const WEBPACK_MEMORY_TEST =
|
||||
process.env.WEBPACK_MEMORY_TEST && process.env.WEBPACK_MEMORY_TEST !== 'false';
|
||||
const NO_COMPRESSION = process.env.NO_COMPRESSION && process.env.NO_COMPRESSION !== 'false';
|
||||
const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS && process.env.NO_SOURCEMAPS !== 'false';
|
||||
let NO_COMPRESSION = process.env.NO_COMPRESSION && process.env.NO_COMPRESSION !== 'false';
|
||||
let NO_SOURCEMAPS = process.env.NO_SOURCEMAPS && process.env.NO_SOURCEMAPS !== 'false';
|
||||
let NO_HASHED_CHUNKS = process.env.NO_HASHED_CHUNKS && process.env.NO_HASHED_CHUNKS !== 'false';
|
||||
|
||||
if (WEBPACK_REPORT) {
|
||||
console.log('Webpack report enabled. Running a "slim" production build.');
|
||||
// For our webpack report we need no source maps, compression _or_ hashed file names.
|
||||
NO_SOURCEMAPS = true;
|
||||
NO_COMPRESSION = true;
|
||||
NO_HASHED_CHUNKS = true;
|
||||
}
|
||||
|
||||
const WEBPACK_OUTPUT_PATH = path.join(ROOT_PATH, 'public/assets/webpack');
|
||||
const WEBPACK_PUBLIC_PATH = '/assets/webpack/';
|
||||
|
@ -251,8 +260,10 @@ module.exports = {
|
|||
output: {
|
||||
path: WEBPACK_OUTPUT_PATH,
|
||||
publicPath: WEBPACK_PUBLIC_PATH,
|
||||
filename: IS_PRODUCTION ? '[name].[contenthash:8].bundle.js' : '[name].bundle.js',
|
||||
chunkFilename: IS_PRODUCTION ? '[name].[contenthash:8].chunk.js' : '[name].chunk.js',
|
||||
filename:
|
||||
IS_PRODUCTION && !NO_HASHED_CHUNKS ? '[name].[contenthash:8].bundle.js' : '[name].bundle.js',
|
||||
chunkFilename:
|
||||
IS_PRODUCTION && !NO_HASHED_CHUNKS ? '[name].[contenthash:8].chunk.js' : '[name].chunk.js',
|
||||
globalObject: 'this', // allow HMR and web workers to play nice
|
||||
},
|
||||
|
||||
|
@ -687,6 +698,8 @@ module.exports = {
|
|||
statsFilename: path.join(ROOT_PATH, 'webpack-report/stats.json'),
|
||||
statsOptions: {
|
||||
source: false,
|
||||
errors: false,
|
||||
warnings: false,
|
||||
},
|
||||
}),
|
||||
|
||||
|
|
|
@ -1,38 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
# This file isn't named "Dangerfile" so that it's not imported by default since it's only meant to be run in the `bundle-size-review` job.
|
||||
|
||||
analysis_result = "./bundle-size-review/analysis.json"
|
||||
markdown_result = "./bundle-size-review/comparison.md"
|
||||
|
||||
# Executing the webpack-entry-point-analyser
|
||||
# We would like to do that in the CI file directly,
|
||||
# but unfortunately the head_commit SHA is not available
|
||||
# as a CI variable due to our merge into master simulation
|
||||
analyze_cmd = [
|
||||
"webpack-entry-point-analyser",
|
||||
"--from-file ./webpack-report/stats.json",
|
||||
"--json #{analysis_result}",
|
||||
" --sha #{gitlab&.head_commit}"
|
||||
].join(" ")
|
||||
|
||||
# execute analysis
|
||||
`#{analyze_cmd}`
|
||||
|
||||
# We are executing the comparison by comparing the start_sha
|
||||
# to the current pipeline result. The start_sha is the commit
|
||||
# from master that was merged into for the merged pipeline.
|
||||
comparison_cmd = [
|
||||
"webpack-compare-reports",
|
||||
"--job #{ENV["CI_JOB_ID"]}",
|
||||
"--to-file #{analysis_result}",
|
||||
"--html ./bundle-size-review/comparison.html",
|
||||
"--markdown #{markdown_result}"
|
||||
].join(" ")
|
||||
|
||||
# execute comparison
|
||||
`#{comparison_cmd}`
|
||||
|
||||
comment = `cat #{markdown_result}`
|
||||
comment = `cat ./bundle-size-review/comparison.md`
|
||||
|
||||
unless comment.strip.empty?
|
||||
markdown(<<~MARKDOWN)
|
||||
|
|
|
@ -31,9 +31,8 @@ by removing the ~database label and re-running the [`danger-review` job](#{ENV['
|
|||
MSG
|
||||
|
||||
DB_MIGRATION_TESTING_REQUIRED_MESSAGE = <<~MSG
|
||||
1. If this is not a ~"Community contribution" or from a Fork, kick off the
|
||||
`db:gitlabcom-database-testing` manual job.
|
||||
|
||||
1. Kick off the `db:gitlabcom-database-testing` manual job. This job can also be used before
|
||||
requesting review to test your migrations against production data.
|
||||
MSG
|
||||
|
||||
DATABASE_APPROVED_LABEL = 'database::approved'
|
||||
|
|
|
@ -105,3 +105,6 @@ parameter:
|
|||
| `deployment_frequency` | The number of successful deployments during the time period. |
|
||||
| `lead_time_for_changes` | The median number of seconds between the merge of the merge request (MR) and the deployment of the MR's commits for all MRs deployed during the time period. |
|
||||
| `time_to_restore_service` | The median number of seconds an incident was open during the time period. Available only for production environment. |
|
||||
|
||||
NOTE:
|
||||
The API returns the `monthly` and `all` intervals by calculating the median of the daily median values. This can introduce a slight inaccuracy in the returned data.
|
||||
|
|
|
@ -7837,6 +7837,29 @@ The edge type for [`MemberInterface`](#memberinterface).
|
|||
| <a id="memberinterfaceedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| <a id="memberinterfaceedgenode"></a>`node` | [`MemberInterface`](#memberinterface) | The item at the end of the edge. |
|
||||
|
||||
#### `MergeAccessLevelConnection`
|
||||
|
||||
The connection type for [`MergeAccessLevel`](#mergeaccesslevel).
|
||||
|
||||
##### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergeaccesslevelconnectionedges"></a>`edges` | [`[MergeAccessLevelEdge]`](#mergeaccessleveledge) | A list of edges. |
|
||||
| <a id="mergeaccesslevelconnectionnodes"></a>`nodes` | [`[MergeAccessLevel]`](#mergeaccesslevel) | A list of nodes. |
|
||||
| <a id="mergeaccesslevelconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
||||
#### `MergeAccessLevelEdge`
|
||||
|
||||
The edge type for [`MergeAccessLevel`](#mergeaccesslevel).
|
||||
|
||||
##### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergeaccessleveledgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| <a id="mergeaccessleveledgenode"></a>`node` | [`MergeAccessLevel`](#mergeaccesslevel) | The item at the end of the edge. |
|
||||
|
||||
#### `MergeRequestAssigneeConnection`
|
||||
|
||||
The connection type for [`MergeRequestAssignee`](#mergerequestassignee).
|
||||
|
@ -10083,6 +10106,7 @@ Branch protection details for a branch rule.
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="branchprotectionallowforcepush"></a>`allowForcePush` | [`Boolean!`](#boolean) | Toggle force push to the branch for users with write access. |
|
||||
| <a id="branchprotectionmergeaccesslevels"></a>`mergeAccessLevels` | [`MergeAccessLevelConnection`](#mergeaccesslevelconnection) | Details about who can merge when this branch is the source branch. (see [Connections](#connections)) |
|
||||
|
||||
### `BranchRule`
|
||||
|
||||
|
@ -13783,6 +13807,17 @@ Maven metadata.
|
|||
| <a id="mavenmetadatapath"></a>`path` | [`String!`](#string) | Path of the Maven package. |
|
||||
| <a id="mavenmetadataupdatedat"></a>`updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
|
||||
### `MergeAccessLevel`
|
||||
|
||||
Represents the merge access level of a branch protection.
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergeaccesslevelaccesslevel"></a>`accessLevel` | [`Int!`](#int) | GitLab::Access level. |
|
||||
| <a id="mergeaccesslevelaccessleveldescription"></a>`accessLevelDescription` | [`String!`](#string) | Human readable representation for this access level. |
|
||||
|
||||
### `MergeRequest`
|
||||
|
||||
#### Fields
|
||||
|
|
|
@ -156,6 +156,12 @@ the time limit to resolve all files is 30 seconds.
|
|||
- You can override included configuration by having the same job name or global keyword
|
||||
in the `.gitlab-ci.yml` file. The two configurations are merged together, and the
|
||||
configuration in the `.gitlab-ci.yml` file takes precedence over the included configuration.
|
||||
- If you rerun a:
|
||||
- Job, the `include` files are not fetched again. All jobs in a pipeline use the configuration
|
||||
fetched when the pipeline was created. Any changes to the source `include` files
|
||||
do not affect job reruns.
|
||||
- Pipeline, the `include` files are fetched again. If they changed after the last
|
||||
pipeline run, the new pipeline uses the changed configuration.
|
||||
|
||||
**Related topics**:
|
||||
|
||||
|
|
|
@ -113,16 +113,23 @@ To view the lead time for changes for merge requests in your project:
|
|||
|
||||
The **Lead Time for Changes** metrics display below the **Filter results** text box.
|
||||
|
||||
## View number of successful deployments **(PREMIUM)**
|
||||
## View number of successful deployments **(FREE)**
|
||||
|
||||
To view deployment metrics, you must have a
|
||||
Prerequisites:
|
||||
|
||||
- To view deployment metrics, you must have a
|
||||
[production environment configured](../../ci/environments/index.md#deployment-tier-of-environments).
|
||||
|
||||
Value stream analytics shows the following deployment metrics for your project:
|
||||
Value stream analytics shows the following deployment metrics for your project within the specified date range:
|
||||
|
||||
- Deploys: The number of successful deployments in the date range.
|
||||
- Deployment Frequency: The average number of successful deployments per day in the date range.
|
||||
|
||||
If you have a GitLab Premium or Ultimate subscription:
|
||||
|
||||
- The number of successful deployments is calculated with DORA data.
|
||||
- The data is filtered based on environment and environment tier.
|
||||
|
||||
To view deployment metrics for your project:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
|
|
|
@ -7,6 +7,7 @@ module Gitlab
|
|||
module Config
|
||||
class Content < Chain::Base
|
||||
include Chain::Helpers
|
||||
include ::Gitlab::Utils::StrongMemoize
|
||||
|
||||
SOURCES = [
|
||||
Gitlab::Ci::Pipeline::Chain::Config::Content::Parameter,
|
||||
|
@ -18,10 +19,10 @@ module Gitlab
|
|||
].freeze
|
||||
|
||||
def perform!
|
||||
if config = find_config
|
||||
@pipeline.build_pipeline_config(content: config.content)
|
||||
@command.config_content = config.content
|
||||
@pipeline.config_source = config.source
|
||||
if pipeline_config&.exists?
|
||||
@pipeline.build_pipeline_config(content: pipeline_config.content)
|
||||
@command.config_content = pipeline_config.content
|
||||
@pipeline.config_source = pipeline_config.source
|
||||
else
|
||||
error('Missing CI config file')
|
||||
end
|
||||
|
@ -33,7 +34,19 @@ module Gitlab
|
|||
|
||||
private
|
||||
|
||||
def find_config
|
||||
def pipeline_config
|
||||
strong_memoize(:pipeline_config) do
|
||||
next legacy_find_config if ::Feature.disabled?(:ci_project_pipeline_config_refactoring, project)
|
||||
|
||||
::Gitlab::Ci::ProjectConfig.new(
|
||||
project: project, sha: @pipeline.sha,
|
||||
custom_content: @command.content,
|
||||
pipeline_source: @command.source, pipeline_source_bridge: @command.bridge
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def legacy_find_config
|
||||
sources.each do |source|
|
||||
config = source.new(@pipeline, @command)
|
||||
return config if config.exists?
|
||||
|
|
|
@ -6,6 +6,7 @@ module Gitlab
|
|||
module Chain
|
||||
module Config
|
||||
class Content
|
||||
# When removing ci_project_pipeline_config_refactoring, this and its subclasses will be removed.
|
||||
class Source
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
# Locates project CI config
|
||||
class ProjectConfig
|
||||
# The order of sources is important:
|
||||
# - EE uses Compliance first since it must be used first if compliance templates are enabled.
|
||||
# (see ee/lib/ee/gitlab/ci/project_config.rb)
|
||||
# - Parameter is used by on-demand security scanning which passes the actual CI YAML to use as argument.
|
||||
# - Bridge is used for downstream pipelines since the config is defined in the bridge job. If lower in priority,
|
||||
# it would evaluate the project's YAML file instead.
|
||||
# - Repository / ExternalProject / Remote: their order is not important between each other.
|
||||
# - AutoDevops is used as default option if nothing else is found and if AutoDevops is enabled.
|
||||
SOURCES = [
|
||||
ProjectConfig::Parameter,
|
||||
ProjectConfig::Bridge,
|
||||
ProjectConfig::Repository,
|
||||
ProjectConfig::ExternalProject,
|
||||
ProjectConfig::Remote,
|
||||
ProjectConfig::AutoDevops
|
||||
].freeze
|
||||
|
||||
def initialize(project:, sha:, custom_content: nil, pipeline_source: nil, pipeline_source_bridge: nil)
|
||||
@config = find_config(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
|
||||
end
|
||||
|
||||
delegate :content, :source, to: :@config, allow_nil: true
|
||||
|
||||
def exists?
|
||||
!!@config&.exists?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_config(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
|
||||
sources.each do |source|
|
||||
config = source.new(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
|
||||
return config if config.exists?
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def sources
|
||||
SOURCES
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Gitlab::Ci::ProjectConfig.prepend_mod_with('Gitlab::Ci::ProjectConfig')
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class AutoDevops < Source
|
||||
def content
|
||||
strong_memoize(:content) do
|
||||
next unless project&.auto_devops_enabled?
|
||||
|
||||
template = Gitlab::Template::GitlabCiYmlTemplate.find(template_name)
|
||||
YAML.dump('include' => [{ 'template' => template.full_name }])
|
||||
end
|
||||
end
|
||||
|
||||
def source
|
||||
:auto_devops_source
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def template_name
|
||||
'Auto-DevOps'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class Bridge < Source
|
||||
def content
|
||||
return unless pipeline_source_bridge
|
||||
|
||||
pipeline_source_bridge.yaml_for_downstream
|
||||
end
|
||||
|
||||
def source
|
||||
:bridge_source
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class ExternalProject < Source
|
||||
def content
|
||||
strong_memoize(:content) do
|
||||
next unless external_project_path?
|
||||
|
||||
path_file, path_project, ref = extract_location_tokens
|
||||
|
||||
config_location = { 'project' => path_project, 'file' => path_file }
|
||||
config_location['ref'] = ref if ref.present?
|
||||
|
||||
YAML.dump('include' => [config_location])
|
||||
end
|
||||
end
|
||||
|
||||
def source
|
||||
:external_project_source
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Example: path/to/.gitlab-ci.yml@another-group/another-project
|
||||
def external_project_path?
|
||||
ci_config_path =~ /\A.+(yml|yaml)@.+\z/
|
||||
end
|
||||
|
||||
# Example: path/to/.gitlab-ci.yml@another-group/another-project:refname
|
||||
def extract_location_tokens
|
||||
path_file, path_project = ci_config_path.split('@', 2)
|
||||
|
||||
if path_project.include? ":"
|
||||
project, ref = path_project.split(':', 2)
|
||||
[path_file, project, ref]
|
||||
else
|
||||
[path_file, path_project]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class Parameter < Source
|
||||
def content
|
||||
strong_memoize(:content) do
|
||||
next unless custom_content.present?
|
||||
|
||||
custom_content
|
||||
end
|
||||
end
|
||||
|
||||
def source
|
||||
:parameter_source
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class Remote < Source
|
||||
def content
|
||||
strong_memoize(:content) do
|
||||
next unless ci_config_path =~ URI::DEFAULT_PARSER.make_regexp(%w[http https])
|
||||
|
||||
YAML.dump('include' => [{ 'remote' => ci_config_path }])
|
||||
end
|
||||
end
|
||||
|
||||
def source
|
||||
:remote_source
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class Repository < Source
|
||||
def content
|
||||
strong_memoize(:content) do
|
||||
next unless file_in_repository?
|
||||
|
||||
YAML.dump('include' => [{ 'local' => ci_config_path }])
|
||||
end
|
||||
end
|
||||
|
||||
def source
|
||||
:repository_source
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def file_in_repository?
|
||||
return unless project
|
||||
return unless sha
|
||||
|
||||
project.repository.gitlab_ci_yml_for(sha, ci_config_path).present?
|
||||
rescue GRPC::NotFound, GRPC::Internal
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
class ProjectConfig
|
||||
class Source
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
def initialize(project, sha, custom_content, pipeline_source, pipeline_source_bridge)
|
||||
@project = project
|
||||
@sha = sha
|
||||
@custom_content = custom_content
|
||||
@pipeline_source = pipeline_source
|
||||
@pipeline_source_bridge = pipeline_source_bridge
|
||||
end
|
||||
|
||||
def exists?
|
||||
strong_memoize(:exists) do
|
||||
content.present?
|
||||
end
|
||||
end
|
||||
|
||||
def content
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def source
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :project, :sha, :custom_content, :pipeline_source, :pipeline_source_bridge
|
||||
|
||||
def ci_config_path
|
||||
@ci_config_path ||= project.ci_config_path_or_default
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Database
|
||||
module QueryAnalyzers
|
||||
module Ci
|
||||
# The purpose of this analyzer is to detect queries not going through a partitioning routing table
|
||||
class PartitioningAnalyzer < Database::QueryAnalyzers::Base
|
||||
RoutingTableNotUsedError = Class.new(QueryAnalyzerError)
|
||||
|
||||
ENABLED_TABLES = %w[
|
||||
ci_builds_metadata
|
||||
].freeze
|
||||
|
||||
class << self
|
||||
def enabled?
|
||||
::Feature::FlipperFeature.table_exists? &&
|
||||
::Feature.enabled?(:ci_partitioning_analyze_queries, type: :ops)
|
||||
end
|
||||
|
||||
def analyze(parsed)
|
||||
analyze_legacy_tables_usage(parsed)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def analyze_legacy_tables_usage(parsed)
|
||||
detected = ENABLED_TABLES & (parsed.pg.dml_tables + parsed.pg.select_tables)
|
||||
|
||||
return if detected.none?
|
||||
|
||||
::Gitlab::ErrorTracking.track_and_raise_for_dev_exception(
|
||||
RoutingTableNotUsedError.new("Detected non-partitioned table use #{detected.inspect}: #{parsed.sql}")
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -44,30 +44,30 @@ module Gitlab
|
|||
TRANSLATION_LEVELS = {
|
||||
'bg' => 0,
|
||||
'cs_CZ' => 0,
|
||||
'da_DK' => 39,
|
||||
'da_DK' => 38,
|
||||
'de' => 17,
|
||||
'en' => 100,
|
||||
'eo' => 0,
|
||||
'es' => 38,
|
||||
'es' => 37,
|
||||
'fil_PH' => 0,
|
||||
'fr' => 11,
|
||||
'gl_ES' => 0,
|
||||
'id_ID' => 0,
|
||||
'it' => 1,
|
||||
'ja' => 32,
|
||||
'ko' => 12,
|
||||
'ja' => 31,
|
||||
'ko' => 17,
|
||||
'nb_NO' => 26,
|
||||
'nl_NL' => 0,
|
||||
'pl_PL' => 4,
|
||||
'pt_BR' => 55,
|
||||
'ro_RO' => 100,
|
||||
'pt_BR' => 56,
|
||||
'ro_RO' => 99,
|
||||
'ru' => 27,
|
||||
'si_LK' => 10,
|
||||
'tr_TR' => 12,
|
||||
'tr_TR' => 11,
|
||||
'uk' => 50,
|
||||
'zh_CN' => 99,
|
||||
'zh_CN' => 97,
|
||||
'zh_HK' => 1,
|
||||
'zh_TW' => 100
|
||||
'zh_TW' => 99
|
||||
}.freeze
|
||||
private_constant :TRANSLATION_LEVELS
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ module Tasks
|
|||
|
||||
asset_files
|
||||
end
|
||||
|
||||
private_class_method :assets_impacting_webpack_compilation
|
||||
end
|
||||
end
|
||||
|
@ -84,9 +85,17 @@ namespace :gitlab do
|
|||
if head_assets_sha256 != master_assets_sha256 || !public_assets_webpack_dir_exists
|
||||
FileUtils.rm_r(Tasks::Gitlab::Assets::PUBLIC_ASSETS_WEBPACK_DIR) if public_assets_webpack_dir_exists
|
||||
|
||||
unless system('yarn webpack')
|
||||
log_path = ENV['WEBPACK_COMPILE_LOG_PATH']
|
||||
|
||||
cmd = 'yarn webpack'
|
||||
cmd += " > #{log_path}" if log_path
|
||||
|
||||
unless system(cmd)
|
||||
abort 'Error: Unable to compile webpack production bundle.'.color(:red)
|
||||
end
|
||||
|
||||
puts "Written webpack stdout log to #{log_path}" if log_path
|
||||
puts "You can inspect the webpack log here: #{ENV['CI_JOB_URL']}/artifacts/file/#{log_path}" if log_path && ENV['CI_JOB_URL']
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -46564,6 +46564,9 @@ msgstr ""
|
|||
msgid "comment"
|
||||
msgstr ""
|
||||
|
||||
msgid "commented"
|
||||
msgstr ""
|
||||
|
||||
msgid "commented on %{link_to_project}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
RSpec.describe 'Create', :reliable do
|
||||
RSpec.describe 'Create', :reliable, quarantine: {
|
||||
type: :investigating,
|
||||
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/373093'
|
||||
} do
|
||||
context 'Content Editor' do
|
||||
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
|
||||
let(:page_title) { 'Content Editor Page' }
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
#
|
||||
# # How does this work in general?
|
||||
#
|
||||
# 1. We run webpack in a production like mode and enable the BundleAnalyzerPlugin
|
||||
# 2. The Plugin builds a index.html for human consumption _and_ a stats.json
|
||||
# 3. This script creates a smaller analysis.json from the gargantuan stats.json
|
||||
# 4. In Merge Requests:
|
||||
# - compare that smaller to analysis.json to the one from the base commit on master
|
||||
# - report the comparison results via danger
|
||||
|
||||
source scripts/utils.sh
|
||||
|
||||
# For now we only want bundle-size-review to run in CI
|
||||
# Maybe we could create a "local mode"
|
||||
if [[ -z "${CI:-}" ]]; then
|
||||
echo 'Not running in a CI context, skipping bundle analysis'
|
||||
exit "0"
|
||||
fi
|
||||
|
||||
# Get the _current_ commit sha
|
||||
if [[ -z "${CI_MERGE_REQUEST_IID:-}" ]]; then
|
||||
echo 'Not in a merge request, setting COMMIT_SHA to $CI_COMMIT_SHA'
|
||||
COMMIT_SHA="${CI_COMMIT_SHA}"
|
||||
else
|
||||
echo 'In a merge request, setting COMMIT_SHA to $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA'
|
||||
COMMIT_SHA="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
fi
|
||||
|
||||
# Create output directory
|
||||
mkdir -p bundle-size-review
|
||||
|
||||
# Running webpack
|
||||
export WEBPACK_REPORT="true"
|
||||
run_timed_command "yarn run webpack-prod > bundle-size-review/webpack-output.log"
|
||||
|
||||
# Copy results from stats plugin
|
||||
cp webpack-report/index.html bundle-size-review/bundle-report.html
|
||||
|
||||
# Run comparison in danger
|
||||
if [[ -z "${DANGER_GITLAB_API_TOKEN:-}" ]]; then
|
||||
echo 'No Danger token available, skipping bundle analysis'
|
||||
exit "0"
|
||||
fi
|
||||
|
||||
# TODO: Make this a dependency of GitLab itself after a proper release
|
||||
yarn global add https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics.git
|
||||
|
||||
# Create smaller analysis.json
|
||||
run_timed_command "webpack-entry-point-analyser --from-file ./webpack-report/stats.json --json ./bundle-size-review/analysis.json --sha ${COMMIT_SHA}"
|
||||
rm -rf webpack-report
|
||||
|
||||
if [[ -z "${CI_MERGE_REQUEST_IID:-}" ]]; then
|
||||
echo 'Not in a merge request, skipping comparison'
|
||||
exit "0"
|
||||
fi
|
||||
|
||||
# Run comparison
|
||||
run_timed_command "webpack-compare-reports --job ${CI_JOB_ID} --to-file ./bundle-size-review/analysis.json --html ./bundle-size-review/comparison.html --markdown ./bundle-size-review/comparison.md"
|
||||
|
||||
# Execute danger
|
||||
danger_id=$(echo -n "${DANGER_GITLAB_API_TOKEN}" | md5sum | awk '{print $1}' | cut -c5-10)
|
||||
run_timed_command "danger --dangerfile=danger/Dangerfile-bundle_size --fail-on-errors=true --verbose --danger_id=bundle-size-review-${danger_id}"
|
||||
|
||||
exit "0"
|
|
@ -17,6 +17,16 @@ FactoryBot.define do
|
|||
ProtectedBranches::CacheService.new(protected_branch.project).refresh
|
||||
end
|
||||
|
||||
after(:build) do |protected_branch, evaluator|
|
||||
if evaluator.default_access_level && evaluator.default_push_level
|
||||
protected_branch.push_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
|
||||
if evaluator.default_access_level && evaluator.default_merge_level
|
||||
protected_branch.merge_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
end
|
||||
|
||||
trait :create_branch_on_repository do
|
||||
association :project, factory: [:project, :repository]
|
||||
|
||||
|
@ -31,6 +41,26 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :maintainers_can_push do
|
||||
transient do
|
||||
default_push_level { false }
|
||||
end
|
||||
|
||||
after(:build) do |protected_branch|
|
||||
protected_branch.push_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
end
|
||||
|
||||
trait :maintainers_can_merge do
|
||||
transient do
|
||||
default_push_level { false }
|
||||
end
|
||||
|
||||
after(:build) do |protected_branch|
|
||||
protected_branch.push_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
end
|
||||
|
||||
trait :developers_can_push do
|
||||
transient do
|
||||
default_push_level { false }
|
||||
|
@ -61,29 +91,13 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :maintainers_can_push do
|
||||
trait :no_one_can_merge do
|
||||
transient do
|
||||
default_push_level { false }
|
||||
default_merge_level { false }
|
||||
end
|
||||
|
||||
after(:build) do |protected_branch|
|
||||
protected_branch.push_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
end
|
||||
|
||||
after(:build) do |protected_branch, evaluator|
|
||||
if evaluator.default_access_level && evaluator.default_push_level
|
||||
protected_branch.push_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
|
||||
if evaluator.default_access_level && evaluator.default_merge_level
|
||||
protected_branch.merge_access_levels.new(access_level: Gitlab::Access::MAINTAINER)
|
||||
end
|
||||
end
|
||||
|
||||
trait :no_one_can_merge do
|
||||
after(:create) do |protected_branch|
|
||||
protected_branch.merge_access_levels.first.update!(access_level: Gitlab::Access::NO_ACCESS)
|
||||
protected_branch.merge_access_levels.new(access_level: Gitlab::Access::NO_ACCESS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ RSpec.describe 'Thread Comments Issue', :js do
|
|||
let(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ RSpec.describe 'Thread Comments Merge Request', :js do
|
|||
let(:merge_request) { create(:merge_request, source_project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ RSpec.describe "Jira", :js do
|
|||
before do
|
||||
remotelink = double(:remotelink, all: [], build: double(save!: true))
|
||||
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
|
||||
stub_request(:get, "https://jira.example.com/rest/api/2/issue/JIRA-5")
|
||||
stub_request(:post, "https://jira.example.com/rest/api/2/issue/JIRA-5/comment")
|
||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe 'List issue resource label events', :js do
|
|||
let!(:event) { create(:resource_label_event, user: user, issue: issue, label: label) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
visit project_issue_path(project, issue)
|
||||
wait_for_requests
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe 'User comments on a diff', :js do
|
|||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ RSpec.describe 'User comments on a merge request', :js do
|
|||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ RSpec.describe 'Project > Merge request > View user status' do
|
|||
end
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
end
|
||||
|
||||
subject { visit merge_request_path(merge_request) }
|
||||
|
|
|
@ -8,7 +8,7 @@ RSpec.describe 'User edit profile' do
|
|||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(remove_user_attributes: false)
|
||||
stub_feature_flags(remove_user_attributes_projects: false)
|
||||
sign_in(user)
|
||||
visit(profile_path)
|
||||
end
|
||||
|
|
|
@ -49,7 +49,8 @@ describe('NoteHeader component', () => {
|
|||
stubs: { GlSprintf, UserNameWithStatus },
|
||||
provide: {
|
||||
glFeatures: {
|
||||
removeUserAttributes: userAttributes,
|
||||
removeUserAttributesProjects: userAttributes,
|
||||
removeUserAttributesGroups: userAttributes,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -60,7 +61,7 @@ describe('NoteHeader component', () => {
|
|||
wrapper = null;
|
||||
});
|
||||
|
||||
describe('when removeUserAttributes feature flag is enabled', () => {
|
||||
describe('when removeUserAttributesProjects feature flag is enabled', () => {
|
||||
it('does not render busy status', () => {
|
||||
createComponent({ author: { ...author, availability: AVAILABILITY_STATUS.BUSY } }, true);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ describe('ImportHistoryApp', () => {
|
|||
describe('general behavior', () => {
|
||||
it('renders loading state when loading', () => {
|
||||
createComponent();
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders empty state when no data is available', async () => {
|
||||
|
@ -87,8 +87,8 @@ describe('ImportHistoryApp', () => {
|
|||
createComponent();
|
||||
await axios.waitForAll();
|
||||
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
|
||||
expect(wrapper.find(GlEmptyState).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
|
||||
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders table with data when history is available', async () => {
|
||||
|
@ -96,7 +96,7 @@ describe('ImportHistoryApp', () => {
|
|||
createComponent();
|
||||
await axios.waitForAll();
|
||||
|
||||
const table = wrapper.find(GlTable);
|
||||
const table = wrapper.findComponent(GlTable);
|
||||
expect(table.exists()).toBe(true);
|
||||
expect(table.props().items).toStrictEqual(DUMMY_RESPONSE);
|
||||
});
|
||||
|
@ -127,7 +127,7 @@ describe('ImportHistoryApp', () => {
|
|||
|
||||
expect(mock.history.get.length).toBe(1);
|
||||
expect(mock.history.get[0].params).toStrictEqual(expect.objectContaining({ page: NEW_PAGE }));
|
||||
expect(wrapper.find(GlTable).props().items).toStrictEqual(FAKE_NEXT_PAGE_REPLY);
|
||||
expect(wrapper.findComponent(GlTable).props().items).toStrictEqual(FAKE_NEXT_PAGE_REPLY);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ describe('ForkForm component', () => {
|
|||
const submitForm = async () => {
|
||||
fillForm();
|
||||
await nextTick();
|
||||
const form = wrapper.find(GlForm);
|
||||
const form = wrapper.findComponent(GlForm);
|
||||
|
||||
await form.trigger('submit');
|
||||
await nextTick();
|
||||
|
|
|
@ -20,8 +20,8 @@ describe('Code Coverage', () => {
|
|||
const graphRef = 'master';
|
||||
const graphCsvPath = 'url/';
|
||||
|
||||
const findAlert = () => wrapper.find(GlAlert);
|
||||
const findAreaChart = () => wrapper.find(GlAreaChart);
|
||||
const findAlert = () => wrapper.findComponent(GlAlert);
|
||||
const findAreaChart = () => wrapper.findComponent(GlAreaChart);
|
||||
const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
|
||||
const findFirstDropdownItem = () => findAllDropdownItems().at(0);
|
||||
const findSecondDropdownItem = () => findAllDropdownItems().at(1);
|
||||
|
@ -142,7 +142,7 @@ describe('Code Coverage', () => {
|
|||
});
|
||||
|
||||
it('renders the dropdown with all custom names as options', () => {
|
||||
expect(wrapper.find(GlDropdown).exists()).toBeDefined();
|
||||
expect(wrapper.findComponent(GlDropdown).exists()).toBeDefined();
|
||||
expect(findAllDropdownItems()).toHaveLength(codeCoverageMockData.length);
|
||||
expect(findFirstDropdownItem().text()).toBe(codeCoverageMockData[0].group_name);
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ describe('Pipeline Schedule Callout', () => {
|
|||
};
|
||||
|
||||
const findInnerContentOfCallout = () => wrapper.find('[data-testid="innerContent"]');
|
||||
const findDismissCalloutBtn = () => wrapper.find(GlButton);
|
||||
const findDismissCalloutBtn = () => wrapper.findComponent(GlButton);
|
||||
|
||||
describe(`when ${cookieKey} cookie is set`, () => {
|
||||
beforeEach(async () => {
|
||||
|
|
|
@ -81,15 +81,17 @@ describe('Settings Panel', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findLFSSettingsRow = () => wrapper.find({ ref: 'git-lfs-settings' });
|
||||
const findLFSSettingsRow = () => wrapper.findComponent({ ref: 'git-lfs-settings' });
|
||||
const findLFSSettingsMessage = () => findLFSSettingsRow().find('p');
|
||||
const findLFSFeatureToggle = () => findLFSSettingsRow().find(GlToggle);
|
||||
const findRepositoryFeatureProjectRow = () => wrapper.find({ ref: 'repository-settings' });
|
||||
const findLFSFeatureToggle = () => findLFSSettingsRow().findComponent(GlToggle);
|
||||
const findRepositoryFeatureProjectRow = () =>
|
||||
wrapper.findComponent({ ref: 'repository-settings' });
|
||||
const findRepositoryFeatureSetting = () =>
|
||||
findRepositoryFeatureProjectRow().find(ProjectFeatureSetting);
|
||||
const findProjectVisibilitySettings = () => wrapper.find({ ref: 'project-visibility-settings' });
|
||||
const findIssuesSettingsRow = () => wrapper.find({ ref: 'issues-settings' });
|
||||
const findAnalyticsRow = () => wrapper.find({ ref: 'analytics-settings' });
|
||||
findRepositoryFeatureProjectRow().findComponent(ProjectFeatureSetting);
|
||||
const findProjectVisibilitySettings = () =>
|
||||
wrapper.findComponent({ ref: 'project-visibility-settings' });
|
||||
const findIssuesSettingsRow = () => wrapper.findComponent({ ref: 'issues-settings' });
|
||||
const findAnalyticsRow = () => wrapper.findComponent({ ref: 'analytics-settings' });
|
||||
const findProjectVisibilityLevelInput = () => wrapper.find('[name="project[visibility_level]"]');
|
||||
const findRequestAccessEnabledInput = () =>
|
||||
wrapper.find('[name="project[request_access_enabled]"]');
|
||||
|
@ -99,31 +101,33 @@ describe('Settings Panel', () => {
|
|||
wrapper.find('[name="project[project_feature_attributes][forking_access_level]"]');
|
||||
const findBuildsAccessLevelInput = () =>
|
||||
wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]');
|
||||
const findContainerRegistrySettings = () => wrapper.find({ ref: 'container-registry-settings' });
|
||||
const findContainerRegistrySettings = () =>
|
||||
wrapper.findComponent({ ref: 'container-registry-settings' });
|
||||
const findContainerRegistryPublicNoteGlSprintfComponent = () =>
|
||||
findContainerRegistrySettings().findComponent(GlSprintf);
|
||||
const findContainerRegistryAccessLevelInput = () =>
|
||||
wrapper.find('[name="project[project_feature_attributes][container_registry_access_level]"]');
|
||||
const findPackageSettings = () => wrapper.find({ ref: 'package-settings' });
|
||||
const findPackageSettings = () => wrapper.findComponent({ ref: 'package-settings' });
|
||||
const findPackageAccessLevel = () =>
|
||||
wrapper.find('[data-testid="package-registry-access-level"]');
|
||||
const findPackageAccessLevels = () =>
|
||||
wrapper.find('[name="project[project_feature_attributes][package_registry_access_level]"]');
|
||||
const findPackagesEnabledInput = () => wrapper.find('[name="project[packages_enabled]"]');
|
||||
const findPagesSettings = () => wrapper.find({ ref: 'pages-settings' });
|
||||
const findPagesSettings = () => wrapper.findComponent({ ref: 'pages-settings' });
|
||||
const findPagesAccessLevels = () =>
|
||||
wrapper.find('[name="project[project_feature_attributes][pages_access_level]"]');
|
||||
const findEmailSettings = () => wrapper.find({ ref: 'email-settings' });
|
||||
const findEmailSettings = () => wrapper.findComponent({ ref: 'email-settings' });
|
||||
const findShowDefaultAwardEmojis = () =>
|
||||
wrapper.find('input[name="project[project_setting_attributes][show_default_award_emojis]"]');
|
||||
const findWarnAboutPuc = () =>
|
||||
wrapper.find(
|
||||
'input[name="project[project_setting_attributes][warn_about_potentially_unwanted_characters]"]',
|
||||
);
|
||||
const findMetricsVisibilitySettings = () => wrapper.find({ ref: 'metrics-visibility-settings' });
|
||||
const findMetricsVisibilitySettings = () =>
|
||||
wrapper.findComponent({ ref: 'metrics-visibility-settings' });
|
||||
const findMetricsVisibilityInput = () =>
|
||||
findMetricsVisibilitySettings().findComponent(ProjectFeatureSetting);
|
||||
const findOperationsSettings = () => wrapper.find({ ref: 'operations-settings' });
|
||||
const findOperationsSettings = () => wrapper.findComponent({ ref: 'operations-settings' });
|
||||
const findOperationsVisibilityInput = () =>
|
||||
findOperationsSettings().findComponent(ProjectFeatureSetting);
|
||||
const findConfirmDangerButton = () => wrapper.findComponent(ConfirmDanger);
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('WikiForm', () => {
|
|||
const findMarkdownHelpLink = () => wrapper.findByTestId('wiki-markdown-help-link');
|
||||
const findContentEditor = () => wrapper.findComponent(ContentEditor);
|
||||
const findClassicEditor = () => wrapper.findComponent(MarkdownField);
|
||||
const findLocalStorageSync = () => wrapper.find(LocalStorageSync);
|
||||
const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
|
||||
|
||||
const setFormat = (value) => {
|
||||
const format = findFormat();
|
||||
|
|
|
@ -257,7 +257,7 @@ describe('detailedMetric', () => {
|
|||
});
|
||||
|
||||
it('displays request warnings', () => {
|
||||
expect(wrapper.find(RequestWarning).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(RequestWarning).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('can open and close traces', async () => {
|
||||
|
|
|
@ -24,11 +24,11 @@ describe('CI Lint Results', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findTable = () => wrapper.find(GlTableLite);
|
||||
const findTable = () => wrapper.findComponent(GlTableLite);
|
||||
const findByTestId = (selector) => () => wrapper.find(`[data-testid="ci-lint-${selector}"]`);
|
||||
const findAllByTestId = (selector) => () =>
|
||||
wrapper.findAll(`[data-testid="ci-lint-${selector}"]`);
|
||||
const findLinkToDoc = () => wrapper.find(GlLink);
|
||||
const findLinkToDoc = () => wrapper.findComponent(GlLink);
|
||||
const findErrors = findByTestId('errors');
|
||||
const findWarnings = findByTestId('warnings');
|
||||
const findStatus = findByTestId('status');
|
||||
|
|
|
@ -17,9 +17,9 @@ describe('CI lint warnings', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findWarningAlert = () => wrapper.find(GlAlert);
|
||||
const findWarningAlert = () => wrapper.findComponent(GlAlert);
|
||||
const findWarnings = () => wrapper.findAll('[data-testid="ci-lint-warning"]');
|
||||
const findWarningMessage = () => trimText(wrapper.find(GlSprintf).text());
|
||||
const findWarningMessage = () => trimText(wrapper.findComponent(GlSprintf).text());
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
|
|
|
@ -254,7 +254,7 @@ describe('Pipeline editor home wrapper', () => {
|
|||
|
||||
expect(findPipelineEditorDrawer().props('isVisible')).toBe(true);
|
||||
|
||||
findPipelineEditorDrawer().find(GlDrawer).vm.$emit('close');
|
||||
findPipelineEditorDrawer().findComponent(GlDrawer).vm.$emit('close');
|
||||
await nextTick();
|
||||
|
||||
expect(findPipelineEditorDrawer().props('isVisible')).toBe(false);
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('Pipeline New Form', () => {
|
|||
let mock;
|
||||
let dummySubmitEvent;
|
||||
|
||||
const findForm = () => wrapper.find(GlForm);
|
||||
const findForm = () => wrapper.findComponent(GlForm);
|
||||
const findRefsDropdown = () => wrapper.findComponent(RefsDropdown);
|
||||
const findSubmitButton = () => wrapper.find('[data-testid="run_pipeline_button"]');
|
||||
const findVariableRows = () => wrapper.findAll('[data-testid="ci-variable-row"]');
|
||||
|
@ -44,9 +44,9 @@ describe('Pipeline New Form', () => {
|
|||
const findValueInputs = () => wrapper.findAll('[data-testid="pipeline-form-ci-variable-value"]');
|
||||
const findErrorAlert = () => wrapper.find('[data-testid="run-pipeline-error-alert"]');
|
||||
const findWarningAlert = () => wrapper.find('[data-testid="run-pipeline-warning-alert"]');
|
||||
const findWarningAlertSummary = () => findWarningAlert().find(GlSprintf);
|
||||
const findWarningAlertSummary = () => findWarningAlert().findComponent(GlSprintf);
|
||||
const findWarnings = () => wrapper.findAll('[data-testid="run-pipeline-warning"]');
|
||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const findCCAlert = () => wrapper.findComponent(CreditCardValidationRequiredAlert);
|
||||
const getFormPostParams = () => JSON.parse(mock.history.post[0].data);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('Pipeline New Form', () => {
|
|||
let mock;
|
||||
let dummySubmitEvent;
|
||||
|
||||
const findForm = () => wrapper.find(GlForm);
|
||||
const findForm = () => wrapper.findComponent(GlForm);
|
||||
const findRefsDropdown = () => wrapper.findComponent(RefsDropdown);
|
||||
const findSubmitButton = () => wrapper.find('[data-testid="run_pipeline_button"]');
|
||||
const findVariableRows = () => wrapper.findAll('[data-testid="ci-variable-row"]');
|
||||
|
@ -44,9 +44,9 @@ describe('Pipeline New Form', () => {
|
|||
const findValueInputs = () => wrapper.findAll('[data-testid="pipeline-form-ci-variable-value"]');
|
||||
const findErrorAlert = () => wrapper.find('[data-testid="run-pipeline-error-alert"]');
|
||||
const findWarningAlert = () => wrapper.find('[data-testid="run-pipeline-warning-alert"]');
|
||||
const findWarningAlertSummary = () => findWarningAlert().find(GlSprintf);
|
||||
const findWarningAlertSummary = () => findWarningAlert().findComponent(GlSprintf);
|
||||
const findWarnings = () => wrapper.findAll('[data-testid="run-pipeline-warning"]');
|
||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const findCCAlert = () => wrapper.findComponent(CreditCardValidationRequiredAlert);
|
||||
const getFormPostParams = () => JSON.parse(mock.history.post[0].data);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ describe('Pipeline New Form', () => {
|
|||
let wrapper;
|
||||
let mock;
|
||||
|
||||
const findDropdown = () => wrapper.find(GlDropdown);
|
||||
const findDropdown = () => wrapper.findComponent(GlDropdown);
|
||||
const findRefsDropdownItems = () => wrapper.findAll(GlDropdownItem);
|
||||
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ describe('Pipeline Wizard -- Input Wrapper', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
createComponent({});
|
||||
inputChild = wrapper.find(TextWidget);
|
||||
inputChild = wrapper.findComponent(TextWidget);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('The DAG annotations', () => {
|
|||
const getAllColorBlocks = () => wrapper.findAll('[data-testid="dag-color-block"]');
|
||||
const getTextBlock = () => wrapper.find('[data-testid="dag-note-text"]');
|
||||
const getAllTextBlocks = () => wrapper.findAll('[data-testid="dag-note-text"]');
|
||||
const getToggleButton = () => wrapper.find(GlButton);
|
||||
const getToggleButton = () => wrapper.findComponent(GlButton);
|
||||
|
||||
const createComponent = (propsData = {}, method = shallowMount) => {
|
||||
if (wrapper?.destroy) {
|
||||
|
|
|
@ -18,12 +18,12 @@ import {
|
|||
|
||||
describe('Pipeline DAG graph wrapper', () => {
|
||||
let wrapper;
|
||||
const getAlert = () => wrapper.find(GlAlert);
|
||||
const getAlert = () => wrapper.findComponent(GlAlert);
|
||||
const getAllAlerts = () => wrapper.findAll(GlAlert);
|
||||
const getGraph = () => wrapper.find(DagGraph);
|
||||
const getNotes = () => wrapper.find(DagAnnotations);
|
||||
const getGraph = () => wrapper.findComponent(DagGraph);
|
||||
const getNotes = () => wrapper.findComponent(DagAnnotations);
|
||||
const getErrorText = (type) => wrapper.vm.$options.errorTexts[type];
|
||||
const getEmptyState = () => wrapper.find(GlEmptyState);
|
||||
const getEmptyState = () => wrapper.findComponent(GlEmptyState);
|
||||
|
||||
const createComponent = ({
|
||||
graphData = mockParsedGraphQLNodes,
|
||||
|
|
|
@ -14,7 +14,7 @@ describe('Pipelines filtered search', () => {
|
|||
let wrapper;
|
||||
let mock;
|
||||
|
||||
const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
|
||||
const findFilteredSearch = () => wrapper.findComponent(GlFilteredSearch);
|
||||
const getSearchToken = (type) =>
|
||||
findFilteredSearch()
|
||||
.props('availableTokens')
|
||||
|
@ -191,7 +191,7 @@ describe('Pipelines filtered search', () => {
|
|||
findFilteredSearch().vm.$emit('submit', mockSearch);
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_filtered_search', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.search,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ import ActionComponent from '~/pipelines/components/jobs_shared/action_component
|
|||
describe('pipeline graph action component', () => {
|
||||
let wrapper;
|
||||
let mock;
|
||||
const findButton = () => wrapper.find(GlButton);
|
||||
const findButton = () => wrapper.findComponent(GlButton);
|
||||
const findTooltipWrapper = () => wrapper.find('[data-testid="ci-action-icon-tooltip-wrapper"]');
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -16,7 +16,7 @@ describe('graph component', () => {
|
|||
let wrapper;
|
||||
|
||||
const findLinkedColumns = () => wrapper.findAll(LinkedPipelinesColumn);
|
||||
const findLinksLayer = () => wrapper.find(LinksLayer);
|
||||
const findLinksLayer = () => wrapper.findComponent(LinksLayer);
|
||||
const findStageColumns = () => wrapper.findAll(StageColumnComponent);
|
||||
const findStageNameInJob = () => wrapper.find('[data-testid="stage-name-in-job"]');
|
||||
|
||||
|
@ -107,7 +107,7 @@ describe('graph component', () => {
|
|||
});
|
||||
|
||||
it('dims unrelated jobs', () => {
|
||||
const unrelatedJob = wrapper.find(JobItem);
|
||||
const unrelatedJob = wrapper.findComponent(JobItem);
|
||||
expect(findLinksLayer().emitted().highlightedJobsChange).toHaveLength(1);
|
||||
expect(unrelatedJob.classes('gl-opacity-3')).toBe(true);
|
||||
});
|
||||
|
|
|
@ -51,11 +51,11 @@ describe('Pipeline graph wrapper', () => {
|
|||
const getDependenciesToggle = () => wrapper.find('[data-testid="show-links-toggle"]');
|
||||
const getLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const getLinksLayer = () => wrapper.findComponent(LinksLayer);
|
||||
const getGraph = () => wrapper.find(PipelineGraph);
|
||||
const getGraph = () => wrapper.findComponent(PipelineGraph);
|
||||
const getStageColumnTitle = () => wrapper.find('[data-testid="stage-column-title"]');
|
||||
const getAllStageColumnGroupsInColumn = () =>
|
||||
wrapper.find(StageColumnComponent).findAll('[data-testid="stage-column-group"]');
|
||||
const getViewSelector = () => wrapper.find(GraphViewSelector);
|
||||
wrapper.findComponent(StageColumnComponent).findAll('[data-testid="stage-column-group"]');
|
||||
const getViewSelector = () => wrapper.findComponent(GraphViewSelector);
|
||||
const getViewSelectorTrip = () => getViewSelector().findComponent(GlAlert);
|
||||
const getLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
|
||||
|
||||
|
@ -408,7 +408,7 @@ describe('Pipeline graph wrapper', () => {
|
|||
|
||||
it('reads the view type from localStorage when available', () => {
|
||||
const viewSelectorNeedsSegment = wrapper
|
||||
.find(GlButtonGroup)
|
||||
.findComponent(GlButtonGroup)
|
||||
.findAllComponents(GlButton)
|
||||
.at(1);
|
||||
expect(viewSelectorNeedsSegment.classes()).toContain('selected');
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('the graph view selector component', () => {
|
|||
const findStageViewButton = () => findViewTypeSelector().findAllComponents(GlButton).at(0);
|
||||
const findLayerViewButton = () => findViewTypeSelector().findAllComponents(GlButton).at(1);
|
||||
const findSwitcherLoader = () => wrapper.find('[data-testid="switcher-loading-state"]');
|
||||
const findToggleLoader = () => findDependenciesToggle().find(GlLoadingIcon);
|
||||
const findToggleLoader = () => findDependenciesToggle().findComponent(GlLoadingIcon);
|
||||
const findHoverTip = () => wrapper.findComponent(GlAlert);
|
||||
|
||||
const defaultProps = {
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('job name component', () => {
|
|||
});
|
||||
|
||||
it('should render an icon with the provided status', () => {
|
||||
expect(wrapper.find(ciIcon).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(ciIcon).exists()).toBe(true);
|
||||
expect(wrapper.find('.ci-status-icon-success').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -36,13 +36,13 @@ describe('Linked pipeline', () => {
|
|||
type: UPSTREAM,
|
||||
};
|
||||
|
||||
const findButton = () => wrapper.find(GlButton);
|
||||
const findButton = () => wrapper.findComponent(GlButton);
|
||||
const findCancelButton = () => wrapper.findByLabelText('Cancel downstream pipeline');
|
||||
const findCardTooltip = () => wrapper.findComponent(GlTooltip);
|
||||
const findDownstreamPipelineTitle = () => wrapper.findByTestId('downstream-title');
|
||||
const findExpandButton = () => wrapper.findByTestId('expand-pipeline-button');
|
||||
const findLinkedPipeline = () => wrapper.find({ ref: 'linkedPipeline' });
|
||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
||||
const findLinkedPipeline = () => wrapper.findComponent({ ref: 'linkedPipeline' });
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const findPipelineLabel = () => wrapper.findByTestId('downstream-pipeline-label');
|
||||
const findPipelineLink = () => wrapper.findByTestId('pipelineLink');
|
||||
const findRetryButton = () => wrapper.findByLabelText('Retry downstream pipeline');
|
||||
|
@ -80,7 +80,7 @@ describe('Linked pipeline', () => {
|
|||
});
|
||||
|
||||
it('should render an svg within the status container', () => {
|
||||
const pipelineStatusElement = wrapper.find(CiStatus);
|
||||
const pipelineStatusElement = wrapper.findComponent(CiStatus);
|
||||
|
||||
expect(pipelineStatusElement.find('svg').exists()).toBe(true);
|
||||
});
|
||||
|
@ -90,7 +90,7 @@ describe('Linked pipeline', () => {
|
|||
});
|
||||
|
||||
it('should have a ci-status child component', () => {
|
||||
expect(wrapper.find(CiStatus).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(CiStatus).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should render the pipeline id', () => {
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('Linked Pipelines Column', () => {
|
|||
let wrapper;
|
||||
const findLinkedColumnTitle = () => wrapper.find('[data-testid="linked-column-title"]');
|
||||
const findLinkedPipelineElements = () => wrapper.findAll(LinkedPipeline);
|
||||
const findPipelineGraph = () => wrapper.find(PipelineGraph);
|
||||
const findPipelineGraph = () => wrapper.findComponent(PipelineGraph);
|
||||
const findExpandButton = () => wrapper.find('[data-testid="expand-pipeline-button"]');
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
|
|
@ -42,8 +42,8 @@ describe('stage column component', () => {
|
|||
const findStageColumnTitle = () => wrapper.find('[data-testid="stage-column-title"]');
|
||||
const findStageColumnGroup = () => wrapper.find('[data-testid="stage-column-group"]');
|
||||
const findAllStageColumnGroups = () => wrapper.findAll('[data-testid="stage-column-group"]');
|
||||
const findJobItem = () => wrapper.find(JobItem);
|
||||
const findActionComponent = () => wrapper.find(ActionComponent);
|
||||
const findJobItem = () => wrapper.findComponent(JobItem);
|
||||
const findActionComponent = () => wrapper.findComponent(ActionComponent);
|
||||
|
||||
const createComponent = ({ method = shallowMount, props = {} } = {}) => {
|
||||
wrapper = method(StageColumnComponent, {
|
||||
|
|
|
@ -6,7 +6,7 @@ import { generateResponse, mockPipelineResponse } from '../graph/mock_data';
|
|||
describe('links layer component', () => {
|
||||
let wrapper;
|
||||
|
||||
const findLinksInner = () => wrapper.find(LinksInner);
|
||||
const findLinksInner = () => wrapper.findComponent(LinksInner);
|
||||
|
||||
const pipeline = generateResponse(mockPipelineResponse, 'root/fungi-xoxo');
|
||||
const containerId = `pipeline-links-container-${pipeline.id}`;
|
||||
|
|
|
@ -21,12 +21,12 @@ describe('Pipeline details header', () => {
|
|||
let glModalDirective;
|
||||
let mutate = jest.fn();
|
||||
|
||||
const findAlert = () => wrapper.find(GlAlert);
|
||||
const findDeleteModal = () => wrapper.find(GlModal);
|
||||
const findAlert = () => wrapper.findComponent(GlAlert);
|
||||
const findDeleteModal = () => wrapper.findComponent(GlModal);
|
||||
const findRetryButton = () => wrapper.find('[data-testid="retryPipeline"]');
|
||||
const findCancelButton = () => wrapper.find('[data-testid="cancelPipeline"]');
|
||||
const findDeleteButton = () => wrapper.find('[data-testid="deletePipeline"]');
|
||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
|
||||
const defaultProvideOptions = {
|
||||
pipelineId: '14',
|
||||
|
|
|
@ -152,7 +152,7 @@ describe('Pipeline Multi Actions Dropdown', () => {
|
|||
findDropdown().vm.$emit('show');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_artifacts_dropdown', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -117,7 +117,7 @@ describe('Pipeline Url Component', () => {
|
|||
findPipelineUrlLink().vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_pipeline_id', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -127,7 +127,7 @@ describe('Pipeline Url Component', () => {
|
|||
findRefName().vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_mr_ref', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -137,7 +137,7 @@ describe('Pipeline Url Component', () => {
|
|||
findCommitRefName().vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_commit_name', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -147,7 +147,7 @@ describe('Pipeline Url Component', () => {
|
|||
findCommitTitle(findCommitTitleContainer()).vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_commit_title', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -157,7 +157,7 @@ describe('Pipeline Url Component', () => {
|
|||
findCommitShortSha().vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_commit_sha', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Pipelines Actions dropdown', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findDropdown = () => wrapper.find(GlDropdown);
|
||||
const findDropdown = () => wrapper.findComponent(GlDropdown);
|
||||
const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
|
||||
const findAllCountdowns = () => wrapper.findAll(GlCountdown);
|
||||
|
||||
|
@ -110,7 +110,7 @@ describe('Pipelines Actions dropdown', () => {
|
|||
findDropdown().vm.$emit('shown');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_manual_actions', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,8 +30,8 @@ describe('Pipelines Artifacts dropdown', () => {
|
|||
};
|
||||
|
||||
const findDropdown = () => wrapper.findComponent(GlDropdown);
|
||||
const findFirstGlDropdownItem = () => wrapper.find(GlDropdownItem);
|
||||
const findAllGlDropdownItems = () => wrapper.find(GlDropdown).findAll(GlDropdownItem);
|
||||
const findFirstGlDropdownItem = () => wrapper.findComponent(GlDropdownItem);
|
||||
const findAllGlDropdownItems = () => wrapper.findComponent(GlDropdown).findAll(GlDropdownItem);
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
|
|
|
@ -7,6 +7,7 @@ import { nextTick } from 'vue';
|
|||
import mockPipelinesResponse from 'test_fixtures/pipelines/pipelines.json';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import { TEST_HOST } from 'helpers/test_constants';
|
||||
import { mockTracking } from 'helpers/tracking_helper';
|
||||
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import Api from '~/api';
|
||||
|
@ -16,7 +17,7 @@ import NavigationControls from '~/pipelines/components/pipelines_list/nav_contro
|
|||
import PipelinesComponent from '~/pipelines/components/pipelines_list/pipelines.vue';
|
||||
import PipelinesCiTemplates from '~/pipelines/components/pipelines_list/empty_state/pipelines_ci_templates.vue';
|
||||
import PipelinesTableComponent from '~/pipelines/components/pipelines_list/pipelines_table.vue';
|
||||
import { RAW_TEXT_WARNING } from '~/pipelines/constants';
|
||||
import { RAW_TEXT_WARNING, TRACKING_CATEGORIES } from '~/pipelines/constants';
|
||||
import Store from '~/pipelines/stores/pipelines_store';
|
||||
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
|
||||
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
|
||||
|
@ -37,6 +38,7 @@ const mockPipelineWithStages = mockPipelinesResponse.pipelines.find(
|
|||
describe('Pipelines', () => {
|
||||
let wrapper;
|
||||
let mock;
|
||||
let trackingSpy;
|
||||
|
||||
const paths = {
|
||||
emptyStateSvgPath: '/assets/illustrations/pipelines_empty.svg',
|
||||
|
@ -123,7 +125,7 @@ describe('Pipelines', () => {
|
|||
});
|
||||
|
||||
it('shows loading state when the app is loading', () => {
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not display tabs when the first request has not yet been made', () => {
|
||||
|
@ -236,6 +238,8 @@ describe('Pipelines', () => {
|
|||
count: mockPipelinesResponse.count,
|
||||
});
|
||||
|
||||
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
|
||||
|
||||
goToTab('finished');
|
||||
|
||||
await waitForPromises();
|
||||
|
@ -256,6 +260,12 @@ describe('Pipelines', () => {
|
|||
`${window.location.pathname}?scope=finished&page=1`,
|
||||
);
|
||||
});
|
||||
|
||||
it('tracks tab change click', () => {
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_filter_tabs', {
|
||||
label: TRACKING_CATEGORIES.tabs,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the scope in the tab is empty', () => {
|
||||
|
@ -375,7 +385,7 @@ describe('Pipelines', () => {
|
|||
const [firstPage, secondPage] = chunk(mockPipelinesResponse.pipelines, mockPageSize);
|
||||
|
||||
const goToPage = (page) => {
|
||||
findTablePagination().find(GlPagination).vm.$emit('input', page);
|
||||
findTablePagination().findComponent(GlPagination).vm.$emit('input', page);
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
|
@ -583,7 +593,7 @@ describe('Pipelines', () => {
|
|||
'This project is not currently set up to run pipelines.',
|
||||
);
|
||||
|
||||
expect(findEmptyState().find(GlButton).exists()).toBe(false);
|
||||
expect(findEmptyState().findComponent(GlButton).exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('does not render tabs or buttons', () => {
|
||||
|
|
|
@ -181,7 +181,7 @@ describe('Pipelines Table', () => {
|
|||
findStatusBadge().vm.$emit('ciStatusBadgeClick');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_ci_status_badge', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -189,7 +189,7 @@ describe('Pipelines Table', () => {
|
|||
findRetryBtn().vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_retry_button', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -197,7 +197,7 @@ describe('Pipelines Table', () => {
|
|||
findCancelBtn().vm.$emit('click');
|
||||
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_cancel_button', {
|
||||
label: TRACKING_CATEGORIES.index,
|
||||
label: TRACKING_CATEGORIES.table,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,10 +26,10 @@ describe('Test reports suite table', () => {
|
|||
|
||||
const noCasesMessage = () => wrapper.findByTestId('no-test-cases');
|
||||
const artifactsExpiredMessage = () => wrapper.findByTestId('artifacts-expired');
|
||||
const artifactsExpiredEmptyState = () => wrapper.find(GlEmptyState);
|
||||
const artifactsExpiredEmptyState = () => wrapper.findComponent(GlEmptyState);
|
||||
const allCaseRows = () => wrapper.findAllByTestId('test-case-row');
|
||||
const findCaseRowAtIndex = (index) => wrapper.findAllByTestId('test-case-row').at(index);
|
||||
const findLinkForRow = (row) => row.find(GlLink);
|
||||
const findLinkForRow = (row) => row.findComponent(GlLink);
|
||||
const findIconForRow = (row, status) => row.find(`.ci-status-icon-${status}`);
|
||||
|
||||
const createComponent = ({ suite = testSuite, perPage = 20, errorMessage } = {}) => {
|
||||
|
@ -113,7 +113,7 @@ describe('Test reports suite table', () => {
|
|||
const filePath = `${blobPath}/${relativeFile}`;
|
||||
const row = findCaseRowAtIndex(0);
|
||||
const fileLink = findLinkForRow(row);
|
||||
const button = row.find(GlButton);
|
||||
const button = row.findComponent(GlButton);
|
||||
|
||||
expect(fileLink.attributes('href')).toBe(filePath);
|
||||
expect(row.text()).toContain(file);
|
||||
|
@ -134,7 +134,7 @@ describe('Test reports suite table', () => {
|
|||
});
|
||||
|
||||
it('renders a pagination component', () => {
|
||||
expect(wrapper.find(GlPagination).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ describe('Test reports summary table', () => {
|
|||
|
||||
describe('when test reports are supplied', () => {
|
||||
beforeEach(() => createComponent());
|
||||
const findErrorIcon = () => wrapper.find({ ref: 'suiteErrorIcon' });
|
||||
const findErrorIcon = () => wrapper.findComponent({ ref: 'suiteErrorIcon' });
|
||||
|
||||
it('renders the correct number of rows', () => {
|
||||
expect(noSuitesToShow().exists()).toBe(false);
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('Timeago component', () => {
|
|||
});
|
||||
|
||||
it('should render duration and timer svg', () => {
|
||||
const icon = duration().find(GlIcon);
|
||||
const icon = duration().findComponent(GlIcon);
|
||||
|
||||
expect(duration().exists()).toBe(true);
|
||||
expect(icon.props('name')).toBe('timer');
|
||||
|
@ -71,7 +71,7 @@ describe('Timeago component', () => {
|
|||
});
|
||||
|
||||
it('should render time and calendar icon', () => {
|
||||
const icon = finishedAt().find(GlIcon);
|
||||
const icon = finishedAt().findComponent(GlIcon);
|
||||
const time = finishedAt().find('time');
|
||||
|
||||
expect(finishedAt().exists()).toBe(true);
|
||||
|
|
|
@ -9,9 +9,9 @@ import { branches, mockBranchesAfterMap } from '../mock_data';
|
|||
describe('Pipeline Branch Name Token', () => {
|
||||
let wrapper;
|
||||
|
||||
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
|
||||
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
|
||||
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
|
||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const getBranchSuggestions = () =>
|
||||
findAllFilteredSearchSuggestions().wrappers.map((w) => w.text());
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import PipelineSourceToken from '~/pipelines/components/pipelines_list/tokens/pi
|
|||
describe('Pipeline Source Token', () => {
|
||||
let wrapper;
|
||||
|
||||
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
|
||||
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
|
||||
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
|
||||
|
||||
const defaultProps = {
|
||||
|
|
|
@ -6,7 +6,7 @@ import PipelineStatusToken from '~/pipelines/components/pipelines_list/tokens/pi
|
|||
describe('Pipeline Status Token', () => {
|
||||
let wrapper;
|
||||
|
||||
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
|
||||
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
|
||||
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
|
||||
const findAllGlIcons = () => wrapper.findAll(GlIcon);
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ import { tags, mockTagsAfterMap } from '../mock_data';
|
|||
describe('Pipeline Branch Name Token', () => {
|
||||
let wrapper;
|
||||
|
||||
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
|
||||
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
|
||||
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
|
||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
|
||||
const stubs = {
|
||||
GlFilteredSearchToken: {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue