Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0d1b0d5d03
commit
47d926e838
|
|
@ -18,6 +18,7 @@ import cancelJobMutation from '../graphql/mutations/job_cancel.mutation.graphql'
|
|||
import playJobMutation from '../graphql/mutations/job_play.mutation.graphql';
|
||||
import retryJobMutation from '../graphql/mutations/job_retry.mutation.graphql';
|
||||
import unscheduleJobMutation from '../graphql/mutations/job_unschedule.mutation.graphql';
|
||||
import { reportMessageToSentry } from '../../../utils';
|
||||
|
||||
export default {
|
||||
ACTIONS_DOWNLOAD_ARTIFACTS,
|
||||
|
|
@ -34,6 +35,7 @@ export default {
|
|||
jobPlay: 'jobPlay',
|
||||
jobUnschedule: 'jobUnschedule',
|
||||
playJobModalId: 'play-job-modal',
|
||||
name: 'JobActionsCell',
|
||||
components: {
|
||||
GlButton,
|
||||
GlButtonGroup,
|
||||
|
|
@ -99,15 +101,17 @@ export default {
|
|||
variables: { id: this.job.id },
|
||||
});
|
||||
if (errors.length > 0) {
|
||||
this.reportFailure();
|
||||
reportMessageToSentry(this.$options.name, errors.join(', '), {});
|
||||
this.showToastMessage();
|
||||
} else {
|
||||
eventHub.$emit('jobActionPerformed');
|
||||
}
|
||||
} catch {
|
||||
this.reportFailure();
|
||||
} catch (failure) {
|
||||
reportMessageToSentry(this.$options.name, failure, {});
|
||||
this.showToastMessage();
|
||||
}
|
||||
},
|
||||
reportFailure() {
|
||||
showToastMessage() {
|
||||
const toastProps = {
|
||||
text: this.$options.GENERIC_ERROR,
|
||||
variant: 'danger',
|
||||
|
|
|
|||
|
|
@ -19,3 +19,12 @@ export const reportToSentry = (component, failureType) => {
|
|||
Sentry.captureException(failureType);
|
||||
});
|
||||
};
|
||||
|
||||
export const reportMessageToSentry = (component, message, context) => {
|
||||
Sentry.withScope((scope) => {
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
scope.setContext('Vue data', context);
|
||||
scope.setTag('component', component);
|
||||
Sentry.captureMessage(message);
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
<script>
|
||||
import { GlButton, GlDropdown, GlDropdownItem } from '@gitlab/ui';
|
||||
import { sprintf, __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
},
|
||||
props: {
|
||||
widget: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
tertiaryButtons: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
dropdownLabel() {
|
||||
return sprintf(__('%{widget} options'), { widget: this.widget });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<gl-dropdown
|
||||
:text="dropdownLabel"
|
||||
icon="ellipsis_v"
|
||||
no-caret
|
||||
category="tertiary"
|
||||
right
|
||||
lazy
|
||||
text-sr-only
|
||||
size="small"
|
||||
class="gl-display-block gl-md-display-none!"
|
||||
>
|
||||
<gl-dropdown-item
|
||||
v-for="(btn, index) in tertiaryButtons"
|
||||
:key="index"
|
||||
:href="btn.href"
|
||||
:target="btn.target"
|
||||
>
|
||||
{{ btn.text }}
|
||||
</gl-dropdown-item>
|
||||
</gl-dropdown>
|
||||
<template v-if="tertiaryButtons.length">
|
||||
<gl-button
|
||||
v-for="(btn, index) in tertiaryButtons"
|
||||
:key="index"
|
||||
:href="btn.href"
|
||||
:target="btn.target"
|
||||
:class="{ 'gl-mr-3': index > 1 }"
|
||||
category="tertiary"
|
||||
variant="confirm"
|
||||
size="small"
|
||||
class="gl-display-none gl-md-display-block"
|
||||
>
|
||||
{{ btn.text }}
|
||||
</gl-button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -11,6 +11,7 @@ import { sprintf, s__ } from '~/locale';
|
|||
import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
|
||||
import { EXTENSION_ICON_CLASS } from '../../constants';
|
||||
import StatusIcon from './status_icon.vue';
|
||||
import Actions from './actions.vue';
|
||||
|
||||
export const LOADING_STATES = {
|
||||
collapsedLoading: 'collapsedLoading',
|
||||
|
|
@ -26,6 +27,7 @@ export default {
|
|||
GlBadge,
|
||||
SmartVirtualList,
|
||||
StatusIcon,
|
||||
Actions,
|
||||
},
|
||||
directives: {
|
||||
SafeHtml: GlSafeHtmlDirective,
|
||||
|
|
@ -66,6 +68,9 @@ export default {
|
|||
|
||||
return this.statusIcon(this.collapsedData);
|
||||
},
|
||||
tertiaryActionsButtons() {
|
||||
return this.tertiaryButtons ? this.tertiaryButtons() : undefined;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isCollapsed(newVal) {
|
||||
|
|
@ -119,13 +124,16 @@ export default {
|
|||
:is-loading="isLoadingSummary"
|
||||
:icon-name="statusIconName"
|
||||
/>
|
||||
<div class="media-body gl-display-flex gl-align-self-center gl-align-items-center">
|
||||
<div class="code-text">
|
||||
<div
|
||||
class="media-body gl-display-flex gl-align-self-center gl-align-items-center gl-flex-direction-row!"
|
||||
>
|
||||
<div class="gl-flex-grow-1">
|
||||
<template v-if="isLoadingSummary">
|
||||
{{ __('Loading...') }}
|
||||
</template>
|
||||
<div v-else v-safe-html="summary(collapsedData)"></div>
|
||||
</div>
|
||||
<actions :widget="$options.name" :tertiary-buttons="tertiaryActionsButtons" />
|
||||
<div
|
||||
class="gl-float-right gl-align-self-center gl-border-l-1 gl-border-l-solid gl-border-gray-100 gl-ml-3 gl-pl-3"
|
||||
>
|
||||
|
|
@ -138,6 +146,7 @@ export default {
|
|||
:icon="isCollapsed ? 'chevron-lg-down' : 'chevron-lg-up'"
|
||||
category="tertiary"
|
||||
data-testid="toggle-button"
|
||||
size="small"
|
||||
@click="toggleCollapsed"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default {
|
|||
name: 'Issues',
|
||||
// Add an array of props
|
||||
// These then get mapped to values stored in the MR Widget store
|
||||
props: ['targetProjectFullPath'],
|
||||
props: ['targetProjectFullPath', 'conflictsDocsPath'],
|
||||
// Add any extra computed props in here
|
||||
computed: {
|
||||
// Small summary text to be displayed in the collapsed state
|
||||
|
|
@ -22,6 +22,11 @@ export default {
|
|||
statusIcon(count) {
|
||||
return EXTENSION_ICONS.warning;
|
||||
},
|
||||
// Tertiary action buttons that will take the user elsewhere
|
||||
// in the GitLab app
|
||||
tertiaryButtons() {
|
||||
return [{ text: 'Full report', href: this.conflictsDocsPath, target: '_blank' }];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// Fetches the collapsed data
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ module Ci
|
|||
class PipelinesForMergeRequestFinder
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
COMMITS_LIMIT = 100
|
||||
|
||||
def initialize(merge_request, current_user)
|
||||
@merge_request = merge_request
|
||||
@current_user = current_user
|
||||
|
|
@ -12,7 +14,7 @@ module Ci
|
|||
|
||||
attr_reader :merge_request, :current_user
|
||||
|
||||
delegate :commit_shas, :target_project, :source_project, :source_branch, to: :merge_request
|
||||
delegate :recent_diff_head_shas, :commit_shas, :target_project, :source_project, :source_branch, to: :merge_request
|
||||
|
||||
# Fetch all pipelines that the user can read.
|
||||
def execute
|
||||
|
|
@ -35,7 +37,7 @@ module Ci
|
|||
|
||||
pipelines =
|
||||
if merge_request.persisted?
|
||||
pipelines_using_cte
|
||||
all_pipelines_for_merge_request
|
||||
else
|
||||
triggered_for_branch.for_sha(commit_shas)
|
||||
end
|
||||
|
|
@ -79,6 +81,17 @@ module Ci
|
|||
pipelines.joins(shas_table) # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
def all_pipelines_for_merge_request
|
||||
if Feature.enabled?(:decomposed_ci_query_in_pipelines_for_merge_request_finder, target_project, default_enabled: :yaml)
|
||||
pipelines_for_merge_request = triggered_by_merge_request
|
||||
pipelines_for_branch = triggered_for_branch.for_sha(recent_diff_head_shas(COMMITS_LIMIT))
|
||||
|
||||
Ci::Pipeline.from_union([pipelines_for_merge_request, pipelines_for_branch])
|
||||
else
|
||||
pipelines_using_cte
|
||||
end
|
||||
end
|
||||
|
||||
# NOTE: this method returns only parent merge request pipelines.
|
||||
# Child merge request pipelines have a different source.
|
||||
def triggered_by_merge_request
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ module Clusters
|
|||
validates :cluster, presence: true
|
||||
validates :enabled, inclusion: { in: [true, false] }
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
|
||||
def available?
|
||||
enabled
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ module Clusters
|
|||
|
||||
default_value_for(:alert_manager_token) { SecureRandom.hex }
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
|
||||
after_destroy do
|
||||
run_after_commit do
|
||||
deactivate_project_integrations
|
||||
|
|
|
|||
|
|
@ -1658,6 +1658,10 @@ class MergeRequest < ApplicationRecord
|
|||
service_class.new(project, current_user, id: id, report_type: report_type).execute(comparison_base_pipeline(identifier), actual_head_pipeline)
|
||||
end
|
||||
|
||||
def recent_diff_head_shas(limit = 100)
|
||||
merge_request_diffs.recent(limit).pluck(:head_commit_sha)
|
||||
end
|
||||
|
||||
def all_commits
|
||||
MergeRequestDiffCommit
|
||||
.where(merge_request_diff: merge_request_diffs.recent)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class MergeRequestDiff < ApplicationRecord
|
|||
joins(:merge_request).where(merge_requests: { target_project_id: project_id })
|
||||
end
|
||||
|
||||
scope :recent, -> { order(id: :desc).limit(100) }
|
||||
scope :recent, -> (limit = 100) { order(id: :desc).limit(limit) }
|
||||
|
||||
scope :files_in_database, -> do
|
||||
where(stored_externally: [false, nil]).where(arel_table[:files_count].gt(0))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: add_actor_based_user_to_snowplow_tracking
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71353
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338150
|
||||
milestone: '14.4'
|
||||
type: development
|
||||
group: group::product intelligence
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: decomposed_ci_query_in_pipelines_for_merge_request_finder
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68549
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341341
|
||||
milestone: '14.4'
|
||||
type: development
|
||||
group: group::pipeline execution
|
||||
default_enabled: false
|
||||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -20,3 +20,4 @@ tier:
|
|||
name: 'count_distinct_user_id_from_clusters_applications_cert_managers'
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -20,3 +20,4 @@ tier:
|
|||
name: 'count_distinct_user_id_from_clusters_applications_helm'
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -20,3 +20,4 @@ tier:
|
|||
name: 'count_distinct_user_id_from_clusters_applications_ingress'
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -20,3 +20,4 @@ tier:
|
|||
name: 'count_distinct_user_id_from_clusters_applications_knative'
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: monitor
|
|||
product_group: group::monitor
|
||||
product_category: metrics
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: verify
|
|||
product_group: group::runner
|
||||
product_category: runner
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: usage_activity_by_stage_monthly.monitor.clusters_integrations_prometheus
|
||||
description: Users creating clusters with Prometheus integration enabled in last 28 days.
|
||||
product_section: ops
|
||||
product_stage: monitor
|
||||
product_group: group::monitor
|
||||
product_category: metrics
|
||||
value_type: number
|
||||
status: active
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "14.4"
|
||||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -19,3 +19,4 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -18,3 +18,4 @@ tier:
|
|||
- premium
|
||||
- ultimate
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -18,3 +18,4 @@ tier:
|
|||
- premium
|
||||
- ultimate
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -18,3 +18,4 @@ tier:
|
|||
- premium
|
||||
- ultimate
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -18,3 +18,4 @@ tier:
|
|||
- premium
|
||||
- ultimate
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: monitor
|
|||
product_group: group::monitor
|
||||
product_category: metrics
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -18,3 +18,4 @@ tier:
|
|||
- premium
|
||||
- ultimate
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: configure
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
@ -18,3 +18,4 @@ tier:
|
|||
- premium
|
||||
- ultimate
|
||||
milestone: "<13.9"
|
||||
milestone_removed: "14.4"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: counts.clusters_integrations_prometheus
|
||||
description: Total clusters with Clusters::Integrations::Prometheus enabled
|
||||
product_section: ops
|
||||
product_stage: configure
|
||||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "14.4"
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: counts.clusters_integrations_elastic_stack
|
||||
description: Total clusters with Clusters::Integrations::ElasticStack enabled
|
||||
product_section: ops
|
||||
product_stage: configure
|
||||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: active
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "14.4"
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: usage_activity_by_stage.monitor.clusters_integrations_prometheus
|
||||
description: Users creating clusters with Prometheus integration enabled in last 28 days.
|
||||
product_section: ops
|
||||
product_stage: monitor
|
||||
product_group: group::monitor
|
||||
product_category: metrics
|
||||
value_type: number
|
||||
status: active
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
milestone: "14.4"
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexOnClustersIntegrationPrometheusEnabled < Gitlab::Database::Migration[1.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_clusters_integration_prometheus_enabled'
|
||||
|
||||
def up
|
||||
add_concurrent_index(:clusters_integration_prometheus, [:enabled, :created_at, :cluster_id], name: INDEX_NAME)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name(:clusters_integration_prometheus, INDEX_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexOnClustersIntegrationElasticStackEnabled < Gitlab::Database::Migration[1.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_clusters_integration_elasticstack_enabled'
|
||||
|
||||
def up
|
||||
add_concurrent_index(:clusters_integration_elasticstack, [:enabled, :created_at, :cluster_id], name: INDEX_NAME)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name(:clusters_integration_elasticstack, INDEX_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
ffb4e066420e1492550255e5866df6dc9f83d3d6cec9033284c4c3194d53b827
|
||||
|
|
@ -0,0 +1 @@
|
|||
fc8f86f794d77902fd86acaec6046b65821ff685f841d28158dc05fb55773c16
|
||||
|
|
@ -24767,6 +24767,10 @@ CREATE UNIQUE INDEX index_clusters_applications_runners_on_cluster_id ON cluster
|
|||
|
||||
CREATE INDEX index_clusters_applications_runners_on_runner_id ON clusters_applications_runners USING btree (runner_id);
|
||||
|
||||
CREATE INDEX index_clusters_integration_elasticstack_enabled ON clusters_integration_elasticstack USING btree (enabled, created_at, cluster_id);
|
||||
|
||||
CREATE INDEX index_clusters_integration_prometheus_enabled ON clusters_integration_prometheus USING btree (enabled, created_at, cluster_id);
|
||||
|
||||
CREATE INDEX index_clusters_kubernetes_namespaces_on_cluster_id ON clusters_kubernetes_namespaces USING btree (cluster_id);
|
||||
|
||||
CREATE INDEX index_clusters_kubernetes_namespaces_on_cluster_project_id ON clusters_kubernetes_namespaces USING btree (cluster_project_id);
|
||||
|
|
|
|||
|
|
@ -407,6 +407,7 @@ listed in the descriptions of the relevant settings.
|
|||
| `spam_check_endpoint_enabled` | boolean | no | Enables Spam Check via external API endpoint. Default is `false`. |
|
||||
| `spam_check_endpoint_url` | string | no | URL of the external Spam Check service endpoint. |
|
||||
| `spam_check_api_key` | string | no | The API key used by GitLab for accessing the Spam Check service endpoint. |
|
||||
| `suggest_pipeline_enabled` | boolean | no | Enable pipeline suggestion banner. |
|
||||
| `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. |
|
||||
| `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. |
|
||||
| `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
|
||||
|
|
|
|||
|
|
@ -60,6 +60,11 @@ in the handbook when writing about Alpha features.
|
|||
|
||||
Instead of **and/or**, use **or** or rewrite the sentence to spell out both options.
|
||||
|
||||
## and so on
|
||||
|
||||
Do not use **and so on**. Instead, be more specific. For details, see
|
||||
[the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/a/and-so-on).
|
||||
|
||||
## area
|
||||
|
||||
Use [**section**](#section) instead of **area**. The only exception is [the Admin Area](#admin-admin-area).
|
||||
|
|
@ -213,7 +218,8 @@ Use lowercase for **epic board**.
|
|||
|
||||
## etc.
|
||||
|
||||
Try to avoid **etc.**. Be as specific as you can. Do not use **and so on** as a replacement.
|
||||
Try to avoid **etc.**. Be as specific as you can. Do not use
|
||||
[**and so on**](#and-so-on) as a replacement.
|
||||
|
||||
- Do: You can update objects, like merge requests and issues.
|
||||
- Do not: You can update objects, like merge requests, issues, etc.
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ We use the following terminology to describe the Service Ping components:
|
|||
|
||||
Starting with GitLab version 14.1, free self-managed users running [GitLab EE](../ee_features.md) can receive paid features by registering with GitLab and sending us activity data via [Service Ping](#what-is-service-ping). Features introduced here do not remove the feature from its paid tier. Users can continue to access the features in a paid tier without sharing usage data.
|
||||
|
||||
The paid feature available in this offering is [Email from GitLab](../../tools/email.md).
|
||||
Administrators can use this [Premium](https://about.gitlab.com/pricing/premium/) feature to streamline
|
||||
their workflow by emailing all or some instance users directly from the Admin Area.
|
||||
##### Features available in 14.1 and later
|
||||
|
||||
1. [Email from GitLab](../../tools/email.md).
|
||||
|
||||
NOTE:
|
||||
Registration is not yet required for participation, but will be added in a future milestone.
|
||||
|
|
|
|||
|
|
@ -264,8 +264,6 @@ module API
|
|||
when 'md5'
|
||||
''
|
||||
else
|
||||
track_package_event('push_package', :maven, user: current_user, project: user_project, namespace: user_project.namespace) if jar_file?(format)
|
||||
|
||||
file_params = {
|
||||
file: params[:file],
|
||||
size: params['file.size'],
|
||||
|
|
@ -276,6 +274,7 @@ module API
|
|||
}
|
||||
|
||||
::Packages::CreatePackageFileService.new(package, file_params.merge(build: current_authenticated_job)).execute
|
||||
track_package_event('push_package', :maven, user: current_user, project: user_project, namespace: user_project.namespace) if jar_file?(format)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ module API
|
|||
optional :whats_new_variant, type: String, values: ApplicationSetting.whats_new_variants.keys, desc: "What's new variant, possible values: `all_tiers`, `current_tier`, and `disabled`."
|
||||
optional :floc_enabled, type: Grape::API::Boolean, desc: 'Enable FloC (Federated Learning of Cohorts)'
|
||||
optional :user_deactivation_emails_enabled, type: Boolean, desc: 'Send emails to users upon account deactivation'
|
||||
optional :suggest_pipeline_enabled, type: Boolean, desc: 'Enable pipeline suggestion banner'
|
||||
|
||||
ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
|
||||
optional :"#{type}_key_restriction",
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ module Gitlab
|
|||
|
||||
# We want to use AttributesCleaner for these relations instead, in the future this should be removed to make sure
|
||||
# we are using AttributesPermitter for every imported relation.
|
||||
DISABLED_RELATION_NAMES = %i[user author ci_cd_settings issuable_sla push_rule].freeze
|
||||
DISABLED_RELATION_NAMES = %i[user author issuable_sla].freeze
|
||||
|
||||
def initialize(config: ImportExport::Config.new.to_h)
|
||||
@config = config
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ module Gitlab
|
|||
|
||||
def parsed_relation_hash
|
||||
strong_memoize(:parsed_relation_hash) do
|
||||
if Feature.enabled?(:permitted_attributes_for_import_export, default_enabled: :yaml) && attributes_permitter.permitted_attributes_defined?(@relation_sym)
|
||||
if use_attributes_permitter? && attributes_permitter.permitted_attributes_defined?(@relation_sym)
|
||||
attributes_permitter.permit(@relation_sym, @relation_hash)
|
||||
else
|
||||
Gitlab::ImportExport::AttributeCleaner.clean(relation_hash: @relation_hash, relation_class: relation_class)
|
||||
|
|
@ -195,6 +195,10 @@ module Gitlab
|
|||
@attributes_permitter ||= Gitlab::ImportExport::AttributesPermitter.new
|
||||
end
|
||||
|
||||
def use_attributes_permitter?
|
||||
Feature.enabled?(:permitted_attributes_for_import_export, default_enabled: :yaml)
|
||||
end
|
||||
|
||||
def existing_or_new_object
|
||||
# Only find existing records to avoid mapping tables such as milestones
|
||||
# Otherwise always create the record, skipping the extra SELECT clause.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ tree:
|
|||
- labels:
|
||||
- :priorities
|
||||
- boards:
|
||||
- :milestone
|
||||
- lists:
|
||||
- label:
|
||||
- :priorities
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ module Gitlab
|
|||
|
||||
@relation_hash['group_id'] = @importable.id
|
||||
end
|
||||
|
||||
def use_attributes_permitter?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -131,7 +131,6 @@ included_attributes:
|
|||
- :link_url
|
||||
- :name
|
||||
- :project_id
|
||||
- :type
|
||||
- :updated_at
|
||||
pipeline_schedules:
|
||||
- :active
|
||||
|
|
@ -155,6 +154,77 @@ included_attributes:
|
|||
- :enabled
|
||||
- :project_id
|
||||
- :updated_at
|
||||
boards:
|
||||
- :project_id
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :group_id
|
||||
- :weight
|
||||
- :name
|
||||
- :hide_backlog_list
|
||||
- :hide_closed_list
|
||||
lists:
|
||||
- :list_type
|
||||
- :position
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :user_id
|
||||
- :max_issue_count
|
||||
- :max_issue_weight
|
||||
- :limit_metric
|
||||
custom_attributes:
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :project_id
|
||||
- :key
|
||||
- :value
|
||||
label:
|
||||
- :title
|
||||
- :color
|
||||
- :project_id
|
||||
- :group_id
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :template
|
||||
- :description
|
||||
- :priority
|
||||
labels:
|
||||
- :title
|
||||
- :color
|
||||
- :project_id
|
||||
- :group_id
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :template
|
||||
- :description
|
||||
- :priority
|
||||
priorities:
|
||||
- :project_id
|
||||
- :priority
|
||||
- :created_at
|
||||
- :updated_at
|
||||
milestone:
|
||||
- :iid
|
||||
- :title
|
||||
- :project_id
|
||||
- :group_id
|
||||
- :description
|
||||
- :due_date
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :start_date
|
||||
- :state
|
||||
milestones:
|
||||
- :iid
|
||||
- :title
|
||||
- :project_id
|
||||
- :group_id
|
||||
- :description
|
||||
- :due_date
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :start_date
|
||||
- :state
|
||||
|
||||
# Do not include the following attributes for the models specified.
|
||||
excluded_attributes:
|
||||
|
|
@ -498,6 +568,10 @@ ee:
|
|||
- :deploy_access_levels
|
||||
- :security_setting
|
||||
- :push_rule
|
||||
- boards:
|
||||
- :milestone
|
||||
- lists:
|
||||
- :milestone
|
||||
|
||||
included_attributes:
|
||||
issuable_sla:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ module Gitlab
|
|||
@namespace = namespace
|
||||
@plan = namespace&.actual_plan_name
|
||||
@project = project
|
||||
@user = user
|
||||
@extra = extra
|
||||
end
|
||||
|
||||
|
|
@ -35,7 +36,7 @@ module Gitlab
|
|||
|
||||
private
|
||||
|
||||
attr_accessor :namespace, :project, :extra, :plan
|
||||
attr_accessor :namespace, :project, :extra, :plan, :user
|
||||
|
||||
def to_h
|
||||
{
|
||||
|
|
@ -44,6 +45,7 @@ module Gitlab
|
|||
plan: plan,
|
||||
extra: extra
|
||||
}.merge(project_and_namespace)
|
||||
.merge(user_data)
|
||||
end
|
||||
|
||||
def project_and_namespace
|
||||
|
|
@ -58,6 +60,10 @@ module Gitlab
|
|||
def project_id
|
||||
project.is_a?(Integer) ? project : project&.id
|
||||
end
|
||||
|
||||
def user_data
|
||||
::Feature.enabled?(:add_actor_based_user_to_snowplow_tracking, user) ? { user_id: user&.id } : {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -123,17 +123,9 @@ module Gitlab
|
|||
clusters_platforms_eks: count(::Clusters::Cluster.aws_installed.enabled),
|
||||
clusters_platforms_gke: count(::Clusters::Cluster.gcp_installed.enabled),
|
||||
clusters_platforms_user: count(::Clusters::Cluster.user_provided.enabled),
|
||||
clusters_applications_helm: count(::Clusters::Applications::Helm.available),
|
||||
clusters_applications_ingress: count(::Clusters::Applications::Ingress.available),
|
||||
clusters_applications_cert_managers: count(::Clusters::Applications::CertManager.available),
|
||||
clusters_applications_crossplane: count(::Clusters::Applications::Crossplane.available),
|
||||
clusters_applications_prometheus: count(::Clusters::Applications::Prometheus.available),
|
||||
clusters_applications_runner: count(::Clusters::Applications::Runner.available),
|
||||
clusters_applications_knative: count(::Clusters::Applications::Knative.available),
|
||||
clusters_applications_elastic_stack: count(::Clusters::Applications::ElasticStack.available),
|
||||
clusters_applications_jupyter: count(::Clusters::Applications::Jupyter.available),
|
||||
clusters_applications_cilium: count(::Clusters::Applications::Cilium.available),
|
||||
clusters_management_project: count(::Clusters::Cluster.with_management_project),
|
||||
clusters_integrations_elastic_stack: count(::Clusters::Integrations::ElasticStack.enabled),
|
||||
clusters_integrations_prometheus: count(::Clusters::Integrations::Prometheus.enabled),
|
||||
kubernetes_agents: count(::Clusters::Agent),
|
||||
kubernetes_agents_with_token: distinct_count(::Clusters::AgentToken, :agent_id),
|
||||
in_review_folder: count(::Environment.in_review_folder),
|
||||
|
|
@ -523,10 +515,6 @@ module Gitlab
|
|||
# rubocop: disable UsageData/LargeTable
|
||||
def usage_activity_by_stage_configure(time_period)
|
||||
{
|
||||
clusters_applications_cert_managers: cluster_applications_user_distinct_count(::Clusters::Applications::CertManager, time_period),
|
||||
clusters_applications_helm: cluster_applications_user_distinct_count(::Clusters::Applications::Helm, time_period),
|
||||
clusters_applications_ingress: cluster_applications_user_distinct_count(::Clusters::Applications::Ingress, time_period),
|
||||
clusters_applications_knative: cluster_applications_user_distinct_count(::Clusters::Applications::Knative, time_period),
|
||||
clusters_management_project: clusters_user_distinct_count(::Clusters::Cluster.with_management_project, time_period),
|
||||
clusters_disabled: clusters_user_distinct_count(::Clusters::Cluster.disabled, time_period),
|
||||
clusters_enabled: clusters_user_distinct_count(::Clusters::Cluster.enabled, time_period),
|
||||
|
|
@ -621,7 +609,7 @@ module Gitlab
|
|||
|
||||
{
|
||||
clusters: distinct_count(::Clusters::Cluster.where(time_period), :user_id),
|
||||
clusters_applications_prometheus: cluster_applications_user_distinct_count(::Clusters::Applications::Prometheus, time_period),
|
||||
clusters_integrations_prometheus: cluster_integrations_user_distinct_count(::Clusters::Integrations::Prometheus, time_period),
|
||||
operations_dashboard_default_dashboard: count(::User.active.with_dashboard('operations').where(time_period),
|
||||
start: minimum_id(User),
|
||||
finish: maximum_id(User)),
|
||||
|
|
@ -687,8 +675,7 @@ module Gitlab
|
|||
ci_pipeline_config_repository: distinct_count(::Ci::Pipeline.repository_source.where(time_period), :user_id, start: minimum_id(User), finish: maximum_id(User)),
|
||||
ci_pipeline_schedules: distinct_count(::Ci::PipelineSchedule.where(time_period), :owner_id),
|
||||
ci_pipelines: distinct_count(::Ci::Pipeline.where(time_period), :user_id, start: minimum_id(User), finish: maximum_id(User)),
|
||||
ci_triggers: distinct_count(::Ci::Trigger.where(time_period), :owner_id),
|
||||
clusters_applications_runner: cluster_applications_user_distinct_count(::Clusters::Applications::Runner, time_period)
|
||||
ci_triggers: distinct_count(::Ci::Trigger.where(time_period), :owner_id)
|
||||
}
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
|
@ -873,8 +860,8 @@ module Gitlab
|
|||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def cluster_applications_user_distinct_count(applications, time_period)
|
||||
distinct_count(applications.where(time_period).available.joins(:cluster), 'clusters.user_id')
|
||||
def cluster_integrations_user_distinct_count(integrations, time_period)
|
||||
distinct_count(integrations.where(time_period).enabled.joins(:cluster), 'clusters.user_id')
|
||||
end
|
||||
|
||||
def clusters_user_distinct_count(clusters, time_period)
|
||||
|
|
|
|||
|
|
@ -1055,6 +1055,9 @@ msgstr ""
|
|||
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook."
|
||||
msgstr ""
|
||||
|
||||
msgid "%{widget} options"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_start}v*%{code_tag_end} or %{code_tag_start}*-release%{code_tag_end} are supported."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -5965,9 +5968,6 @@ msgstr ""
|
|||
msgid "CI configuration validated, including all configuration added with the %{codeStart}includes%{codeEnd} keyword. %{link}"
|
||||
msgstr ""
|
||||
|
||||
msgid "CI minutes"
|
||||
msgstr ""
|
||||
|
||||
msgid "CI settings"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6637,6 +6637,9 @@ msgstr ""
|
|||
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|CI minutes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|Checkout"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6784,6 +6787,9 @@ msgstr ""
|
|||
msgid "Checkout|minutes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|x %{quantity} %{units} per pack"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|x %{quantity} %{units} per pack ="
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ module QA
|
|||
def with_retry_on_too_many_requests
|
||||
response = nil
|
||||
|
||||
Support::Retrier.retry_until do
|
||||
Support::Retrier.retry_until(log: false) do
|
||||
response = yield
|
||||
|
||||
if response.code == HTTP_STATUS_TOO_MANY_REQUESTS
|
||||
|
|
|
|||
|
|
@ -34,15 +34,29 @@ module QA
|
|||
result
|
||||
end
|
||||
|
||||
def retry_until(max_attempts: nil, max_duration: nil, reload_page: nil, sleep_interval: 0, raise_on_failure: true, retry_on_exception: false, log: true)
|
||||
def retry_until(
|
||||
max_attempts: nil,
|
||||
max_duration: nil,
|
||||
reload_page: nil,
|
||||
sleep_interval: 0,
|
||||
raise_on_failure: true,
|
||||
retry_on_exception: false,
|
||||
log: true
|
||||
)
|
||||
# For backwards-compatibility
|
||||
max_attempts = 3 if max_attempts.nil? && max_duration.nil?
|
||||
|
||||
if log
|
||||
start_msg ||= ["with retry_until:"]
|
||||
start_msg = ["with retry_until:"]
|
||||
start_msg << "max_attempts: #{max_attempts};" if max_attempts
|
||||
start_msg << "max_duration: #{max_duration};" if max_duration
|
||||
start_msg << "reload_page: #{reload_page}; sleep_interval: #{sleep_interval}; raise_on_failure: #{raise_on_failure}; retry_on_exception: #{retry_on_exception}"
|
||||
start_msg.push(*[
|
||||
"reload_page: #{reload_page};",
|
||||
"sleep_interval: #{sleep_interval};",
|
||||
"raise_on_failure: #{raise_on_failure};",
|
||||
"retry_on_exception: #{retry_on_exception}"
|
||||
])
|
||||
|
||||
QA::Runtime::Logger.debug(start_msg.join(' '))
|
||||
end
|
||||
|
||||
|
|
@ -58,7 +72,7 @@ module QA
|
|||
) do
|
||||
result = yield
|
||||
end
|
||||
QA::Runtime::Logger.debug("ended retry_until")
|
||||
QA::Runtime::Logger.debug("ended retry_until") if log
|
||||
|
||||
result
|
||||
end
|
||||
|
|
|
|||
|
|
@ -88,17 +88,9 @@ FactoryBot.define do
|
|||
create(:cluster, :group, :disabled)
|
||||
create(:cluster, :instance, :disabled)
|
||||
|
||||
# Applications
|
||||
create(:clusters_applications_helm, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_ingress, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_cert_manager, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_crossplane, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_runner, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_knative, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_elastic_stack, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_jupyter, :installed, cluster: gcp_cluster)
|
||||
create(:clusters_applications_cilium, :installed, cluster: gcp_cluster)
|
||||
# Cluster Integrations
|
||||
create(:clusters_integrations_prometheus, cluster: gcp_cluster)
|
||||
create(:clusters_integrations_elastic_stack, cluster: gcp_cluster)
|
||||
|
||||
create(:grafana_integration, project: projects[0], enabled: true)
|
||||
create(:grafana_integration, project: projects[1], enabled: true)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
let(:actor) { developer_in_both }
|
||||
|
||||
it 'returns all pipelines' do
|
||||
is_expected.to eq([pipeline_in_fork, pipeline_in_parent])
|
||||
is_expected.to match_array([pipeline_in_fork, pipeline_in_parent])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
let(:actor) { reporter_in_parent_and_developer_in_fork }
|
||||
|
||||
it 'returns all pipelines' do
|
||||
is_expected.to eq([pipeline_in_fork, pipeline_in_parent])
|
||||
is_expected.to match_array([pipeline_in_fork, pipeline_in_parent])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
let(:actor) { developer_in_parent }
|
||||
|
||||
it 'returns pipelines in parent' do
|
||||
is_expected.to eq([pipeline_in_parent])
|
||||
is_expected.to match_array([pipeline_in_parent])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
let(:actor) { developer_in_fork }
|
||||
|
||||
it 'returns pipelines in fork' do
|
||||
is_expected.to eq([pipeline_in_fork])
|
||||
is_expected.to match_array([pipeline_in_fork])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
|
||||
shared_examples 'returning pipelines with proper ordering' do
|
||||
let!(:all_pipelines) do
|
||||
merge_request.all_commit_shas.map do |sha|
|
||||
merge_request.recent_diff_head_shas.map do |sha|
|
||||
create(:ci_empty_pipeline,
|
||||
project: project, sha: sha, ref: merge_request.source_branch)
|
||||
end
|
||||
|
|
@ -135,12 +135,92 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
end
|
||||
|
||||
context 'when pipelines exist for the branch and merge request' do
|
||||
shared_examples 'returns all pipelines for merge request' do
|
||||
it 'returns merge request pipeline first' do
|
||||
expect(subject.all).to eq([detached_merge_request_pipeline, branch_pipeline])
|
||||
end
|
||||
|
||||
context 'when there are a branch pipeline and a merge request pipeline' do
|
||||
let!(:branch_pipeline_2) do
|
||||
create(:ci_pipeline, source: :push, project: project,
|
||||
ref: source_ref, sha: shas.first)
|
||||
end
|
||||
|
||||
let!(:detached_merge_request_pipeline_2) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: source_ref, sha: shas.first, merge_request: merge_request)
|
||||
end
|
||||
|
||||
it 'returns merge request pipelines first' do
|
||||
expect(subject.all)
|
||||
.to eq([detached_merge_request_pipeline_2,
|
||||
detached_merge_request_pipeline,
|
||||
branch_pipeline_2,
|
||||
branch_pipeline])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are multiple merge request pipelines from the same branch' do
|
||||
let!(:branch_pipeline_2) do
|
||||
create(:ci_pipeline, source: :push, project: project,
|
||||
ref: source_ref, sha: shas.first)
|
||||
end
|
||||
|
||||
let!(:branch_pipeline_with_sha_not_belonging_to_merge_request) do
|
||||
create(:ci_pipeline, source: :push, project: project, ref: source_ref)
|
||||
end
|
||||
|
||||
let!(:detached_merge_request_pipeline_2) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: source_ref, sha: shas.first, merge_request: merge_request_2)
|
||||
end
|
||||
|
||||
let(:merge_request_2) do
|
||||
create(:merge_request, source_project: project, source_branch: source_ref,
|
||||
target_project: project, target_branch: 'stable')
|
||||
end
|
||||
|
||||
before do
|
||||
shas.each.with_index do |sha, index|
|
||||
create(:merge_request_diff_commit,
|
||||
merge_request_diff: merge_request_2.merge_request_diff,
|
||||
sha: sha, relative_order: index)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns only related merge request pipelines' do
|
||||
expect(subject.all)
|
||||
.to eq([detached_merge_request_pipeline,
|
||||
branch_pipeline_2,
|
||||
branch_pipeline])
|
||||
|
||||
expect(described_class.new(merge_request_2, nil).all)
|
||||
.to match_array([detached_merge_request_pipeline_2, branch_pipeline_2, branch_pipeline])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when detached merge request pipeline is run on head ref of the merge request' do
|
||||
let!(:detached_merge_request_pipeline) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: merge_request.ref_path, sha: shas.second, merge_request: merge_request)
|
||||
end
|
||||
|
||||
it 'sets the head ref of the merge request to the pipeline ref' do
|
||||
expect(detached_merge_request_pipeline.ref).to match(%r{refs/merge-requests/\d+/head})
|
||||
end
|
||||
|
||||
it 'includes the detached merge request pipeline even though the ref is custom path' do
|
||||
expect(merge_request.all_pipelines).to include(detached_merge_request_pipeline)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:source_ref) { 'feature' }
|
||||
let(:target_ref) { 'master' }
|
||||
|
||||
let!(:branch_pipeline) do
|
||||
create(:ci_pipeline, source: :push, project: project,
|
||||
ref: source_ref, sha: shas.second)
|
||||
ref: source_ref, sha: merge_request.merge_request_diff.head_commit_sha)
|
||||
end
|
||||
|
||||
let!(:tag_pipeline) do
|
||||
|
|
@ -149,97 +229,31 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
|
|||
|
||||
let!(:detached_merge_request_pipeline) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: source_ref, sha: shas.second, merge_request: merge_request)
|
||||
ref: source_ref, sha: shas.second, merge_request: merge_request)
|
||||
end
|
||||
|
||||
let(:merge_request) do
|
||||
create(:merge_request, source_project: project, source_branch: source_ref,
|
||||
target_project: project, target_branch: target_ref)
|
||||
target_project: project, target_branch: target_ref)
|
||||
end
|
||||
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:shas) { project.repository.commits(source_ref, limit: 2).map(&:id) }
|
||||
|
||||
before do
|
||||
create(:merge_request_diff_commit,
|
||||
merge_request_diff: merge_request.merge_request_diff,
|
||||
sha: shas.second, relative_order: 1)
|
||||
end
|
||||
|
||||
it 'returns merge request pipeline first' do
|
||||
expect(subject.all).to eq([detached_merge_request_pipeline, branch_pipeline])
|
||||
end
|
||||
|
||||
context 'when there are a branch pipeline and a merge request pipeline' do
|
||||
let!(:branch_pipeline_2) do
|
||||
create(:ci_pipeline, source: :push, project: project,
|
||||
ref: source_ref, sha: shas.first)
|
||||
end
|
||||
|
||||
let!(:detached_merge_request_pipeline_2) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: source_ref, sha: shas.first, merge_request: merge_request)
|
||||
end
|
||||
|
||||
it 'returns merge request pipelines first' do
|
||||
expect(subject.all)
|
||||
.to eq([detached_merge_request_pipeline_2,
|
||||
detached_merge_request_pipeline,
|
||||
branch_pipeline_2,
|
||||
branch_pipeline])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are multiple merge request pipelines from the same branch' do
|
||||
let!(:branch_pipeline_2) do
|
||||
create(:ci_pipeline, source: :push, project: project,
|
||||
ref: source_ref, sha: shas.first)
|
||||
end
|
||||
|
||||
let!(:detached_merge_request_pipeline_2) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: source_ref, sha: shas.first, merge_request: merge_request_2)
|
||||
end
|
||||
|
||||
let(:merge_request_2) do
|
||||
create(:merge_request, source_project: project, source_branch: source_ref,
|
||||
target_project: project, target_branch: 'stable')
|
||||
end
|
||||
|
||||
context 'when `decomposed_ci_query_in_pipelines_for_merge_request_finder` feature flag enabled' do
|
||||
before do
|
||||
shas.each.with_index do |sha, index|
|
||||
create(:merge_request_diff_commit,
|
||||
merge_request_diff: merge_request_2.merge_request_diff,
|
||||
sha: sha, relative_order: index)
|
||||
end
|
||||
stub_feature_flags(decomposed_ci_query_in_pipelines_for_merge_request_finder: merge_request.target_project)
|
||||
end
|
||||
|
||||
it 'returns only related merge request pipelines' do
|
||||
expect(subject.all)
|
||||
.to eq([detached_merge_request_pipeline,
|
||||
branch_pipeline_2,
|
||||
branch_pipeline])
|
||||
|
||||
expect(described_class.new(merge_request_2, nil).all)
|
||||
.to eq([detached_merge_request_pipeline_2,
|
||||
branch_pipeline_2,
|
||||
branch_pipeline])
|
||||
end
|
||||
it_behaves_like 'returns all pipelines for merge request'
|
||||
end
|
||||
|
||||
context 'when detached merge request pipeline is run on head ref of the merge request' do
|
||||
let!(:detached_merge_request_pipeline) do
|
||||
create(:ci_pipeline, source: :merge_request_event, project: project,
|
||||
ref: merge_request.ref_path, sha: shas.second, merge_request: merge_request)
|
||||
context 'when `decomposed_ci_query_in_pipelines_for_merge_request_finder` feature flag disabled' do
|
||||
before do
|
||||
stub_feature_flags(decomposed_ci_query_in_pipelines_for_merge_request_finder: false)
|
||||
end
|
||||
|
||||
it 'sets the head ref of the merge request to the pipeline ref' do
|
||||
expect(detached_merge_request_pipeline.ref).to match(%r{refs/merge-requests/\d+/head})
|
||||
end
|
||||
|
||||
it 'includes the detached merge request pipeline even though the ref is custom path' do
|
||||
expect(merge_request.all_pipelines).to include(detached_merge_request_pipeline)
|
||||
end
|
||||
it_behaves_like 'returns all pipelines for merge request'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7759,7 +7759,29 @@
|
|||
"created_at": "2019-06-06T14:01:06.204Z",
|
||||
"updated_at": "2019-06-06T14:22:37.045Z",
|
||||
"name": "TestBoardABC",
|
||||
"milestone_id": null,
|
||||
"milestone": {
|
||||
"id": 1,
|
||||
"title": "test milestone",
|
||||
"project_id": 8,
|
||||
"description": "test milestone",
|
||||
"due_date": null,
|
||||
"created_at": "2016-06-14T15:02:04.415Z",
|
||||
"updated_at": "2016-06-14T15:02:04.415Z",
|
||||
"state": "active",
|
||||
"iid": 1,
|
||||
"events": [
|
||||
{
|
||||
"id": 487,
|
||||
"target_type": "Milestone",
|
||||
"target_id": 1,
|
||||
"project_id": 46,
|
||||
"created_at": "2016-06-14T15:02:04.418Z",
|
||||
"updated_at": "2016-06-14T15:02:04.418Z",
|
||||
"action": 1,
|
||||
"author_id": 18
|
||||
}
|
||||
]
|
||||
},
|
||||
"group_id": null,
|
||||
"weight": null,
|
||||
"lists": [
|
||||
|
|
@ -7772,7 +7794,29 @@
|
|||
"created_at": "2019-06-06T14:01:06.214Z",
|
||||
"updated_at": "2019-06-06T14:01:06.214Z",
|
||||
"user_id": null,
|
||||
"milestone_id": null
|
||||
"milestone": {
|
||||
"id": 1,
|
||||
"title": "test milestone",
|
||||
"project_id": 8,
|
||||
"description": "test milestone",
|
||||
"due_date": null,
|
||||
"created_at": "2016-06-14T15:02:04.415Z",
|
||||
"updated_at": "2016-06-14T15:02:04.415Z",
|
||||
"state": "active",
|
||||
"iid": 1,
|
||||
"events": [
|
||||
{
|
||||
"id": 487,
|
||||
"target_type": "Milestone",
|
||||
"target_id": 1,
|
||||
"project_id": 46,
|
||||
"created_at": "2016-06-14T15:02:04.418Z",
|
||||
"updated_at": "2016-06-14T15:02:04.418Z",
|
||||
"action": 1,
|
||||
"author_id": 18
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 61,
|
||||
|
|
@ -7783,7 +7827,29 @@
|
|||
"created_at": "2019-06-06T14:01:43.197Z",
|
||||
"updated_at": "2019-06-06T14:01:43.197Z",
|
||||
"user_id": null,
|
||||
"milestone_id": null,
|
||||
"milestone": {
|
||||
"id": 1,
|
||||
"title": "test milestone",
|
||||
"project_id": 8,
|
||||
"description": "test milestone",
|
||||
"due_date": null,
|
||||
"created_at": "2016-06-14T15:02:04.415Z",
|
||||
"updated_at": "2016-06-14T15:02:04.415Z",
|
||||
"state": "active",
|
||||
"iid": 1,
|
||||
"events": [
|
||||
{
|
||||
"id": 487,
|
||||
"target_type": "Milestone",
|
||||
"target_id": 1,
|
||||
"project_id": 46,
|
||||
"created_at": "2016-06-14T15:02:04.418Z",
|
||||
"updated_at": "2016-06-14T15:02:04.418Z",
|
||||
"action": 1,
|
||||
"author_id": 18
|
||||
}
|
||||
]
|
||||
},
|
||||
"label": {
|
||||
"id": 20,
|
||||
"title": "testlabel",
|
||||
|
|
@ -7807,7 +7873,29 @@
|
|||
"created_at": "2019-06-06T14:01:06.221Z",
|
||||
"updated_at": "2019-06-06T14:01:06.221Z",
|
||||
"user_id": null,
|
||||
"milestone_id": null
|
||||
"milestone": {
|
||||
"id": 1,
|
||||
"title": "test milestone",
|
||||
"project_id": 8,
|
||||
"description": "test milestone",
|
||||
"due_date": null,
|
||||
"created_at": "2016-06-14T15:02:04.415Z",
|
||||
"updated_at": "2016-06-14T15:02:04.415Z",
|
||||
"state": "active",
|
||||
"iid": 1,
|
||||
"events": [
|
||||
{
|
||||
"id": 487,
|
||||
"target_type": "Milestone",
|
||||
"target_id": 1,
|
||||
"project_id": 46,
|
||||
"created_at": "2016-06-14T15:02:04.418Z",
|
||||
"updated_at": "2016-06-14T15:02:04.418Z",
|
||||
"action": 1,
|
||||
"author_id": 18
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"id":29,"project_id":49,"created_at":"2019-06-06T14:01:06.204Z","updated_at":"2019-06-06T14:22:37.045Z","name":"TestBoardABC","milestone_id":null,"group_id":null,"weight":null,"lists":[{"id":59,"board_id":29,"label_id":null,"list_type":"backlog","position":null,"created_at":"2019-06-06T14:01:06.214Z","updated_at":"2019-06-06T14:01:06.214Z","user_id":null,"milestone_id":null},{"id":61,"board_id":29,"label_id":20,"list_type":"label","position":0,"created_at":"2019-06-06T14:01:43.197Z","updated_at":"2019-06-06T14:01:43.197Z","user_id":null,"milestone_id":null,"label":{"id":20,"title":"testlabel","color":"#0033CC","project_id":49,"created_at":"2019-06-06T14:01:19.698Z","updated_at":"2019-06-06T14:01:19.698Z","template":false,"description":null,"group_id":null,"type":"ProjectLabel","priorities":[]}},{"id":60,"board_id":29,"label_id":null,"list_type":"closed","position":null,"created_at":"2019-06-06T14:01:06.221Z","updated_at":"2019-06-06T14:01:06.221Z","user_id":null,"milestone_id":null}]}
|
||||
{"id":29,"project_id":49,"created_at":"2019-06-06T14:01:06.204Z","updated_at":"2019-06-06T14:22:37.045Z","name":"TestBoardABC","group_id":null,"weight":null,"milestone":{"id":1,"title":"test milestone","project_id":8,"description":"test milestone","due_date":null,"created_at":"2016-06-14T15:02:04.415Z","updated_at":"2016-06-14T15:02:04.415Z","state":"active","iid":1,"events":[{"id":487,"target_type":"Milestone","target_id":1,"project_id":46,"created_at":"2016-06-14T15:02:04.418Z","updated_at":"2016-06-14T15:02:04.418Z","action":1,"author_id":18}]},"lists":[{"id":59,"board_id":29,"label_id":null,"list_type":"backlog","position":null,"created_at":"2019-06-06T14:01:06.214Z","updated_at":"2019-06-06T14:01:06.214Z","user_id":null,"milestone":{"id":1,"title":"test milestone","project_id":8,"description":"test milestone","due_date":null,"created_at":"2016-06-14T15:02:04.415Z","updated_at":"2016-06-14T15:02:04.415Z","state":"active","iid":1,"events":[{"id":487,"target_type":"Milestone","target_id":1,"project_id":46,"created_at":"2016-06-14T15:02:04.418Z","updated_at":"2016-06-14T15:02:04.418Z","action":1,"author_id":18}]}},{"id":61,"board_id":29,"label_id":20,"list_type":"label","position":0,"created_at":"2019-06-06T14:01:43.197Z","updated_at":"2019-06-06T14:01:43.197Z","user_id":null,"milestone":{"id":1,"title":"test milestone","project_id":8,"description":"test milestone","due_date":null,"created_at":"2016-06-14T15:02:04.415Z","updated_at":"2016-06-14T15:02:04.415Z","state":"active","iid":1,"events":[{"id":487,"target_type":"Milestone","target_id":1,"project_id":46,"created_at":"2016-06-14T15:02:04.418Z","updated_at":"2016-06-14T15:02:04.418Z","action":1,"author_id":18}]},"label":{"id":20,"title":"testlabel","color":"#0033CC","project_id":49,"created_at":"2019-06-06T14:01:19.698Z","updated_at":"2019-06-06T14:01:19.698Z","template":false,"description":null,"group_id":null,"type":"ProjectLabel","priorities":[]}},{"id":60,"board_id":29,"label_id":null,"list_type":"closed","position":null,"created_at":"2019-06-06T14:01:06.221Z","updated_at":"2019-06-06T14:01:06.221Z","user_id":null,"milestone":{"id":1,"title":"test milestone","project_id":8,"description":"test milestone","due_date":null,"created_at":"2016-06-14T15:02:04.415Z","updated_at":"2016-06-14T15:02:04.415Z","state":"active","iid":1,"events":[{"id":487,"target_type":"Milestone","target_id":1,"project_id":46,"created_at":"2016-06-14T15:02:04.418Z","updated_at":"2016-06-14T15:02:04.418Z","action":1,"author_id":18}]}}]}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
import { GlButton, GlDropdownItem } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import Actions from '~/vue_merge_request_widget/components/extensions/actions.vue';
|
||||
|
||||
let wrapper;
|
||||
|
||||
function factory(propsData = {}) {
|
||||
wrapper = shallowMount(Actions, {
|
||||
propsData: { ...propsData, widget: 'test' },
|
||||
});
|
||||
}
|
||||
|
||||
describe('MR widget extension actions', () => {
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('tertiaryButtons', () => {
|
||||
it('renders buttons', () => {
|
||||
factory({
|
||||
tertiaryButtons: [{ text: 'hello world', href: 'https://gitlab.com', target: '_blank' }],
|
||||
});
|
||||
|
||||
expect(wrapper.findAllComponents(GlButton)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders tertiary actions in dropdown', () => {
|
||||
factory({
|
||||
tertiaryButtons: [{ text: 'hello world', href: 'https://gitlab.com', target: '_blank' }],
|
||||
});
|
||||
|
||||
expect(wrapper.findAllComponents(GlDropdownItem)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -83,14 +83,15 @@ RSpec.describe Gitlab::ImportExport::AttributesPermitter do
|
|||
where(:relation_name, :permitted_attributes_defined) do
|
||||
:user | false
|
||||
:author | false
|
||||
:ci_cd_settings | false
|
||||
:issuable_sla | false
|
||||
:push_rule | false
|
||||
:ci_cd_settings | true
|
||||
:metrics_setting | true
|
||||
:project_badges | true
|
||||
:pipeline_schedules | true
|
||||
:error_tracking_setting | true
|
||||
:auto_devops | true
|
||||
:boards | true
|
||||
:custom_attributes | true
|
||||
:labels | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
|
@ -99,47 +100,11 @@ RSpec.describe Gitlab::ImportExport::AttributesPermitter do
|
|||
end
|
||||
|
||||
describe 'included_attributes for Project' do
|
||||
let(:prohibited_attributes) { %i[remote_url my_attributes my_ids token my_id test] }
|
||||
|
||||
subject { described_class.new }
|
||||
|
||||
Gitlab::ImportExport::Config.new.to_h[:included_attributes].each do |relation_sym, permitted_attributes|
|
||||
context "for #{relation_sym}" do
|
||||
let(:import_export_config) { Gitlab::ImportExport::Config.new.to_h }
|
||||
let(:project_relation_factory) { Gitlab::ImportExport::Project::RelationFactory }
|
||||
|
||||
let(:relation_hash) { (permitted_attributes + prohibited_attributes).map(&:to_s).zip([]).to_h }
|
||||
let(:relation_name) { project_relation_factory.overrides[relation_sym]&.to_sym || relation_sym }
|
||||
let(:relation_class) { project_relation_factory.relation_class(relation_name) }
|
||||
let(:excluded_keys) { import_export_config.dig(:excluded_keys, relation_sym) || [] }
|
||||
|
||||
let(:cleaned_hash) do
|
||||
Gitlab::ImportExport::AttributeCleaner.new(
|
||||
relation_hash: relation_hash,
|
||||
relation_class: relation_class,
|
||||
excluded_keys: excluded_keys
|
||||
).clean
|
||||
end
|
||||
|
||||
let(:permitted_hash) { subject.permit(relation_sym, relation_hash) }
|
||||
|
||||
if described_class.new.permitted_attributes_defined?(relation_sym)
|
||||
it 'contains only attributes that are defined as permitted in the import/export config' do
|
||||
expect(permitted_hash.keys).to contain_exactly(*permitted_attributes.map(&:to_s))
|
||||
end
|
||||
|
||||
it 'does not contain attributes that would be cleaned with AttributeCleaner' do
|
||||
expect(cleaned_hash.keys).to include(*permitted_hash.keys)
|
||||
end
|
||||
|
||||
it 'does not contain prohibited attributes that are not related to given relation' do
|
||||
expect(permitted_hash.keys).not_to include(*prohibited_attributes.map(&:to_s))
|
||||
end
|
||||
else
|
||||
it 'is disabled' do
|
||||
expect(subject).not_to be_permitted_attributes_defined(relation_sym)
|
||||
end
|
||||
end
|
||||
it_behaves_like 'a permitted attribute', relation_sym, permitted_attributes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::Tracking::StandardContext do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:namespace) { create(:namespace) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
let(:snowplow_context) { subject.to_context }
|
||||
|
||||
|
|
@ -87,8 +88,8 @@ RSpec.describe Gitlab::Tracking::StandardContext do
|
|||
end
|
||||
end
|
||||
|
||||
it 'does not contain user id' do
|
||||
expect(snowplow_context.to_json[:data].keys).not_to include(:user_id)
|
||||
it 'contains user id' do
|
||||
expect(snowplow_context.to_json[:data].keys).to include(:user_id)
|
||||
end
|
||||
|
||||
it 'contains namespace and project ids' do
|
||||
|
|
@ -104,8 +105,18 @@ RSpec.describe Gitlab::Tracking::StandardContext do
|
|||
stub_feature_flags(add_namespace_and_project_to_snowplow_tracking: false)
|
||||
end
|
||||
|
||||
it 'does not contain any ids' do
|
||||
expect(snowplow_context.to_json[:data].keys).not_to include(:user_id, :project_id, :namespace_id)
|
||||
it 'does not contain project or namespace ids' do
|
||||
expect(snowplow_context.to_json[:data].keys).not_to include(:project_id, :namespace_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without add_actor_based_user_to_snowplow_tracking feature' do
|
||||
before do
|
||||
stub_feature_flags(add_actor_based_user_to_snowplow_tracking: false)
|
||||
end
|
||||
|
||||
it 'does not contain user_id' do
|
||||
expect(snowplow_context.to_json[:data].keys).not_to include(:user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ RSpec.describe Gitlab::Tracking do
|
|||
other_context = double(:context)
|
||||
|
||||
project = build_stubbed(:project)
|
||||
user = double(:user)
|
||||
user = build_stubbed(:user)
|
||||
|
||||
expect(Gitlab::Tracking::StandardContext)
|
||||
.to receive(:new)
|
||||
|
|
|
|||
|
|
@ -101,11 +101,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
it 'includes accurate usage_activity_by_stage data' do
|
||||
for_defined_days_back do
|
||||
user = create(:user)
|
||||
cluster = create(:cluster, user: user)
|
||||
create(:clusters_applications_cert_manager, :installed, cluster: cluster)
|
||||
create(:clusters_applications_helm, :installed, cluster: cluster)
|
||||
create(:clusters_applications_ingress, :installed, cluster: cluster)
|
||||
create(:clusters_applications_knative, :installed, cluster: cluster)
|
||||
create(:cluster, user: user)
|
||||
create(:cluster, :disabled, user: user)
|
||||
create(:cluster_provider_gcp, :created)
|
||||
create(:cluster_provider_aws, :created)
|
||||
|
|
@ -118,10 +114,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
end
|
||||
|
||||
expect(described_class.usage_activity_by_stage_configure({})).to include(
|
||||
clusters_applications_cert_managers: 2,
|
||||
clusters_applications_helm: 2,
|
||||
clusters_applications_ingress: 2,
|
||||
clusters_applications_knative: 2,
|
||||
clusters_management_project: 2,
|
||||
clusters_disabled: 4,
|
||||
clusters_enabled: 12,
|
||||
|
|
@ -136,10 +128,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
project_clusters_enabled: 10
|
||||
)
|
||||
expect(described_class.usage_activity_by_stage_configure(described_class.monthly_time_range_db_params)).to include(
|
||||
clusters_applications_cert_managers: 1,
|
||||
clusters_applications_helm: 1,
|
||||
clusters_applications_ingress: 1,
|
||||
clusters_applications_knative: 1,
|
||||
clusters_management_project: 1,
|
||||
clusters_disabled: 2,
|
||||
clusters_enabled: 6,
|
||||
|
|
@ -392,7 +380,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
user = create(:user, dashboard: 'operations')
|
||||
cluster = create(:cluster, user: user)
|
||||
project = create(:project, creator: user)
|
||||
create(:clusters_applications_prometheus, :installed, cluster: cluster)
|
||||
create(:clusters_integrations_prometheus, cluster: cluster)
|
||||
create(:project_tracing_setting)
|
||||
create(:project_error_tracking_setting)
|
||||
create(:incident)
|
||||
|
|
@ -402,7 +390,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
|
||||
expect(described_class.usage_activity_by_stage_monitor({})).to include(
|
||||
clusters: 2,
|
||||
clusters_applications_prometheus: 2,
|
||||
clusters_integrations_prometheus: 2,
|
||||
operations_dashboard_default_dashboard: 2,
|
||||
projects_with_tracing_enabled: 2,
|
||||
projects_with_error_tracking_enabled: 2,
|
||||
|
|
@ -414,7 +402,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
data_28_days = described_class.usage_activity_by_stage_monitor(described_class.monthly_time_range_db_params)
|
||||
expect(data_28_days).to include(
|
||||
clusters: 1,
|
||||
clusters_applications_prometheus: 1,
|
||||
clusters_integrations_prometheus: 1,
|
||||
operations_dashboard_default_dashboard: 1,
|
||||
projects_with_tracing_enabled: 1,
|
||||
projects_with_error_tracking_enabled: 1,
|
||||
|
|
@ -502,7 +490,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
create(:ci_pipeline, :repository_source, user: user)
|
||||
create(:ci_pipeline_schedule, owner: user)
|
||||
create(:ci_trigger, owner: user)
|
||||
create(:clusters_applications_runner, :installed)
|
||||
end
|
||||
|
||||
expect(described_class.usage_activity_by_stage_verify({})).to include(
|
||||
|
|
@ -513,8 +500,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
ci_pipeline_config_repository: 2,
|
||||
ci_pipeline_schedules: 2,
|
||||
ci_pipelines: 2,
|
||||
ci_triggers: 2,
|
||||
clusters_applications_runner: 2
|
||||
ci_triggers: 2
|
||||
)
|
||||
expect(described_class.usage_activity_by_stage_verify(described_class.monthly_time_range_db_params)).to include(
|
||||
ci_builds: 1,
|
||||
|
|
@ -524,8 +510,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
ci_pipeline_config_repository: 1,
|
||||
ci_pipeline_schedules: 1,
|
||||
ci_pipelines: 1,
|
||||
ci_triggers: 1,
|
||||
clusters_applications_runner: 1
|
||||
ci_triggers: 1
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -607,17 +592,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
expect(count_data[:clusters_platforms_eks]).to eq(1)
|
||||
expect(count_data[:clusters_platforms_gke]).to eq(1)
|
||||
expect(count_data[:clusters_platforms_user]).to eq(1)
|
||||
expect(count_data[:clusters_applications_helm]).to eq(1)
|
||||
expect(count_data[:clusters_applications_ingress]).to eq(1)
|
||||
expect(count_data[:clusters_applications_cert_managers]).to eq(1)
|
||||
expect(count_data[:clusters_applications_crossplane]).to eq(1)
|
||||
expect(count_data[:clusters_applications_prometheus]).to eq(1)
|
||||
expect(count_data[:clusters_applications_runner]).to eq(1)
|
||||
expect(count_data[:clusters_applications_knative]).to eq(1)
|
||||
expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
|
||||
expect(count_data[:clusters_integrations_elastic_stack]).to eq(1)
|
||||
expect(count_data[:clusters_integrations_prometheus]).to eq(1)
|
||||
expect(count_data[:grafana_integrated_projects]).to eq(2)
|
||||
expect(count_data[:clusters_applications_jupyter]).to eq(1)
|
||||
expect(count_data[:clusters_applications_cilium]).to eq(1)
|
||||
expect(count_data[:clusters_management_project]).to eq(1)
|
||||
expect(count_data[:kubernetes_agents]).to eq(2)
|
||||
expect(count_data[:kubernetes_agents_with_token]).to eq(1)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ RSpec.describe 'Query.project.mergeRequests.pipelines' do
|
|||
|
||||
before do
|
||||
merge_requests.each do |mr|
|
||||
shas = mr.all_commits.limit(2).pluck(:sha)
|
||||
shas = mr.recent_diff_head_shas
|
||||
|
||||
shas.each do |sha|
|
||||
create(:ci_pipeline, :success, project: project, ref: mr.source_branch, sha: sha)
|
||||
|
|
@ -52,7 +52,7 @@ RSpec.describe 'Query.project.mergeRequests.pipelines' do
|
|||
|
||||
p_nodes = graphql_data_at(:project, :merge_requests, :nodes)
|
||||
|
||||
expect(p_nodes).to all(match('iid' => be_present, 'pipelines' => match('count' => 2)))
|
||||
expect(p_nodes).to all(match('iid' => be_present, 'pipelines' => match('count' => 1)))
|
||||
end
|
||||
|
||||
it 'is scalable', :request_store, :use_clean_rails_memory_store_caching do
|
||||
|
|
|
|||
|
|
@ -798,8 +798,6 @@ RSpec.describe API::MavenPackages do
|
|||
end
|
||||
|
||||
describe 'PUT /api/v4/projects/:id/packages/maven/*path/:file_name' do
|
||||
include_context 'workhorse headers'
|
||||
|
||||
let(:send_rewritten_field) { true }
|
||||
let(:file_upload) { fixture_file_upload('spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jar') }
|
||||
|
||||
|
|
@ -833,6 +831,8 @@ RSpec.describe API::MavenPackages do
|
|||
context 'when params from workhorse are correct' do
|
||||
let(:params) { { file: file_upload } }
|
||||
|
||||
subject { upload_file_with_token(params: params) }
|
||||
|
||||
context 'file size is too large' do
|
||||
it 'rejects the request' do
|
||||
allow_next_instance_of(UploadedFile) do |uploaded_file|
|
||||
|
|
@ -851,18 +851,20 @@ RSpec.describe API::MavenPackages do
|
|||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
|
||||
context 'without workhorse header' do
|
||||
let(:workhorse_headers) { {} }
|
||||
|
||||
subject { upload_file_with_token(params: params) }
|
||||
|
||||
it_behaves_like 'package workhorse uploads'
|
||||
end
|
||||
it_behaves_like 'package workhorse uploads'
|
||||
|
||||
context 'event tracking' do
|
||||
subject { upload_file_with_token(params: params) }
|
||||
|
||||
it_behaves_like 'a package tracking event', described_class.name, 'push_package'
|
||||
|
||||
context 'when the package file fails to be created' do
|
||||
before do
|
||||
allow_next_instance_of(::Packages::CreatePackageFileService) do |create_package_file_service|
|
||||
allow(create_package_file_service).to receive(:execute).and_raise(StandardError)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'not a package tracking event'
|
||||
end
|
||||
end
|
||||
|
||||
it 'creates package and stores package file' do
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
|
|||
expect(json_response['admin_mode']).to be(false)
|
||||
expect(json_response['whats_new_variant']).to eq('all_tiers')
|
||||
expect(json_response['user_deactivation_emails_enabled']).to be(true)
|
||||
expect(json_response['suggest_pipeline_enabled']).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -135,7 +136,8 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
|
|||
wiki_page_max_content_bytes: 12345,
|
||||
personal_access_token_prefix: "GL-",
|
||||
user_deactivation_emails_enabled: false,
|
||||
admin_mode: true
|
||||
admin_mode: true,
|
||||
suggest_pipeline_enabled: false
|
||||
}
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
|
|
@ -187,6 +189,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
|
|||
expect(json_response['personal_access_token_prefix']).to eq("GL-")
|
||||
expect(json_response['admin_mode']).to be(true)
|
||||
expect(json_response['user_deactivation_emails_enabled']).to be(false)
|
||||
expect(json_response['suggest_pipeline_enabled']).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -54,15 +54,8 @@ module UsageDataHelpers
|
|||
clusters_platforms_eks
|
||||
clusters_platforms_gke
|
||||
clusters_platforms_user
|
||||
clusters_applications_helm
|
||||
clusters_applications_ingress
|
||||
clusters_applications_cert_managers
|
||||
clusters_applications_prometheus
|
||||
clusters_applications_crossplane
|
||||
clusters_applications_runner
|
||||
clusters_applications_knative
|
||||
clusters_applications_elastic_stack
|
||||
clusters_applications_jupyter
|
||||
clusters_integrations_elastic_stack
|
||||
clusters_integrations_prometheus
|
||||
clusters_management_project
|
||||
in_review_folder
|
||||
grafana_integrated_projects
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
RSpec.shared_examples 'a permitted attribute' do |relation_sym, permitted_attributes|
|
||||
let(:prohibited_attributes) { %i[remote_url my_attributes my_ids token my_id test] }
|
||||
|
||||
let(:import_export_config) { Gitlab::ImportExport::Config.new.to_h }
|
||||
let(:project_relation_factory) { Gitlab::ImportExport::Project::RelationFactory }
|
||||
|
||||
let(:relation_hash) { (permitted_attributes + prohibited_attributes).map(&:to_s).zip([]).to_h }
|
||||
let(:relation_name) { project_relation_factory.overrides[relation_sym]&.to_sym || relation_sym }
|
||||
let(:relation_class) { project_relation_factory.relation_class(relation_name) }
|
||||
let(:excluded_keys) { import_export_config.dig(:excluded_keys, relation_sym) || [] }
|
||||
|
||||
let(:cleaned_hash) do
|
||||
Gitlab::ImportExport::AttributeCleaner.new(
|
||||
relation_hash: relation_hash,
|
||||
relation_class: relation_class,
|
||||
excluded_keys: excluded_keys
|
||||
).clean
|
||||
end
|
||||
|
||||
let(:permitted_hash) { subject.permit(relation_sym, relation_hash) }
|
||||
|
||||
if described_class.new.permitted_attributes_defined?(relation_sym)
|
||||
it 'contains only attributes that are defined as permitted in the import/export config' do
|
||||
expect(permitted_hash.keys).to contain_exactly(*permitted_attributes.map(&:to_s))
|
||||
end
|
||||
|
||||
it 'does not contain attributes that would be cleaned with AttributeCleaner' do
|
||||
expect(cleaned_hash.keys).to include(*permitted_hash.keys)
|
||||
end
|
||||
|
||||
it 'does not contain prohibited attributes that are not related to given relation' do
|
||||
expect(permitted_hash.keys).not_to include(*prohibited_attributes.map(&:to_s))
|
||||
end
|
||||
else
|
||||
it 'is disabled' do
|
||||
expect(subject).not_to be_permitted_attributes_defined(relation_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue