Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-26 18:10:26 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-26 18:10:26 +0300
commit60a260df4186ab0fe08352d1eb957b34ebdeb7c2 (patch)
tree5c1f44c0cb9c992cd0e1c7d3aa0b241359438314
parentee0b7522d90ace2053f1d8dfcdf6b01d50179ed1 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/added_commit_message.vue43
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue34
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue20
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue32
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue12
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue43
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue33
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue342
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue16
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue33
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb1
-rw-r--r--app/serializers/issue_entity.rb4
-rw-r--r--app/views/projects/pages/_use.html.haml5
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/workers/concerns/waitable_worker.rb6
-rw-r--r--config/feature_flags/development/always_async_project_authorizations_refresh.yml (renamed from config/feature_flags/development/restructured_mr_widget.yml)12
-rw-r--r--doc/administration/package_information/supported_os.md2
-rw-r--r--doc/ci/pipeline_editor/index.md18
-rw-r--r--doc/development/documentation/restful_api_styleguide.md3
-rw-r--r--doc/development/documentation/site_architecture/index.md4
-rw-r--r--lib/gitlab/memory/reports_daemon.rb4
-rw-r--r--locale/gitlab.pot45
-rw-r--r--qa/qa/page/merge_request/show.rb1
-rw-r--r--spec/features/merge_request/user_merges_merge_request_spec.rb21
-rw-r--r--spec/frontend/notes/components/note_actions_spec.js29
-rw-r--r--spec/frontend/vue_mr_widget/components/added_commit_message_spec.js5
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js17
-rw-r--r--spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap56
-rw-r--r--spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap4
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js5
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js104
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js24
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js57
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js13
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js7
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js135
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/mr_widget_options_spec.js76
-rw-r--r--spec/frontend/vue_mr_widget/stores/get_state_key_spec.js22
-rw-r--r--spec/lib/gitlab/git_access_spec.rb10
-rw-r--r--spec/lib/gitlab/memory/reports_daemon_spec.rb4
-rw-r--r--spec/serializers/issue_entity_spec.rb7
-rw-r--r--spec/services/ci/register_job_service_spec.rb16
-rw-r--r--spec/services/merge_requests/reload_diffs_service_spec.rb5
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/helpers/stub_member.rb8
-rw-r--r--spec/support/helpers/stubbed_member.rb64
-rw-r--r--spec/workers/concerns/waitable_worker_spec.rb40
66 files changed, 383 insertions, 1155 deletions
diff --git a/Gemfile b/Gemfile
index 991d84d582e..1883cf53394 100644
--- a/Gemfile
+++ b/Gemfile
@@ -536,7 +536,7 @@ gem 'valid_email', '~> 0.1'
# JSON
gem 'json', '~> 2.5.1'
gem 'json_schemer', '~> 0.2.18'
-gem 'oj', '~> 3.13.17'
+gem 'oj', '~> 3.13.18'
gem 'multi_json', '~> 1.14.1'
gem 'yajl-ruby', '~> 1.4.1', require: 'yajl'
diff --git a/Gemfile.lock b/Gemfile.lock
index d8c3b881ac2..c32c8a6d2a7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -869,7 +869,7 @@ GEM
plist (~> 3.1)
train-core
wmi-lite (~> 1.0)
- oj (3.13.17)
+ oj (3.13.18)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@@ -1637,7 +1637,7 @@ DEPENDENCIES
oauth2 (~> 2.0)
octokit (~> 4.15)
ohai (~> 16.10)
- oj (~> 3.13.17)
+ oj (~> 3.13.18)
omniauth (~> 1.8)
omniauth-alicloud (~> 1.0.1)
omniauth-atlassian-oauth2 (~> 0.2.0)
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index 10e3f57a56d..c7f293a219a 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -170,7 +170,7 @@ export default {
return this.targetType === 'issue';
},
canAssign() {
- return this.getNoteableData.current_user?.can_update && this.isIssue;
+ return this.getNoteableData.current_user?.can_set_issue_metadata && this.isIssue;
},
displayAuthorBadgeText() {
return sprintf(__('This user is the author of this %{noteable}.'), {
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/added_commit_message.vue b/app/assets/javascripts/vue_merge_request_widget/components/added_commit_message.vue
index 437d035fbf5..266f1fb594b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/added_commit_message.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/added_commit_message.vue
@@ -52,31 +52,20 @@ export default {
return n__('%d commit', '%d commits', this.isSquashEnabled ? 1 : this.commitsCount);
},
message() {
- if (this.glFeatures.restructuredMrWidget) {
- if (this.state === 'closed') {
- return s__('mrWidgetCommitsAdded|The changes were not merged into %{targetBranch}.');
- } else if (this.isMerged) {
- return s__(
- 'mrWidgetCommitsAdded|Changes merged into %{targetBranch} with %{mergeCommitSha}%{squashedCommits}.',
- );
- }
-
- return this.isFastForwardEnabled
- ? s__('mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}.')
- : s__(
- 'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}%{squashedCommits}.',
- );
+ if (this.state === 'closed') {
+ return s__('mrWidgetCommitsAdded|The changes were not merged into %{targetBranch}.');
+ } else if (this.isMerged) {
+ return s__(
+ 'mrWidgetCommitsAdded|Changes merged into %{targetBranch} with %{mergeCommitSha}%{squashedCommits}.',
+ );
}
return this.isFastForwardEnabled
- ? s__('mrWidgetCommitsAdded|Adds %{commitCount} to %{targetBranch}.')
+ ? s__('mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}.')
: s__(
- 'mrWidgetCommitsAdded|Adds %{commitCount} and %{mergeCommitCount} to %{targetBranch}%{squashedCommits}.',
+ 'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}%{squashedCommits}.',
);
},
- textDecorativeComponent() {
- return this.glFeatures.restructuredMrWidget ? 'span' : 'strong';
- },
squashCommitMessage() {
if (this.isMerged) {
return s__('mergedCommitsAdded|(commits were squashed)');
@@ -93,25 +82,19 @@ export default {
<span>
<gl-sprintf :message="message">
<template #commitCount>
- <component :is="textDecorativeComponent" class="commits-count-message">{{
- commitsCountMessage
- }}</component>
+ <span class="commits-count-message">{{ commitsCountMessage }}</span>
</template>
<template #mergeCommitCount>
- <component :is="textDecorativeComponent">{{ $options.mergeCommitCount }}</component>
+ <span>{{ $options.mergeCommitCount }}</span>
</template>
<template #targetBranch>
<span class="label-branch">{{ targetBranchEscaped }}</span>
</template>
<template #squashedCommits>
- <template v-if="glFeatures.restructuredMrWidget && isSquashEnabled">
- {{ squashCommitMessage }}</template
- ></template
- >
+ <template v-if="isSquashEnabled"> {{ squashCommitMessage }}</template>
+ </template>
<template #mergeCommitSha>
- <template v-if="glFeatures.restructuredMrWidget"
- ><span class="label-branch">{{ mergeCommitSha }}</span></template
- >
+ <span class="label-branch">{{ mergeCommitSha }}</span>
</template>
</gl-sprintf>
</span>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
index 913aa0e1e34..94a1b805b99 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
@@ -1,7 +1,6 @@
<script>
-import { GlSafeHtmlDirective as SafeHtml, GlLink, GlSprintf } from '@gitlab/ui';
+import { GlSafeHtmlDirective as SafeHtml, GlLink } from '@gitlab/ui';
import { s__, n__ } from '~/locale';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
name: 'MRWidgetRelatedLinks',
@@ -10,9 +9,7 @@ export default {
},
components: {
GlLink,
- GlSprintf,
},
- mixins: [glFeatureFlagMixin()],
props: {
relatedLinks: {
type: Object,
@@ -67,42 +64,21 @@ export default {
</script>
<template>
<section>
- <p
- v-if="relatedLinks.closing"
- :class="{ 'gl-display-inline gl-m-0': glFeatures.restructuredMrWidget }"
- >
+ <p v-if="relatedLinks.closing" class="gl-display-inline gl-m-0">
{{ closesText }}
<span v-safe-html="relatedLinks.closing"></span>
</p>
- <p
- v-if="relatedLinks.mentioned"
- :class="{ 'gl-display-inline gl-m-0': glFeatures.restructuredMrWidget }"
- >
- <span v-if="relatedLinks.closing && glFeatures.restructuredMrWidget">&middot;</span>
+ <p v-if="relatedLinks.mentioned" class="gl-display-inline gl-m-0">
+ <span v-if="relatedLinks.closing">&middot;</span>
{{ n__('mrWidget|Mentions issue', 'mrWidget|Mentions issues', relatedLinks.mentionedCount) }}
<span v-safe-html="relatedLinks.mentioned"></span>
</p>
- <p
- v-if="shouldShowAssignToMeLink"
- :class="{ 'gl-display-inline gl-m-0': glFeatures.restructuredMrWidget }"
- >
+ <p v-if="shouldShowAssignToMeLink" class="gl-display-inline gl-m-0">
<span>
<gl-link rel="nofollow" data-method="post" :href="relatedLinks.assignToMe">{{
assignIssueText
}}</gl-link>
</span>
</p>
- <div
- v-if="divergedCommitsCount > 0 && !glFeatures.restructuredMrWidget"
- class="diverged-commits-count"
- >
- <gl-sprintf :message="s__('mrWidget|The source branch is %{link} the target branch')">
- <template #link>
- <gl-link :href="targetBranchPath">{{
- n__('%d commit behind', '%d commits behind', divergedCommitsCount)
- }}</gl-link>
- </template>
- </gl-sprintf>
- </div>
</section>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
index 7ff1eb6e73a..5b8acb4ebf8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
@@ -1,25 +1,17 @@
<script>
-import { GlButton, GlLoadingIcon } from '@gitlab/ui';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { GlLoadingIcon } from '@gitlab/ui';
import ciIcon from '~/vue_shared/components/ci_icon.vue';
export default {
components: {
ciIcon,
- GlButton,
GlLoadingIcon,
},
- mixins: [glFeatureFlagMixin()],
props: {
status: {
type: String,
required: true,
},
- showDisabledButton: {
- type: Boolean,
- required: false,
- default: false,
- },
},
computed: {
isLoading() {
@@ -42,15 +34,5 @@ export default {
</div>
<ci-icon v-else :status="statusObj" :size="24" />
</div>
-
- <gl-button
- v-if="!glFeatures.restructuredMrWidget && showDisabledButton"
- category="primary"
- variant="confirm"
- data-testid="disabled-merge-button"
- :disabled="true"
- >
- {{ s__('mrWidget|Merge') }}
- </gl-button>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue
index 18761d04c2e..515a7cf51a1 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue
@@ -1,8 +1,5 @@
<script>
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-
export default {
- mixins: [glFeatureFlagMixin()],
props: {
value: {
type: String,
@@ -23,10 +20,7 @@ export default {
<template>
<li>
<div class="commit-message-editor">
- <div
- :class="{ 'gl-mb-3': glFeatures.restructuredMrWidget }"
- class="d-flex flex-wrap align-items-center justify-content-between"
- >
+ <div class="d-flex flex-wrap align-items-center justify-content-between gl-mb-3">
<label class="col-form-label" :for="inputId">
<strong>{{ label }}</strong>
</label>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue
index 071920856a8..f74826f95d3 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue
@@ -1,5 +1,4 @@
<script>
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import statusIcon from '../mr_widget_status_icon.vue';
export default {
@@ -7,7 +6,6 @@ export default {
components: {
statusIcon,
},
- mixins: [glFeatureFlagMixin()],
};
</script>
<template>
@@ -16,7 +14,7 @@ export default {
<status-icon status="warning" show-disabled-button />
</div>
<div class="media-body">
- <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
+ <span class="gl-ml-0! gl-text-body! bold">
{{ s__('mrWidget|Merge unavailable: merge requests are read-only on archived projects.') }}
</span>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
index aabbeac564a..63bd8f3d8dc 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
@@ -3,7 +3,6 @@ import { GlSkeletonLoader, GlIcon, GlButton, GlSprintf } from '@gitlab/ui';
import autoMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/auto_merge';
import autoMergeEnabledQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql';
import createFlash from '~/flash';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { AUTO_MERGE_STRATEGIES } from '../../constants';
@@ -78,19 +77,6 @@ export default {
autoMergeStrategy() {
return (this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr).autoMergeStrategy;
},
- canRemoveSourceBranch() {
- const { currentUserId } = this.mr;
- const mergeUserId = this.glFeatures.mergeRequestWidgetGraphql
- ? getIdFromGraphQLId(this.state.mergeUser?.id)
- : this.mr.mergeUserId;
- const canRemoveSourceBranch = this.glFeatures.mergeRequestWidgetGraphql
- ? this.state.userPermissions.removeSourceBranch
- : this.mr.canRemoveSourceBranch;
-
- return (
- !this.shouldRemoveSourceBranch && canRemoveSourceBranch && mergeUserId === currentUserId
- );
- },
},
methods: {
cancelAutomaticMerge() {
@@ -175,24 +161,6 @@ export default {
{{ cancelButtonText }}
</gl-button>
</h4>
- <section v-if="!glFeatures.restructuredMrWidget" class="mr-info-list">
- <p v-if="shouldRemoveSourceBranch">
- {{ s__('mrWidget|Deletes the source branch') }}
- </p>
- <p v-else class="gl-display-flex">
- <span class="gl-mr-3">{{ s__('mrWidget|Does not delete the source branch') }}</span>
- <gl-button
- v-if="canRemoveSourceBranch"
- :loading="isRemovingSourceBranch"
- size="small"
- class="js-remove-source-branch"
- data-testid="removeSourceBranchButton"
- @click="removeSourceBranch"
- >
- {{ s__('mrWidget|Delete source branch') }}
- </gl-button>
- </p>
- </section>
</div>
</template>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
index fd42fa0421f..e2d87d8d536 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
@@ -1,5 +1,4 @@
<script>
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import statusIcon from '../mr_widget_status_icon.vue';
export default {
@@ -7,14 +6,13 @@ export default {
components: {
statusIcon,
},
- mixins: [glFeatureFlagMixin()],
};
</script>
<template>
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="loading" />
<div class="media-body space-children">
- <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
+ <span class="gl-ml-0! gl-text-body! bold">
{{ s__('mrWidget|Checking if merge request can be merged…') }}
</span>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue
index d50e52f5ac1..61f7d26f51e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue
@@ -1,5 +1,4 @@
<script>
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MrWidgetAuthorTime from '../mr_widget_author_time.vue';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -9,7 +8,6 @@ export default {
MrWidgetAuthorTime,
statusIcon,
},
- mixins: [glFeatureFlagMixin()],
props: {
/* TODO: This is providing all store and service down when it
only needs metrics and targetBranch */
@@ -30,13 +28,6 @@ export default {
:date-title="mr.metrics.closedAt"
:date-readable="mr.metrics.readableClosedAt"
/>
-
- <section v-if="!glFeatures.restructuredMrWidget" class="mr-info-list">
- <p>
- {{ s__('mrWidget|The changes were not merged into') }}
- <a :href="mr.targetBranchPath" class="label-branch"> {{ mr.targetBranch }} </a>
- </p>
- </section>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
index def30dacf8a..7652d7049f2 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
@@ -97,18 +97,14 @@ export default {
</gl-skeleton-loader>
</div>
<div v-else class="media-body space-children gl-display-flex gl-align-items-center">
- <span
- v-if="shouldBeRebased"
- :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
- class="bold"
- >
+ <span v-if="shouldBeRebased" class="gl-ml-0! gl-text-body! bold">
{{
s__(`mrWidget|Merge blocked: fast-forward merge is not possible.
To merge this request, first rebase locally.`)
}}
</span>
<template v-else>
- <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
+ <span class="gl-ml-0! gl-text-body! bold">
{{ s__('mrWidget|Merge blocked: merge conflicts must be resolved.') }}
<span v-if="!canMerge">
{{
@@ -121,14 +117,14 @@ export default {
<gl-button
v-if="showResolveButton"
:href="mr.conflictResolutionPath"
- :size="glFeatures.restructuredMrWidget ? 'small' : 'medium'"
+ size="small"
data-testid="resolve-conflicts-button"
>
{{ s__('mrWidget|Resolve conflicts') }}
</gl-button>
<gl-button
v-if="canMerge"
- :size="glFeatures.restructuredMrWidget ? 'small' : 'medium'"
+ size="small"
data-testid="merge-locally-button"
class="js-check-out-modal-trigger"
>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
index bf036f562ed..19df346759f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
@@ -1,13 +1,10 @@
<script>
-/* eslint-disable @gitlab/vue-require-i18n-strings */
-import { GlLoadingIcon, GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui';
import api from '~/api';
import createFlash from '~/flash';
import { s__, __ } from '~/locale';
import { OPEN_REVERT_MODAL, OPEN_CHERRY_PICK_MODAL } from '~/projects/commit/constants';
import modalEventHub from '~/projects/commit/event_hub';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import eventHub from '../../event_hub';
import MrWidgetAuthorTime from '../mr_widget_author_time.vue';
@@ -19,11 +16,8 @@ export default {
components: {
MrWidgetAuthorTime,
GlIcon,
- ClipboardButton,
- GlLoadingIcon,
GlButton,
},
- mixins: [glFeatureFlagMixin()],
props: {
mr: {
type: Object,
@@ -183,41 +177,6 @@ export default {
{{ s__('mrWidget|Delete source branch') }}
</gl-button>
</div>
- <section
- v-if="!glFeatures.restructuredMrWidget"
- class="mr-info-list"
- data-qa-selector="merged_status_content"
- >
- <p>
- {{ s__('mrWidget|The changes were merged into') }}
- <span class="label-branch">
- <a :href="mr.targetBranchPath">{{ mr.targetBranch }}</a>
- </span>
- <template v-if="mr.mergeCommitSha">
- with
- <a
- :href="mr.mergeCommitPath"
- class="commit-sha js-mr-merged-commit-sha"
- v-text="mr.shortMergeCommitSha"
- >
- </a>
- <clipboard-button
- :title="__('Copy commit SHA')"
- :text="mr.mergeCommitSha"
- css-class="js-mr-merged-copy-sha"
- category="tertiary"
- size="small"
- />
- </template>
- </p>
- <p v-if="mr.sourceBranchRemoved">
- {{ s__('mrWidget|The source branch has been deleted') }}
- </p>
- <p v-if="shouldShowSourceBranchRemoving">
- <gl-loading-icon size="sm" :inline="true" />
- <span> {{ s__('mrWidget|The source branch is being deleted') }} </span>
- </p>
- </section>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue
index b86ab69af3f..c7574a41bb8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue
@@ -1,6 +1,5 @@
<script>
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import simplePoll from '~/lib/utils/simple_poll';
import MergeRequest from '~/merge_request';
import eventHub from '../../event_hub';
@@ -15,7 +14,6 @@ export default {
components: {
statusIcon,
},
- mixins: [glFeatureFlagMixin()],
props: {
mr: {
type: Object,
@@ -90,14 +88,6 @@ export default {
{{ mergeStatus.message }}
<gl-emoji :data-name="mergeStatus.emoji" />
</h4>
- <section v-if="!glFeatures.restructuredMrWidget" class="mr-info-list">
- <p>
- {{ s__('mrWidget|Merges changes into') }}
- <span class="label-branch">
- <a :href="mr.targetBranchPath">{{ mr.targetBranch }}</a>
- </span>
- </p>
- </section>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue
index cadbd9c28a9..659d12d1160 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue
@@ -74,13 +74,7 @@ export default {
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
- <span
- :class="{
- 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget,
- }"
- class="bold js-branch-text"
- data-testid="widget-content"
- >
+ <span class="gl-ml-0! gl-text-body! bold js-branch-text" data-testid="widget-content">
<gl-sprintf :message="warning">
<template #code="{ content }">
<code>{{ content }}</code>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue
index 34c5a2ff2c8..e99ee59b877 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue
@@ -14,7 +14,7 @@ export default {
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
- <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
+ <span class="gl-ml-0! gl-text-body! bold">
{{
s__(
`mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue.`,
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
index 59767eb2e6e..0880fd81500 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
@@ -161,15 +161,13 @@ export default {
<div class="rebase-state-find-class-convention media media-body space-children">
<span
v-if="rebaseInProgress || isMakingRequest"
- :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
- class="gl-font-weight-bold"
+ class="gl-ml-0! gl-text-body! gl-font-weight-bold"
data-testid="rebase-message"
>{{ __('Rebase in progress') }}</span
>
<span
v-if="!rebaseInProgress && !canPushToSourceBranch"
- :class="{ 'gl-text-body!': glFeatures.restructuredMrWidget }"
- class="gl-font-weight-bold gl-ml-0!"
+ class="gl-text-body! gl-font-weight-bold gl-ml-0!"
data-testid="rebase-message"
>{{ fastForwardMergeText }}</span
>
@@ -177,30 +175,9 @@ export default {
v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest"
class="accept-merge-holder clearfix js-toggle-container accept-action media space-children gl-align-items-center"
>
- <gl-button
- v-if="!glFeatures.restructuredMrWidget"
- :loading="isMakingRequest"
- variant="confirm"
- data-qa-selector="mr_rebase_button"
- data-testid="standard-rebase-button"
- @click="rebase"
- >
- {{ __('Rebase') }}
- </gl-button>
- <gl-button
- v-if="!glFeatures.restructuredMrWidget && showRebaseWithoutCi"
- :loading="isMakingRequest"
- variant="confirm"
- category="secondary"
- data-testid="rebase-without-ci-button"
- @click="rebaseWithoutCi"
- >
- {{ __('Rebase without pipeline') }}
- </gl-button>
<span
v-if="!rebasingError"
- :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
- class="gl-font-weight-bold"
+ class="gl-ml-0! gl-text-body! gl-font-weight-bold"
data-testid="rebase-message"
data-qa-selector="no_fast_forward_message_content"
>{{
@@ -211,18 +188,18 @@ export default {
rebasingError
}}</span>
<gl-button
- v-if="glFeatures.restructuredMrWidget"
:loading="isMakingRequest"
variant="confirm"
size="small"
data-qa-selector="mr_rebase_button"
+ data-testid="standard-rebase-button"
class="gl-ml-3!"
@click="rebase"
>
{{ __('Rebase') }}
</gl-button>
<gl-button
- v-if="glFeatures.restructuredMrWidget && showRebaseWithoutCi"
+ v-if="showRebaseWithoutCi"
:loading="isMakingRequest"
variant="confirm"
size="small"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue
index d204befef58..d507e5f232b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue
@@ -1,7 +1,6 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__ } from '~/locale';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -12,7 +11,6 @@ export default {
GlSprintf,
statusIcon,
},
- mixins: [glFeatureFlagMixin()],
computed: {
troubleshootingDocsPath() {
return helpPagePath('ci/troubleshooting', { anchor: 'merge-request-status-messages' });
@@ -30,7 +28,7 @@ export default {
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
- <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold">
+ <span class="gl-ml-0! gl-text-body! bold">
<gl-sprintf :message="$options.i18n.failedMessage">
<template #link="{ content }">
<gl-link :href="troubleshootingDocsPath" target="_blank">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index cf482410bef..884fc666276 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -31,12 +31,10 @@ import {
import eventHub from '../../event_hub';
import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
import MergeRequestStore from '../../stores/mr_widget_store';
-import statusIcon from '../mr_widget_status_icon.vue';
import AddedCommitMessage from '../added_commit_message.vue';
import RelatedLinks from '../mr_widget_related_links.vue';
import CommitEdit from './commit_edit.vue';
import CommitMessageDropdown from './commit_message_dropdown.vue';
-import CommitsHeader from './commits_header.vue';
import SquashBeforeMerge from './squash_before_merge.vue';
import MergeFailedPipelineConfirmationDialog from './merge_failed_pipeline_confirmation_dialog.vue';
@@ -96,9 +94,7 @@ export default {
},
},
components: {
- statusIcon,
SquashBeforeMerge,
- CommitsHeader,
CommitEdit,
CommitMessageDropdown,
GlIcon,
@@ -320,34 +316,24 @@ export default {
showDangerMessageForMergeTrain() {
return this.preferredAutoMergeStrategy === MT_MERGE_STRATEGY && this.isPipelineFailed;
},
- restructuredWidgetShowMergeButtons() {
- if (this.glFeatures.restructuredMrWidget) {
- return (
- (this.isMergeAllowed || this.isAutoMergeAvailable) &&
- this.state.userPermissions.canMerge &&
- !this.mr.mergeOngoing &&
- !this.mr.autoMergeEnabled
- );
- }
-
- return true;
+ shouldShowMergeControls() {
+ return (
+ (this.isMergeAllowed || this.isAutoMergeAvailable) &&
+ (this.stateData.userPermissions?.canMerge || this.mr.canMerge) &&
+ !this.mr.mergeOngoing &&
+ !this.mr.autoMergeEnabled
+ );
},
sourceBranchDeletedText() {
- if (this.glFeatures.restructuredMrWidget) {
- if (this.removeSourceBranch) {
- return this.mr.state === 'merged'
- ? __('Deleted the source branch.')
- : __('Source branch will be deleted.');
- }
-
+ if (this.removeSourceBranch) {
return this.mr.state === 'merged'
- ? __('Did not delete the source branch.')
- : __('Source branch will not be deleted.');
+ ? __('Deleted the source branch.')
+ : __('Source branch will be deleted.');
}
- return this.removeSourceBranch
- ? __('Deletes the source branch.')
- : __('Does not delete the source branch.');
+ return this.mr.state === 'merged'
+ ? __('Did not delete the source branch.')
+ : __('Source branch will not be deleted.');
},
},
mounted() {
@@ -525,10 +511,7 @@ export default {
<template>
<div
data-testid="ready_to_merge_state"
- :class="{
- 'gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-pl-7 gl-rounded-bottom-left-base gl-rounded-bottom-right-base':
- glFeatures.restructuredMrWidget,
- }"
+ class="gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-pl-7 gl-rounded-bottom-left-base gl-rounded-bottom-right-base"
>
<div v-if="loading" class="mr-widget-body">
<div class="gl-w-full mr-ready-to-merge-loader">
@@ -541,16 +524,10 @@ export default {
</div>
</div>
<template v-else>
- <div
- class="mr-widget-body media"
- :class="{
- 'mr-widget-body-line-height-1': glFeatures.restructuredMrWidget,
- }"
- >
- <status-icon v-if="!glFeatures.restructuredMrWidget" :status="iconClass" />
+ <div class="mr-widget-body media mr-widget-body-line-height-1">
<div class="media-body">
<div class="mr-widget-body-controls gl-display-flex gl-align-items-center gl-flex-wrap">
- <gl-button-group v-if="restructuredWidgetShowMergeButtons" class="gl-align-self-start">
+ <gl-button-group v-if="shouldShowMergeControls" class="gl-align-self-start">
<gl-button
size="medium"
category="primary"
@@ -603,19 +580,14 @@ export default {
<merge-train-helper-icon v-if="shouldRenderMergeTrainHelperIcon" class="gl-mx-3" />
<div
v-if="shouldShowMergeControls"
- :class="{ 'gl-w-full gl-order-n1 gl-mb-5': glFeatures.restructuredMrWidget }"
- class="gl-display-flex gl-align-items-center gl-flex-wrap"
+ class="gl-display-flex gl-align-items-center gl-flex-wrap gl-w-full gl-order-n1 gl-mb-5"
>
<gl-form-checkbox
v-if="canRemoveSourceBranch"
id="remove-source-branch-input"
v-model="removeSourceBranch"
:disabled="isRemoveSourceBranchButtonDisabled"
- :class="{
- 'gl-mx-3': !glFeatures.restructuredMrWidget,
- 'gl-mr-5': glFeatures.restructuredMrWidget,
- }"
- class="js-remove-source-branch-checkbox gl-display-flex gl-align-items-center"
+ class="js-remove-source-branch-checkbox gl-display-flex gl-align-items-center gl-mr-5"
>
{{ __('Delete source branch') }}
</gl-form-checkbox>
@@ -626,16 +598,11 @@ export default {
v-model="squashBeforeMerge"
:help-path="mr.squashBeforeMergeHelpPath"
:is-disabled="isSquashReadOnly"
- :class="{
- 'gl-mx-3': !glFeatures.restructuredMrWidget,
- 'gl-mr-5': glFeatures.restructuredMrWidget,
- }"
+ class="gl-mr-5"
/>
<gl-form-checkbox
- v-if="
- glFeatures.restructuredMrWidget && (shouldShowSquashEdit || shouldShowMergeEdit)
- "
+ v-if="shouldShowSquashEdit || shouldShowMergeEdit"
v-model="editCommitMessage"
data-testid="widget_edit_commit_message"
class="gl-display-flex gl-align-items-center"
@@ -644,198 +611,113 @@ export default {
</gl-form-checkbox>
</div>
<div
- v-else-if="!glFeatures.restructuredMrWidget"
- class="bold js-resolve-mr-widget-items-message gl-ml-3"
+ v-if="editCommitMessage"
+ class="gl-w-full gl-order-n1"
+ data-testid="edit_commit_message"
>
- <div
- v-if="hasPipelineMustSucceedConflict"
- class="gl-display-flex gl-align-items-center"
- data-testid="pipeline-succeed-conflict"
- >
- <gl-sprintf :message="pipelineMustSucceedConflictText" />
- <gl-link
- :href="mr.pipelineMustSucceedDocsPath"
- target="_blank"
- class="gl-display-flex gl-ml-2"
+ <ul class="border-top commits-list flex-list gl-list-style-none gl-p-0 gl-pt-4">
+ <commit-edit
+ v-if="shouldShowSquashEdit"
+ :value="squashCommitMessage"
+ :label="__('Squash commit message')"
+ input-id="squash-message-edit"
+ class="gl-m-0! gl-p-0!"
+ @input="setSquashCommitMessage"
>
- <gl-icon name="question" />
- </gl-link>
- </div>
- <gl-sprintf v-else :message="mergeDisabledText" />
+ <template #header>
+ <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" />
+ </template>
+ </commit-edit>
+ <commit-edit
+ v-if="shouldShowMergeEdit"
+ :value="commitMessage"
+ :label="__('Merge commit message')"
+ input-id="merge-message-edit"
+ class="gl-m-0! gl-p-0!"
+ @input="setCommitMessage"
+ />
+ <li class="gl-m-0! gl-p-0!">
+ <p class="form-text text-muted">
+ <gl-sprintf :message="commitTemplateHintText">
+ <template #link="{ content }">
+ <gl-link :href="commitTemplateHelpPage" class="inline-link" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </li>
+ </ul>
</div>
- <template v-if="glFeatures.restructuredMrWidget">
- <div
- v-if="editCommitMessage"
- class="gl-w-full gl-order-n1"
- data-testid="edit_commit_message"
- >
- <ul
- :class="{
- 'content-list': !glFeatures.restructuredMrWidget,
- 'gl-list-style-none gl-p-0 gl-pt-4': glFeatures.restructuredMrWidget,
- }"
- class="border-top commits-list flex-list"
- >
- <commit-edit
- v-if="shouldShowSquashEdit"
- :value="squashCommitMessage"
- :label="__('Squash commit message')"
- input-id="squash-message-edit"
- class="gl-m-0! gl-p-0!"
- @input="setSquashCommitMessage"
+ <div
+ v-if="!shouldShowMergeControls"
+ class="gl-w-full gl-order-n1 gl-text-gray-500"
+ data-qa-selector="merged_status_content"
+ >
+ <strong v-if="mr.state !== 'closed'">
+ {{ __('Merge details') }}
+ </strong>
+ <ul class="gl-pl-4 gl-m-0">
+ <li v-if="mr.divergedCommitsCount > 0" class="gl-line-height-normal">
+ <gl-sprintf
+ :message="s__('mrWidget|The source branch is %{link} the target branch')"
>
- <template #header>
- <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" />
+ <template #link>
+ <gl-link :href="mr.targetBranchPath">{{
+ n__('%d commit behind', '%d commits behind', mr.divergedCommitsCount)
+ }}</gl-link>
</template>
- </commit-edit>
- <commit-edit
- v-if="shouldShowMergeEdit"
- :value="commitMessage"
- :label="__('Merge commit message')"
- input-id="merge-message-edit"
- class="gl-m-0! gl-p-0!"
- @input="setCommitMessage"
+ </gl-sprintf>
+ </li>
+ <li class="gl-line-height-normal">
+ <added-commit-message
+ :state="mr.state"
+ :merge-commit-sha="mr.shortMergeCommitSha"
+ :is-squash-enabled="squashBeforeMerge"
+ :is-fast-forward-enabled="!shouldShowMergeEdit"
+ :commits-count="commitsCount"
+ :target-branch="stateData.targetBranch"
/>
- <li class="gl-m-0! gl-p-0!">
- <p class="form-text text-muted">
- <gl-sprintf :message="commitTemplateHintText">
- <template #link="{ content }">
- <gl-link
- :href="commitTemplateHelpPage"
- class="inline-link"
- target="_blank"
- >
- {{ content }}
- </gl-link>
- </template>
- </gl-sprintf>
- </p>
- </li>
- </ul>
- </div>
- <div
- v-if="!restructuredWidgetShowMergeButtons"
- class="gl-w-full gl-order-n1 gl-text-gray-500"
- data-qa-selector="merged_status_content"
- >
- <strong v-if="mr.state !== 'closed'">
- {{ __('Merge details') }}
- </strong>
- <ul class="gl-pl-4 gl-m-0">
- <li v-if="mr.divergedCommitsCount > 0" class="gl-line-height-normal">
- <gl-sprintf
- :message="s__('mrWidget|The source branch is %{link} the target branch')"
- >
- <template #link>
- <gl-link :href="mr.targetBranchPath">{{
- n__('%d commit behind', '%d commits behind', mr.divergedCommitsCount)
- }}</gl-link>
- </template>
- </gl-sprintf>
- </li>
- <li class="gl-line-height-normal">
- <added-commit-message
- :state="mr.state"
- :merge-commit-sha="mr.shortMergeCommitSha"
- :is-squash-enabled="squashBeforeMerge"
- :is-fast-forward-enabled="!shouldShowMergeEdit"
- :commits-count="commitsCount"
- :target-branch="stateData.targetBranch"
- />
- </li>
- <li v-if="mr.state !== 'closed'" class="gl-line-height-normal">
- {{ sourceBranchDeletedText }}
- </li>
- <li v-if="mr.relatedLinks" class="gl-line-height-normal">
- <related-links
- :state="mr.state"
- :related-links="mr.relatedLinks"
- :show-assign-to-me="false"
- class="mr-ready-merge-related-links gl-display-inline"
- />
- </li>
- </ul>
- </div>
- <div
- v-else
- :class="{ 'gl-mb-5': restructuredWidgetShowMergeButtons }"
- class="gl-w-full gl-order-n1 gl-text-gray-500"
- >
- <added-commit-message
- :is-squash-enabled="squashBeforeMerge"
- :is-fast-forward-enabled="!shouldShowMergeEdit"
- :commits-count="commitsCount"
- :target-branch="stateData.targetBranch"
- />
- <template v-if="mr.relatedLinks">
- &middot;
+ </li>
+ <li v-if="mr.state !== 'closed'" class="gl-line-height-normal">
+ {{ sourceBranchDeletedText }}
+ </li>
+ <li v-if="mr.relatedLinks" class="gl-line-height-normal">
<related-links
:state="mr.state"
:related-links="mr.relatedLinks"
:show-assign-to-me="false"
- :diverged-commits-count="mr.divergedCommitsCount"
- :target-branch-path="mr.targetBranchPath"
class="mr-ready-merge-related-links gl-display-inline"
/>
- </template>
- </div>
- </template>
- </div>
- <div
- v-if="showDangerMessageForMergeTrain && !glFeatures.restructuredMrWidget"
- class="gl-mt-5 gl-text-gray-500"
- data-testid="failed-pipeline-merge-train-text"
- >
- {{ __('The latest pipeline for this merge request did not complete successfully.') }}
+ </li>
+ </ul>
+ </div>
+ <div
+ v-else
+ :class="{ 'gl-mb-5': shouldShowMergeControls }"
+ class="gl-w-full gl-order-n1 gl-text-gray-500"
+ >
+ <added-commit-message
+ :is-squash-enabled="squashBeforeMerge"
+ :is-fast-forward-enabled="!shouldShowMergeEdit"
+ :commits-count="commitsCount"
+ :target-branch="stateData.targetBranch"
+ />
+ <template v-if="mr.relatedLinks">
+ &middot;
+ <related-links
+ :state="mr.state"
+ :related-links="mr.relatedLinks"
+ :show-assign-to-me="false"
+ :diverged-commits-count="mr.divergedCommitsCount"
+ :target-branch-path="mr.targetBranchPath"
+ class="mr-ready-merge-related-links gl-display-inline"
+ />
+ </template>
+ </div>
</div>
</div>
</div>
- <template v-if="shouldShowMergeControls && !glFeatures.restructuredMrWidget">
- <div v-if="!shouldShowMergeEdit" class="mr-fast-forward-message">
- {{ __('Fast-forward merge without a merge commit') }}
- </div>
- <commits-header
- v-if="!glFeatures.restructuredMrWidget && (shouldShowSquashEdit || shouldShowMergeEdit)"
- :is-squash-enabled="squashBeforeMerge"
- :commits-count="commitsCount"
- :target-branch="stateData.targetBranch"
- :is-fast-forward-enabled="!shouldShowMergeEdit"
- :class="{ 'border-bottom': stateData.mergeError }"
- >
- <ul class="border-top content-list commits-list flex-list">
- <commit-edit
- v-if="shouldShowSquashEdit"
- :value="squashCommitMessage"
- :label="__('Squash commit message')"
- input-id="squash-message-edit"
- squash
- @input="setSquashCommitMessage"
- >
- <template #header>
- <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" />
- </template>
- </commit-edit>
- <commit-edit
- v-if="shouldShowMergeEdit"
- :value="commitMessage"
- :label="__('Merge commit message')"
- input-id="merge-message-edit"
- @input="setCommitMessage"
- />
- <li>
- <p class="form-text text-muted">
- <gl-sprintf :message="commitTemplateHintText">
- <template #link="{ content }">
- <gl-link :href="commitTemplateHelpPage" class="inline-link" target="_blank">
- {{ content }}
- </gl-link>
- </template>
- </gl-sprintf>
- </p>
- </li>
- </ul>
- </commits-header>
- </template>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue
index b1fbe150fcf..06f70bc456e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue
@@ -1,6 +1,5 @@
<script>
import { GlButton } from '@gitlab/ui';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { I18N_SHA_MISMATCH } from '../../i18n';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -13,7 +12,6 @@ export default {
i18n: {
I18N_SHA_MISMATCH,
},
- mixins: [glFeatureFlagMixin()],
props: {
mr: {
type: Object,
@@ -28,8 +26,7 @@ export default {
<status-icon :show-disabled-button="false" status="warning" />
<div class="media-body">
<span
- :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
- class="gl-font-weight-bold"
+ class="gl-ml-0! gl-text-body! gl-font-weight-bold"
data-qa-selector="head_mismatch_content"
>
{{ $options.i18n.I18N_SHA_MISMATCH.warningMessage }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
index c6227c4394d..1413a46b4b9 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
@@ -1,6 +1,5 @@
<script>
import { GlIcon, GlTooltipDirective, GlFormCheckbox, GlLink } from '@gitlab/ui';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { SQUASH_BEFORE_MERGE } from '../../i18n';
export default {
@@ -12,7 +11,6 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
- mixins: [glFeatureFlagsMixin()],
i18n: {
...SQUASH_BEFORE_MERGE,
},
@@ -36,9 +34,6 @@ export default {
tooltipTitle() {
return this.isDisabled ? this.$options.i18n.tooltipTitle : null;
},
- helpIconName() {
- return this.glFeatures.restructuredMrWidget ? 'question-o' : 'question';
- },
},
};
</script>
@@ -62,10 +57,10 @@ export default {
v-gl-tooltip
:href="helpPath"
:title="$options.i18n.helpLabel"
- :class="{ 'gl-text-blue-600': glFeatures.restructuredMrWidget }"
+ class="gl-text-blue-600"
target="_blank"
>
- <gl-icon :name="helpIconName" />
+ <gl-icon name="question-o" />
<span class="sr-only">
{{ $options.i18n.helpLabel }}
</span>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
index 25ba4bf12af..7e9ebcf0b2e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
@@ -1,6 +1,5 @@
<script>
import { GlButton } from '@gitlab/ui';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import notesEventHub from '~/notes/event_hub';
import statusIcon from '../mr_widget_status_icon.vue';
@@ -10,7 +9,6 @@ export default {
statusIcon,
GlButton,
},
- mixins: [glFeatureFlagMixin()],
props: {
mr: {
type: Object,
@@ -29,22 +27,15 @@ export default {
<div class="mr-widget-body media gl-flex-wrap">
<status-icon show-disabled-button status="warning" />
<div class="media-body">
- <span
- :class="{
- 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget,
- 'gl-display-block': !glFeatures.restructuredMrWidget,
- }"
- class="gl-ml-3 gl-font-weight-bold gl-w-100"
- >
+ <span class="gl-ml-0! gl-text-body! gl-ml-3 gl-font-weight-bold gl-w-100">
{{ s__('mrWidget|Merge blocked: all threads must be resolved.') }}
</span>
<gl-button
data-testid="jump-to-first"
class="gl-ml-3"
size="small"
- :icon="glFeatures.restructuredMrWidget ? undefined : 'comment-next'"
- :variant="glFeatures.restructuredMrWidget ? 'confirm' : 'default'"
- :category="glFeatures.restructuredMrWidget ? 'secondary' : 'primary'"
+ variant="confirm"
+ category="secondary"
@click="jumpToFirstUnresolvedDiscussion"
>
{{ s__('mrWidget|Jump to first unresolved thread') }}
@@ -54,7 +45,6 @@ export default {
:href="mr.createIssueToResolveDiscussionsPath"
class="js-create-issue gl-ml-3"
size="small"
- :icon="glFeatures.restructuredMrWidget ? undefined : 'issue-new'"
>
{{ s__('mrWidget|Create issue to resolve all threads') }}
</gl-button>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
index 5bd7745d704..501aee1a18d 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
@@ -167,10 +167,7 @@ export default {
<status-icon :show-disabled-button="canUpdate" status="warning" />
<div class="media-body">
<div class="float-left">
- <span
- :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
- class="gl-font-weight-bold"
- >
+ <span class="gl-ml-0! gl-text-body! gl-font-weight-bold">
{{
__("Merge blocked: merge request must be marked as ready. It's still marked as draft.")
}}
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
index 627ddb0445e..d964b4bacac 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
@@ -20,13 +20,6 @@ export default {
this.mr.preventMerge,
);
},
- shouldShowMergeControls() {
- if (this.glFeatures.restructuredMrWidget) {
- return this.restructuredWidgetShowMergeButtons;
- }
-
- return this.isMergeAllowed || this.isAutoMergeAvailable;
- },
mergeDisabledText() {
if (this.pipeline?.status === PIPELINE_SKIPPED_STATUS) {
return MERGE_DISABLED_SKIPPED_PIPELINE_TEXT;
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index 3e0ac236fdf..0edd44d835e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -17,7 +17,6 @@ import { setFaviconOverlay } from '../lib/utils/favicon';
import Loading from './components/loading.vue';
import MrWidgetAlertMessage from './components/mr_widget_alert_message.vue';
import MrWidgetPipelineContainer from './components/mr_widget_pipeline_container.vue';
-import WidgetRelatedLinks from './components/mr_widget_related_links.vue';
import WidgetSuggestPipeline from './components/mr_widget_suggest_pipeline.vue';
import SourceBranchRemovalStatus from './components/source_branch_removal_status.vue';
import ArchivedState from './components/states/mr_widget_archived.vue';
@@ -61,7 +60,6 @@ export default {
ExtensionsContainer,
'mr-widget-suggest-pipeline': WidgetSuggestPipeline,
MrWidgetPipelineContainer,
- 'mr-widget-related-links': WidgetRelatedLinks,
MrWidgetAlertMessage,
'mr-widget-merged': MergedState,
'mr-widget-closed': ClosedState,
@@ -73,9 +71,7 @@ export default {
'mr-widget-nothing-to-merge': NothingToMergeState,
'mr-widget-not-allowed': NotAllowedState,
'mr-widget-missing-branch': MissingBranchState,
- 'mr-widget-ready-to-merge': window.gon?.features?.restructuredMrWidget
- ? () => import('./components/states/new_ready_to_merge.vue')
- : ReadyToMergeState,
+ 'mr-widget-ready-to-merge': () => import('./components/states/new_ready_to_merge.vue'),
'sha-mismatch': ShaMismatch,
'mr-widget-checking': CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
@@ -163,12 +159,6 @@ export default {
shouldRenderCodeQuality() {
return this.mr?.codequalityReportsPath;
},
- shouldRenderRelatedLinks() {
- return (
- (Boolean(this.mr.relatedLinks) || this.mr.divergedCommitsCount > 0) &&
- !this.mr.isNothingToMergeState
- );
- },
shouldRenderSourceBranchRemovalStatus() {
return (
!this.mr.canRemoveSourceBranch &&
@@ -239,9 +229,6 @@ export default {
shouldShowCodeQualityExtension() {
return window.gon?.features?.refactorCodeQualityExtension;
},
- isRestructuredMrWidgetEnabled() {
- return window.gon?.features?.restructuredMrWidget;
- },
},
watch: {
'mr.machineValue': {
@@ -638,23 +625,7 @@ export default {
<div class="mr-widget-section" data-qa-selector="mr_widget_content">
<component :is="componentName" :mr="mr" :service="service" />
- <ready-to-merge
- v-if="isRestructuredMrWidgetEnabled && mr.commitsCount"
- :mr="mr"
- :service="service"
- />
- <div v-else class="mr-widget-info">
- <mr-widget-related-links
- v-if="shouldRenderRelatedLinks"
- :state="mr.state"
- :related-links="mr.relatedLinks"
- :diverged-commits-count="mr.divergedCommitsCount"
- :target-branch-path="mr.targetBranchPath"
- class="mr-info-list gl-ml-7 gl-pb-5"
- />
-
- <source-branch-removal-status v-if="shouldRenderSourceBranchRemovalStatus" />
- </div>
+ <ready-to-merge v-if="mr.commitsCount" :mr="mr" :service="service" />
</div>
</div>
<mr-widget-pipeline-container
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
index 18d955652ba..7a458f9ce7e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
@@ -27,8 +27,6 @@ export default function deviseState() {
return stateKey.shaMismatch;
} else if (this.autoMergeEnabled && !this.mergeError) {
return stateKey.autoMergeEnabled;
- } else if (!this.canMerge && !window.gon?.features?.restructuredMrWidget) {
- return stateKey.notAllowedToMerge;
} else if (this.canBeMerged) {
return stateKey.readyToMerge;
}
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 6f1f37b86cf..13ebe57a4d9 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -34,7 +34,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action only: [:show] do
push_frontend_feature_flag(:merge_request_widget_graphql, project)
push_frontend_feature_flag(:core_security_mr_widget_counts, project)
- push_frontend_feature_flag(:restructured_mr_widget, project)
push_frontend_feature_flag(:refactor_mr_widgets_extensions, project)
push_frontend_feature_flag(:refactor_code_quality_extension, project)
push_frontend_feature_flag(:refactor_mr_widget_test_summary, project)
diff --git a/app/serializers/issue_entity.rb b/app/serializers/issue_entity.rb
index ea43ed87d22..7ff75927fcd 100644
--- a/app/serializers/issue_entity.rb
+++ b/app/serializers/issue_entity.rb
@@ -47,6 +47,10 @@ class IssueEntity < IssuableEntity
can?(request.current_user, :update_issue, issue)
end
+ expose :can_set_issue_metadata do |issue|
+ can?(request.current_user, :set_issue_metadata, issue)
+ end
+
expose :can_award_emoji do |issue|
can?(request.current_user, :award_emoji, issue)
end
diff --git a/app/views/projects/pages/_use.html.haml b/app/views/projects/pages/_use.html.haml
index 20e6338fa76..f865fac0e88 100644
--- a/app/views/projects/pages/_use.html.haml
+++ b/app/views/projects/pages/_use.html.haml
@@ -4,7 +4,8 @@
= s_('GitLabPages|Configure pages')
.card-body
%p.gl-mb-0
- - docs_link_start = "<a href='#{help_page_path('user/project/pages/index')}' target='_blank' rel='noopener noreferrer'>".html_safe
- - samples_link_start = "<a href='https://gitlab.com/pages' target='_blank' rel='noopener noreferrer'>".html_safe
+ - docs_link_start = "<a href='#{help_page_path('user/project/pages/index')}' target='_blank' rel='noopener noreferrer' data-track-action='click_link' data-track-label='pages_docs_link'>".html_safe
+ - samples_link_start = "<a href='https://gitlab.com/pages' target='_blank' rel='noopener noreferrer' data-track-action='click_link' data-track-label='pages_samples_link>"
+ .html_safe
- link_end = '</a>'.html_safe
= s_('GitLabPages|Your Pages site is not configured yet. See the %{docs_link_start}GitLab Pages documentation%{link_end} to learn how to upload your static site and have GitLab serve it. You can also take some inspiration from the %{samples_link_start}sample Pages projects%{link_end}.').html_safe % { docs_link_start: docs_link_start, samples_link_start: samples_link_start, link_end: link_end }
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index e90ea35f28e..58db071a8d1 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -3,7 +3,7 @@
- project = @target_project || @project
- presenter = local_assigns.fetch(:presenter, nil)
-= form_errors(issuable)
+= form_errors(issuable, pajamas_alert: true)
- if @conflict
= render Pajamas::AlertComponent.new(variant: :danger,
diff --git a/app/workers/concerns/waitable_worker.rb b/app/workers/concerns/waitable_worker.rb
index 336d60d46ac..9300c2a5790 100644
--- a/app/workers/concerns/waitable_worker.rb
+++ b/app/workers/concerns/waitable_worker.rb
@@ -7,7 +7,7 @@ module WaitableWorker
# Schedules multiple jobs and waits for them to be completed.
def bulk_perform_and_wait(args_list)
# Short-circuit: it's more efficient to do small numbers of jobs inline
- if args_list.size == 1
+ if args_list.size == 1 && !always_async_project_authorizations_refresh?
return bulk_perform_inline(args_list)
end
@@ -29,6 +29,10 @@ module WaitableWorker
bulk_perform_async(failed) if failed.present?
end
+
+ def always_async_project_authorizations_refresh?
+ Feature.enabled?(:always_async_project_authorizations_refresh)
+ end
end
def perform(*args)
diff --git a/config/feature_flags/development/restructured_mr_widget.yml b/config/feature_flags/development/always_async_project_authorizations_refresh.yml
index cf20130509a..233be4d930e 100644
--- a/config/feature_flags/development/restructured_mr_widget.yml
+++ b/config/feature_flags/development/always_async_project_authorizations_refresh.yml
@@ -1,8 +1,8 @@
---
-name: restructured_mr_widget
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68565
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339181
-milestone: '14.3'
+name: always_async_project_authorizations_refresh
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92333
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367683
+milestone: '15.3'
type: development
-group: group::code review
-default_enabled: true
+group: group::workspace
+default_enabled: false
diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md
index 4f31981a05c..739ba80ea2b 100644
--- a/doc/administration/package_information/supported_os.md
+++ b/doc/administration/package_information/supported_os.md
@@ -23,7 +23,7 @@ The following lists the currently supported OSs and their possible EOL dates.
| Debian 10 | GitLab CE / GitLab EE 12.2.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | 2024 | <https://wiki.debian.org/LTS> |
| Debian 11 | GitLab CE / GitLab EE 14.6.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | 2026 | <https://wiki.debian.org/LTS> |
| OpenSUSE 15.3 | GitLab CE / GitLab EE 14.5.0 | x86_64, aarch64 | [OpenSUSE Install Documentation](https://about.gitlab.com/install/#opensuse-leap-15-3) | Nov 2022 | <https://en.opensuse.org/Lifetime> |
-| RHEL 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, arm64 | [Use CentOS Install Documentation](https://about.gitlab.com/install/#centos-7) | May 2024 | [RHEL Details](https://access.redhat.com/support/policy/updates/errata/#Life_Cycle_Dates) |
+| RHEL 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, arm64 | [Use CentOS Install Documentation](https://about.gitlab.com/install/#centos-7) | May 2029 | [RHEL Details](https://access.redhat.com/support/policy/updates/errata/#Life_Cycle_Dates) |
| SLES 12 | GitLab EE 9.0.0 | x86_64 | [Use OpenSUSE Install Documentation](https://about.gitlab.com/install/#opensuse-leap-15-3) | Oct 2027 | <https://www.suse.com/lifecycle/> |
| Oracle Linux | GitLab CE / GitLab EE 8.14.0 | x86_64 | [Use CentOS Install Documentation](https://about.gitlab.com/install/#centos-7) | Jul 2024 | <https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf> |
| Scientific Linux | GitLab CE / GitLab EE 8.14.0 | x86_64 | [Use CentOS Install Documentation](https://about.gitlab.com/install/#centos-7) | June 2024 | <https://scientificlinux.org/downloads/sl-versions/sl7/> |
diff --git a/doc/ci/pipeline_editor/index.md b/doc/ci/pipeline_editor/index.md
index 4fb2ec94d60..d9687e4f9fc 100644
--- a/doc/ci/pipeline_editor/index.md
+++ b/doc/ci/pipeline_editor/index.md
@@ -40,6 +40,10 @@ is invalid, a tip is shown to help you fix the problem:
## Lint CI configuration
+NOTE:
+The **Lint** tab is replaced with the **Validate** tab when [pipeline simulations](#simulate-a-cicd-pipeline)
+are enabled.
+
To test the validity of your GitLab CI/CD configuration before committing the changes,
you can use the CI lint tool. To access it, go to **CI/CD > Editor** and select the **Lint** tab.
@@ -51,6 +55,20 @@ reflected in the CI lint. It displays the same results as the existing [CI Lint
![Linting errors in a CI configuration](img/pipeline_editor_lint_v13_8.png)
+## Simulate a CI/CD pipeline
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337282) in GitLab 15.3 [with a flag](../../administration/feature_flags.md) named `simulate_pipeline`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `simulate_pipeline`.
+The feature is not ready for production use. When this feature is enabled, it replaces the **Lint** tab.
+
+To look for pipeline syntax and logic issues, you can simulate the creation of a
+GitLab CI/CD pipeline in the **Validate** tab. A pipeline simulation can help find
+problems such as incorrect `rules` and `needs` job dependencies, and is similar to
+simulations in the [CI Lint tool](../lint.md#simulate-a-pipeline).
+
## View included CI/CD configuration
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/7064) in GitLab 15.0 [with a flag](../../administration/feature_flags.md) named `pipeline_editor_file_tree`. Disabled by default.
diff --git a/doc/development/documentation/restful_api_styleguide.md b/doc/development/documentation/restful_api_styleguide.md
index 30bd5e27411..bf1461a810d 100644
--- a/doc/development/documentation/restful_api_styleguide.md
+++ b/doc/development/documentation/restful_api_styleguide.md
@@ -104,6 +104,9 @@ for the section. For example:
> `widget_message` [introduced](<link-to-issue>) in GitLab 14.3.
```
+If the API or attribute is deployed behind a feature flag,
+[include the feature flag information](feature_flags.md) in the version history.
+
## Deprecations
To document the deprecation of an API endpoint, follow the steps to
diff --git a/doc/development/documentation/site_architecture/index.md b/doc/development/documentation/site_architecture/index.md
index 2fe4494bc37..1dadbaa7051 100644
--- a/doc/development/documentation/site_architecture/index.md
+++ b/doc/development/documentation/site_architecture/index.md
@@ -66,10 +66,10 @@ you should keep the documentation with the code in that repository.
Then you can use one of these approaches:
-- (Recommended) [Add the repository to the list of products](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/development.md#add-a-new-product)
+- Recommended. [Add the repository to the list of products](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/development.md#add-a-new-product)
published at <https://docs.gitlab.com>. The source of the documentation pages remains
in the external repository, but the resulting pages are indexed and searchable on <https://docs.gitlab.com>.
-- (Recommended) [Add an entry in the global navigation](global_nav.md#add-a-navigation-entry) for
+- Recommended. [Add an entry in the global navigation](global_nav.md#add-a-navigation-entry) for
<https://docs.gitlab.com> that links directly to the documentation in that external repository.
The documentation pages are not indexed or searchable on <https://docs.gitlab.com>.
View [an example](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/fedb6378a3c92274ba3b6031df0d34455594e4cc/content/_data/navigation.yaml#L2944-L2946).
diff --git a/lib/gitlab/memory/reports_daemon.rb b/lib/gitlab/memory/reports_daemon.rb
index 2b2e0915e72..779c19b3a1e 100644
--- a/lib/gitlab/memory/reports_daemon.rb
+++ b/lib/gitlab/memory/reports_daemon.rb
@@ -41,7 +41,7 @@ module Gitlab
end
log_report(report_label(report), tms)
- @report_duration_counter.increment({ report: report_label(report) }, tms.real.to_i)
+ @report_duration_counter.increment({ report: report_label(report) }, tms.real)
sleep sleep_between_reports_s
end
@@ -63,7 +63,7 @@ module Gitlab
message: 'finished',
pid: $$,
worker_id: worker_id,
- report: report_label,
+ perf_report: report_label,
duration_s: tms.real.round(2),
cpu_s: tms.utime.round(2),
sys_cpu_s: tms.stime.round(2)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 1cf6a679287..8e5cd06dc39 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -12466,9 +12466,6 @@ msgstr ""
msgid "Deletes the source branch"
msgstr ""
-msgid "Deletes the source branch."
-msgstr ""
-
msgid "Deleting"
msgstr ""
@@ -13732,9 +13729,6 @@ msgstr ""
msgid "Documents reindexed: %{processed_documents} (%{percentage}%%)"
msgstr ""
-msgid "Does not delete the source branch."
-msgstr ""
-
msgid "Domain"
msgstr ""
@@ -16021,9 +16015,6 @@ msgstr ""
msgid "Fast timeout"
msgstr ""
-msgid "Fast-forward merge without a merge commit"
-msgstr ""
-
msgid "Faster releases. Better code. Less pain."
msgstr ""
@@ -38957,9 +38948,6 @@ msgstr ""
msgid "The latest artifacts created by jobs in the most recent successful pipeline will be stored."
msgstr ""
-msgid "The latest pipeline for this merge request did not complete successfully."
-msgstr ""
-
msgid "The latest pipeline for this merge request did not succeed. The latest changes are unverified."
msgstr ""
@@ -39488,9 +39476,6 @@ msgstr ""
msgid "There was an error removing the e-mail."
msgstr ""
-msgid "There was an error resetting group pipeline minutes."
-msgstr ""
-
msgid "There was an error resetting user pipeline minutes."
msgstr ""
@@ -46292,12 +46277,6 @@ msgstr ""
msgid "mrWidgetCommitsAdded|1 merge commit"
msgstr ""
-msgid "mrWidgetCommitsAdded|Adds %{commitCount} and %{mergeCommitCount} to %{targetBranch}%{squashedCommits}."
-msgstr ""
-
-msgid "mrWidgetCommitsAdded|Adds %{commitCount} to %{targetBranch}."
-msgstr ""
-
msgid "mrWidgetCommitsAdded|Changes merged into %{targetBranch} with %{mergeCommitSha}%{squashedCommits}."
msgstr ""
@@ -46414,9 +46393,6 @@ msgstr ""
msgid "mrWidget|Delete source branch"
msgstr ""
-msgid "mrWidget|Deletes the source branch"
-msgstr ""
-
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
@@ -46426,9 +46402,6 @@ msgstr ""
msgid "mrWidget|Dismiss"
msgstr ""
-msgid "mrWidget|Does not delete the source branch"
-msgstr ""
-
msgid "mrWidget|Failed to load deployment statistics"
msgstr ""
@@ -46464,9 +46437,6 @@ msgid_plural "mrWidget|Mentions issues"
msgstr[0] ""
msgstr[1] ""
-msgid "mrWidget|Merge"
-msgstr ""
-
msgid "mrWidget|Merge blocked: all required approvals must be given."
msgstr ""
@@ -46500,9 +46470,6 @@ msgstr ""
msgid "mrWidget|Merged by"
msgstr ""
-msgid "mrWidget|Merges changes into"
-msgstr ""
-
msgid "mrWidget|Merging! Changes are being shipped…"
msgstr ""
@@ -46587,21 +46554,9 @@ msgstr ""
msgid "mrWidget|The %{type} branch %{codeStart}%{name}%{codeEnd} does not exist."
msgstr ""
-msgid "mrWidget|The changes were merged into"
-msgstr ""
-
-msgid "mrWidget|The changes were not merged into"
-msgstr ""
-
-msgid "mrWidget|The source branch has been deleted"
-msgstr ""
-
msgid "mrWidget|The source branch is %{link} the target branch"
msgstr ""
-msgid "mrWidget|The source branch is being deleted"
-msgstr ""
-
msgid "mrWidget|This merge request failed to be merged automatically"
msgstr ""
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 27c12a4e21f..8e2959abb2f 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -71,7 +71,6 @@ module QA
view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue' do
element :cherry_pick_button
- element :merged_status_content
element :revert_button
end
diff --git a/spec/features/merge_request/user_merges_merge_request_spec.rb b/spec/features/merge_request/user_merges_merge_request_spec.rb
index 6a9a30953df..c91dc7b1c00 100644
--- a/spec/features/merge_request/user_merges_merge_request_spec.rb
+++ b/spec/features/merge_request/user_merges_merge_request_spec.rb
@@ -21,27 +21,6 @@ RSpec.describe "User merges a merge request", :js do
end
end
- context "ff-only merge" do
- let(:project) { create(:project, :public, :repository, merge_requests_ff_only_enabled: true) }
-
- before do
- stub_feature_flags(restructured_mr_widget: false)
- visit(merge_request_path(merge_request))
- end
-
- context "when branch is rebased" do
- let!(:merge_request) { create(:merge_request, :rebased, source_project: project) }
-
- it_behaves_like "fast forward merge a merge request"
- end
-
- context "when branch is merged" do
- let!(:merge_request) { create(:merge_request, :merged_target, source_project: project) }
-
- it_behaves_like "fast forward merge a merge request"
- end
- end
-
context 'sidebar merge requests counter' do
let(:project) { create(:project, :public, :repository) }
let!(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js
index bf5a6b4966a..524b6c442cf 100644
--- a/spec/frontend/notes/components/note_actions_spec.js
+++ b/spec/frontend/notes/components/note_actions_spec.js
@@ -159,7 +159,7 @@ describe('noteActions', () => {
});
});
- describe('when a user has access to edit an issue', () => {
+ describe('when a user can set metadata of an issue', () => {
const testButtonClickTriggersAction = () => {
axiosMock.onPut(`${TEST_HOST}/api/v4/projects/group/project/issues/1`).reply(() => {
expect(actions.updateAssignees).toHaveBeenCalled();
@@ -176,7 +176,7 @@ describe('noteActions', () => {
});
store.state.noteableData = {
current_user: {
- can_update: true,
+ can_set_issue_metadata: true,
},
};
store.state.userData = userDataMock;
@@ -191,6 +191,31 @@ describe('noteActions', () => {
it('should be possible to unassign the comment author', testButtonClickTriggersAction);
});
+ describe('when a user can update but not set metadata of an issue', () => {
+ beforeEach(() => {
+ wrapper = mountNoteActions(props, {
+ targetType: () => 'issue',
+ });
+ store.state.noteableData = {
+ current_user: {
+ can_update: true,
+ can_set_issue_metadata: false,
+ },
+ };
+ store.state.userData = userDataMock;
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ axiosMock.restore();
+ });
+
+ it('should not be possible to assign or unassign the comment author', () => {
+ const assignUserButton = wrapper.find('[data-testid="assign-user"]');
+ expect(assignUserButton.exists()).toBe(false);
+ });
+ });
+
describe('when a user does not have access to edit an issue', () => {
const testButtonDoesNotRender = () => {
const assignUserButton = wrapper.find('[data-testid="assign-user"]');
diff --git a/spec/frontend/vue_mr_widget/components/added_commit_message_spec.js b/spec/frontend/vue_mr_widget/components/added_commit_message_spec.js
index 150680caa7e..cb53dc1fb61 100644
--- a/spec/frontend/vue_mr_widget/components/added_commit_message_spec.js
+++ b/spec/frontend/vue_mr_widget/components/added_commit_message_spec.js
@@ -10,11 +10,6 @@ function factory(propsData) {
targetBranch: 'main',
...propsData,
},
- provide: {
- glFeatures: {
- restructuredMrWidget: true.valueOf,
- },
- },
});
}
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js
index c25e10c5249..11373be578a 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js
@@ -6,7 +6,6 @@ describe('MR widget status icon component', () => {
let wrapper;
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
- const findDisabledMergeButton = () => wrapper.find('[data-testid="disabled-merge-button"]');
const createWrapper = (props, mountFn = shallowMount) => {
wrapper = mountFn(mrStatusIcon, {
@@ -41,20 +40,4 @@ describe('MR widget status icon component', () => {
expect(wrapper.find('[data-testid="status_failed-icon"]').exists()).toBe(true);
});
});
-
- describe('with disabled button', () => {
- it('renders a disabled button', () => {
- createWrapper({ status: 'failed', showDisabledButton: true });
-
- expect(findDisabledMergeButton().exists()).toBe(true);
- });
- });
-
- describe('without disabled button', () => {
- it('does not render a disabled button', () => {
- createWrapper({ status: 'failed' });
-
- expect(findDisabledMergeButton().exists()).toBe(false);
- });
- });
});
diff --git a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
index 56a0218b374..e591698aa90 100644
--- a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
+++ b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
@@ -40,34 +40,6 @@ exports[`MRWidgetAutoMergeEnabled when graphql is disabled template should have
</gl-button-stub>
</h4>
-
- <section
- class="mr-info-list"
- >
- <p
- class="gl-display-flex"
- >
- <span
- class="gl-mr-3"
- >
- Does not delete the source branch
- </span>
-
- <gl-button-stub
- buttontextclasses=""
- category="primary"
- class="js-remove-source-branch"
- data-testid="removeSourceBranchButton"
- icon=""
- size="small"
- variant="default"
- >
-
- Delete source branch
-
- </gl-button-stub>
- </p>
- </section>
</div>
</div>
`;
@@ -112,34 +84,6 @@ exports[`MRWidgetAutoMergeEnabled when graphql is enabled template should have c
</gl-button-stub>
</h4>
-
- <section
- class="mr-info-list"
- >
- <p
- class="gl-display-flex"
- >
- <span
- class="gl-mr-3"
- >
- Does not delete the source branch
- </span>
-
- <gl-button-stub
- buttontextclasses=""
- category="primary"
- class="js-remove-source-branch"
- data-testid="removeSourceBranchButton"
- icon=""
- size="small"
- variant="default"
- >
-
- Delete source branch
-
- </gl-button-stub>
- </p>
- </section>
</div>
</div>
`;
diff --git a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap
index 98297630792..7e741bf4660 100644
--- a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap
+++ b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap
@@ -5,7 +5,7 @@ exports[`PipelineFailed should render error message with a disabled merge button
class="mr-widget-body media"
>
<status-icon-stub
- showdisabledbutton="true"
+ show-disabled-button="true"
status="warning"
/>
@@ -13,7 +13,7 @@ exports[`PipelineFailed should render error message with a disabled merge button
class="media-body space-children"
>
<span
- class="bold"
+ class="gl-ml-0! gl-text-body! bold"
>
<gl-sprintf-stub
message="Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js
index f3061d792d0..9332b7e334a 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js
@@ -18,11 +18,6 @@ describe('MRWidgetArchived', () => {
expect(vm.$el.querySelector('.ci-status-icon')).not.toBeNull();
});
- it('renders a disabled button', () => {
- expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
- expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Merge');
- });
-
it('renders information', () => {
expect(vm.$el.querySelector('.bold').textContent.trim()).toEqual(
'Merge unavailable: merge requests are read-only on archived projects.',
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
index 7387ed2d5e9..5bbc5d4a106 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
@@ -102,74 +102,6 @@ describe('MRWidgetAutoMergeEnabled', () => {
});
describe('computed', () => {
- describe('canRemoveSourceBranch', () => {
- it('should return true when user is able to remove source branch', () => {
- factory({
- ...defaultMrProps(),
- });
-
- expect(wrapper.findByTestId('removeSourceBranchButton').exists()).toBe(true);
- });
-
- it.each`
- mergeUserId | currentUserId
- ${2} | ${1}
- ${1} | ${2}
- `(
- 'should return false when user id is not the same with who set the MWPS',
- ({ mergeUserId, currentUserId }) => {
- factory({
- ...defaultMrProps(),
- mergeUserId,
- currentUserId,
- });
-
- expect(wrapper.findByTestId('removeSourceBranchButton').exists()).toBe(false);
- },
- );
-
- it('should not find "Delete" button when shouldRemoveSourceBranch set to true', () => {
- factory({
- ...defaultMrProps(),
- shouldRemoveSourceBranch: true,
- });
-
- expect(wrapper.findByTestId('removeSourceBranchButton').exists()).toBe(false);
- });
-
- it('should find "Delete" button when shouldRemoveSourceBranch overrides state.forceRemoveSourceBranch', () => {
- factory(
- {
- ...defaultMrProps(),
- shouldRemoveSourceBranch: false,
- },
- {
- forceRemoveSourceBranch: true,
- },
- );
-
- expect(wrapper.findByTestId('removeSourceBranchButton').exists()).toBe(true);
- });
-
- it('should find "Delete" button when shouldRemoveSourceBranch set to false', () => {
- factory({
- ...defaultMrProps(),
- shouldRemoveSourceBranch: false,
- });
-
- expect(wrapper.findByTestId('removeSourceBranchButton').exists()).toBe(true);
- });
-
- it('should return false if user is not able to remove the source branch', () => {
- factory({
- ...defaultMrProps(),
- canRemoveSourceBranch: false,
- });
-
- expect(wrapper.findByTestId('removeSourceBranchButton').exists()).toBe(false);
- });
- });
-
describe('cancelButtonText', () => {
it('should return "Cancel" if MWPS is selected', () => {
factory({
@@ -265,42 +197,6 @@ describe('MRWidgetAutoMergeEnabled', () => {
expect(wrapper.find('.js-cancel-auto-merge').props('loading')).toBe(true);
});
- it('should show source branch will be deleted text when it source branch set to remove', () => {
- factory({
- ...defaultMrProps(),
- shouldRemoveSourceBranch: true,
- });
-
- const normalizedText = wrapper.text().replace(/\s+/g, ' ');
-
- expect(normalizedText).toContain('Deletes the source branch');
- expect(normalizedText).not.toContain('Does not delete the source branch');
- });
-
- it('should not show delete source branch button when user not able to delete source branch', () => {
- factory({
- ...defaultMrProps(),
- currentUserId: 4,
- });
-
- expect(wrapper.find('.js-remove-source-branch').exists()).toBe(false);
- });
-
- it('should disable delete source branch button when the action is in progress', async () => {
- factory({
- ...defaultMrProps(),
- });
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- isRemovingSourceBranch: true,
- });
-
- await nextTick();
-
- expect(wrapper.find('.js-remove-source-branch').props('loading')).toBe(true);
- });
-
it('should render the status text as "...to merged automatically" if MWPS is selected', () => {
factory({
...defaultMrProps(),
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js
index afe6bd0e767..02de426204b 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js
@@ -15,10 +15,6 @@ describe('MRWidgetChecking', () => {
vm.$destroy();
});
- it('renders disabled button', () => {
- expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
- });
-
it('renders loading icon', () => {
expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js
index 6ae218ce6f8..f7d046eb8f9 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js
@@ -36,28 +36,4 @@ describe('MRWidgetClosed', () => {
it('renders warning icon', () => {
expect(vm.$el.querySelector('.js-ci-status-icon-warning')).not.toBeNull();
});
-
- it('renders closed by information with author and time', () => {
- expect(
- vm.$el.querySelector('.js-mr-widget-author').textContent.trim().replace(/\s\s+/g, ' '),
- ).toContain('Closed by Administrator less than a minute ago');
- });
-
- it('links to the user that closed the MR', () => {
- expect(vm.$el.querySelector('.author-link').getAttribute('href')).toEqual(
- 'http://localhost:3000/root',
- );
- });
-
- it('renders information about the changes not being merged', () => {
- expect(
- vm.$el.querySelector('.mr-info-list').textContent.trim().replace(/\s\s+/g, ' '),
- ).toContain('The changes were not merged into so_long_jquery');
- });
-
- it('renders link for target branch', () => {
- expect(vm.$el.querySelector('.label-branch').getAttribute('href')).toEqual(
- '/twitter/flight/commits/so_long_jquery',
- );
- });
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
index 6d8e7056366..a9c1d602a37 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
@@ -1,6 +1,5 @@
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
-import StatusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue';
import MrWidgetFailedToMerge from '~/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue';
import eventHub from '~/vue_merge_request_widget/event_hub';
@@ -116,7 +115,6 @@ describe('MRWidgetFailedToMerge', () => {
it('renders warning icon and disabled merge button', () => {
expect(wrapper.find('.js-ci-status-icon-warning')).not.toBeNull();
- expect(wrapper.find(StatusIcon).props('showDisabledButton')).toBe(true);
});
it('renders given error', () => {
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js
index 29ee7e0010f..2606933450e 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js
@@ -1,5 +1,5 @@
import { getByRole } from '@testing-library/dom';
-import Vue, { nextTick } from 'vue';
+import Vue from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { OPEN_REVERT_MODAL, OPEN_CHERRY_PICK_MODAL } from '~/projects/commit/constants';
@@ -10,14 +10,6 @@ import eventHub from '~/vue_merge_request_widget/event_hub';
describe('MRWidgetMerged', () => {
let vm;
const targetBranch = 'foo';
- const selectors = {
- get copyMergeShaButton() {
- return vm.$el.querySelector('button.js-mr-merged-copy-sha');
- },
- get mergeCommitShaLink() {
- return vm.$el.querySelector('a.js-mr-merged-commit-sha');
- },
- };
beforeEach(() => {
jest.spyOn(document, 'dispatchEvent');
@@ -177,58 +169,11 @@ describe('MRWidgetMerged', () => {
expect(vm.$el.textContent).toContain('Administrator');
});
- it('renders branch information', () => {
- expect(vm.$el.textContent).toContain('The changes were merged into');
- expect(vm.$el.textContent).toContain(targetBranch);
- });
-
- it('renders information about branch being deleted', () => {
- expect(vm.$el.textContent).toContain('The source branch has been deleted');
- });
-
it('shows revert and cherry-pick buttons', () => {
expect(vm.$el.textContent).toContain('Revert');
expect(vm.$el.textContent).toContain('Cherry-pick');
});
- it('shows button to copy commit SHA to clipboard', () => {
- expect(selectors.copyMergeShaButton).not.toBe(null);
- expect(selectors.copyMergeShaButton.dataset.clipboardText).toBe(vm.mr.mergeCommitSha);
- });
-
- it('hides button to copy commit SHA if SHA does not exist', async () => {
- vm.mr.mergeCommitSha = null;
-
- await nextTick();
-
- expect(selectors.copyMergeShaButton).toBe(null);
- expect(vm.$el.querySelector('.mr-info-list').innerText).not.toContain('with');
- });
-
- it('shows merge commit SHA link', () => {
- expect(selectors.mergeCommitShaLink).not.toBe(null);
- expect(selectors.mergeCommitShaLink.text).toContain(vm.mr.shortMergeCommitSha);
- expect(selectors.mergeCommitShaLink.href).toBe(vm.mr.mergeCommitPath);
- });
-
- it('should not show source branch deleted text', async () => {
- vm.mr.sourceBranchRemoved = false;
-
- await nextTick();
-
- expect(vm.$el.innerText).not.toContain('The source branch has been deleted');
- });
-
- it('should show source branch deleting text', async () => {
- vm.mr.isRemovingSourceBranch = true;
- vm.mr.sourceBranchRemoved = false;
-
- await nextTick();
-
- expect(vm.$el.innerText).toContain('The source branch is being deleted');
- expect(vm.$el.innerText).not.toContain('The source branch has been deleted');
- });
-
it('should use mergedEvent mergedAt as tooltip title', () => {
expect(vm.$el.querySelector('time').getAttribute('title')).toBe('Jan 24, 2018 1:02pm UTC');
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
index e16c897a49b..49bd3739fdb 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
@@ -43,19 +43,6 @@ describe('MRWidgetMerging', () => {
).toContain('Merging!');
});
- it('renders branch information', () => {
- expect(
- wrapper
- .find('.mr-info-list')
- .text()
- .trim()
- .replace(/\s\s+/g, ' ')
- .replace(/[\r\n]+/g, ' '),
- ).toEqual('Merges changes into branch');
-
- expect(wrapper.find('a').attributes('href')).toBe('/branch-path');
- });
-
describe('initiateMergePolling', () => {
it('should call simplePoll', () => {
wrapper.vm.initiateMergePolling();
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
index 3e0840fef4e..4e44ac539f2 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
@@ -1,5 +1,4 @@
import { shallowMount } from '@vue/test-utils';
-import statusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue';
import PipelineFailed from '~/vue_merge_request_widget/components/states/pipeline_failed.vue';
describe('PipelineFailed', () => {
@@ -9,8 +8,6 @@ describe('PipelineFailed', () => {
wrapper = shallowMount(PipelineFailed);
};
- const findStatusIcon = () => wrapper.find(statusIcon);
-
beforeEach(() => {
createComponent();
});
@@ -23,8 +20,4 @@ describe('PipelineFailed', () => {
it('should render error message with a disabled merge button', () => {
expect(wrapper.element).toMatchSnapshot();
});
-
- it('merge button should be disabled', () => {
- expect(findStatusIcon().props('showDisabledButton')).toBe(true);
- });
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 188582d2e05..02148e044ec 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -10,7 +10,6 @@ import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/state
import simplePoll from '~/lib/utils/simple_poll';
import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
-import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue';
import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue';
import MergeFailedPipelineConfirmationDialog from '~/vue_merge_request_widget/components/states/merge_failed_pipeline_confirmation_dialog.vue';
@@ -60,6 +59,7 @@ const createTestMr = (customConfig) => {
transitionStateMachine: (transition) => eventHub.$emit('StateMachineValueChanged', transition),
translateStateToMachine: () => this.transitionStateMachine(),
state: 'open',
+ canMerge: true,
};
Object.assign(mr, customConfig.mr);
@@ -90,7 +90,7 @@ const createReadyToMergeResponse = (customMr) => {
const createComponent = (
customConfig = {},
mergeRequestWidgetGraphql = false,
- restructuredMrWidget = false,
+ restructuredMrWidget = true,
) => {
wrapper = shallowMount(ReadyToMerge, {
propsData: {
@@ -111,7 +111,6 @@ const createComponent = (
};
const findCheckboxElement = () => wrapper.find(SquashBeforeMerge);
-const findCommitsHeaderElement = () => wrapper.find(CommitsHeader);
const findCommitEditElements = () => wrapper.findAll(CommitEdit);
const findCommitDropdownElement = () => wrapper.find(CommitMessageDropdown);
const findFirstCommitEditLabel = () => findCommitEditElements().at(0).props('label');
@@ -575,71 +574,9 @@ describe('ReadyToMerge', () => {
});
});
- describe('commits count collapsible header', () => {
- it('should be rendered when fast-forward is disabled', () => {
- createComponent();
-
- expect(findCommitsHeaderElement().exists()).toBeTruthy();
- });
-
- describe('when fast-forward is enabled', () => {
- it('should be rendered if squash and squash before are enabled and there is more than 1 commit', () => {
- createComponent({
- mr: {
- ffOnlyEnabled: true,
- enableSquashBeforeMerge: true,
- squashIsSelected: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeTruthy();
- });
-
- it('should not be rendered if squash before merge is disabled', () => {
- createComponent({
- mr: {
- ffOnlyEnabled: true,
- enableSquashBeforeMerge: false,
- squash: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeFalsy();
- });
-
- it('should not be rendered if squash is disabled', () => {
- createComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: false,
- enableSquashBeforeMerge: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeFalsy();
- });
-
- it('should not be rendered if commits count is 1', () => {
- createComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: true,
- enableSquashBeforeMerge: true,
- commitsCount: 1,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeFalsy();
- });
- });
- });
-
describe('commits edit components', () => {
describe('when fast-forward merge is enabled', () => {
- it('should not be rendered if squash is disabled', () => {
+ it('should not be rendered if squash is disabled', async () => {
createComponent({
mr: {
ffOnlyEnabled: true,
@@ -678,7 +615,7 @@ describe('ReadyToMerge', () => {
expect(findCommitEditElements().length).toBe(0);
});
- it('should have one edit component if squash is enabled and there is more than 1 commit', () => {
+ it('should have one edit component if squash is enabled and there is more than 1 commit', async () => {
createComponent({
mr: {
ffOnlyEnabled: true,
@@ -688,18 +625,14 @@ describe('ReadyToMerge', () => {
},
});
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
+
expect(findCommitEditElements().length).toBe(1);
expect(findFirstCommitEditLabel()).toBe('Squash commit message');
});
});
- it('should have one edit component when squash is disabled', () => {
- createComponent();
-
- expect(findCommitEditElements().length).toBe(1);
- });
-
- it('should have two edit components when squash is enabled and there is more than 1 commit', () => {
+ it('should have two edit components when squash is enabled and there is more than 1 commit', async () => {
createComponent({
mr: {
commitsCount: 2,
@@ -708,6 +641,8 @@ describe('ReadyToMerge', () => {
},
});
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
+
expect(findCommitEditElements().length).toBe(2);
});
@@ -737,11 +672,12 @@ describe('ReadyToMerge', () => {
},
});
await nextTick();
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
expect(findCommitEditElements().length).toBe(2);
});
- it('should have one edit components when squash is enabled and there is 1 commit only', () => {
+ it('should have one edit components when squash is enabled and there is 1 commit only', async () => {
createComponent({
mr: {
commitsCount: 1,
@@ -750,16 +686,12 @@ describe('ReadyToMerge', () => {
},
});
- expect(findCommitEditElements().length).toBe(1);
- });
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
- it('should have correct edit merge commit label', () => {
- createComponent();
-
- expect(findFirstCommitEditLabel()).toBe('Merge commit message');
+ expect(findCommitEditElements().length).toBe(1);
});
- it('should have correct edit squash commit label', () => {
+ it('should have correct edit squash commit label', async () => {
createComponent({
mr: {
commitsCount: 2,
@@ -768,6 +700,8 @@ describe('ReadyToMerge', () => {
},
});
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
+
expect(findFirstCommitEditLabel()).toBe('Squash commit message');
});
});
@@ -779,45 +713,23 @@ describe('ReadyToMerge', () => {
expect(findCommitDropdownElement().exists()).toBeFalsy();
});
- it('should be rendered if squash is enabled and there is more than 1 commit', () => {
+ it('should be rendered if squash is enabled and there is more than 1 commit', async () => {
createComponent({
mr: { enableSquashBeforeMerge: true, squashIsSelected: true, commitsCount: 2 },
});
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
+
expect(findCommitDropdownElement().exists()).toBeTruthy();
});
});
- it('renders a tip including a link to docs on templates', () => {
+ it('renders a tip including a link to docs on templates', async () => {
createComponent();
- expect(findTipLink().exists()).toBe(true);
- });
- });
-
- describe('Merge request project settings', () => {
- describe('when the merge commit merge method is enabled', () => {
- beforeEach(() => {
- createComponent({
- mr: { ffOnlyEnabled: false },
- });
- });
-
- it('should not show fast forward message', () => {
- expect(wrapper.find('.mr-fast-forward-message').exists()).toBe(false);
- });
- });
-
- describe('when the fast-forward merge method is enabled', () => {
- beforeEach(() => {
- createComponent({
- mr: { ffOnlyEnabled: true },
- });
- });
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
- it('should show fast forward message', () => {
- expect(wrapper.find('.mr-fast-forward-message').exists()).toBe(true);
- });
+ expect(findTipLink().exists()).toBe(true);
});
});
@@ -872,6 +784,7 @@ describe('ReadyToMerge', () => {
createDefaultGqlComponent();
await waitForPromises();
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
expect(finderFn()).toBe(initialValue);
});
@@ -879,6 +792,7 @@ describe('ReadyToMerge', () => {
it('should have updated value after graphql refetch', async () => {
createDefaultGqlComponent();
await waitForPromises();
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
triggerApprovalUpdated();
await waitForPromises();
@@ -889,6 +803,7 @@ describe('ReadyToMerge', () => {
it('should not update if user has touched', async () => {
createDefaultGqlComponent();
await waitForPromises();
+ await wrapper.find('[data-testid="widget_edit_commit_message"]').vm.$emit('input', true);
const input = wrapper.find(inputId);
input.element.value = USER_COMMIT_MESSAGE;
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
index 4998147c6b6..e4ffa37a84d 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
@@ -85,8 +85,6 @@ describe('Wip', () => {
expect(el.innerText).toContain(
"Merge blocked: merge request must be marked as ready. It's still marked as draft.",
);
- expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(el.querySelector('button').innerText).toContain('Merge');
expect(el.querySelector('.js-remove-draft').innerText.replace(/\s\s+/g, ' ')).toContain(
'Mark as ready',
);
diff --git a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
index b3af5eba364..8367dc6b716 100644
--- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
@@ -20,7 +20,6 @@ import {
import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants';
import eventHub from '~/vue_merge_request_widget/event_hub';
import MrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue';
-import { stateKey } from '~/vue_merge_request_widget/stores/state_maps';
import StatusIcon from '~/vue_merge_request_widget/components/extensions/status_icon.vue';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql';
import { faviconDataUrl, overlayDataUrl } from '../lib/utils/mock_data';
@@ -135,18 +134,6 @@ describe('MrWidgetOptions', () => {
});
});
- describe('shouldRenderRelatedLinks', () => {
- it('should return false for the initial data', () => {
- expect(wrapper.vm.shouldRenderRelatedLinks).toBeFalsy();
- });
-
- it('should return true if there is relatedLinks in MR', () => {
- Vue.set(wrapper.vm.mr, 'relatedLinks', {});
-
- expect(wrapper.vm.shouldRenderRelatedLinks).toBeTruthy();
- });
- });
-
describe('shouldRenderSourceBranchRemovalStatus', () => {
beforeEach(() => {
wrapper.vm.mr.state = 'readyToMerge';
@@ -519,61 +506,6 @@ describe('MrWidgetOptions', () => {
});
});
- describe('rendering relatedLinks', () => {
- beforeEach(() => {
- return createComponent({
- ...mockData,
- issues_links: {
- closing: `
- <a class="close-related-link" href="#">
- Close
- </a>
- `,
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders if there are relatedLinks', () => {
- expect(wrapper.find('.close-related-link').exists()).toBe(true);
- });
-
- it('does not render if state is nothingToMerge', async () => {
- wrapper.vm.mr.state = stateKey.nothingToMerge;
- await nextTick();
- expect(wrapper.find('.close-related-link').exists()).toBe(false);
- });
- });
-
- describe('rendering source branch removal status', () => {
- it('renders when user cannot remove branch and branch should be removed', async () => {
- wrapper.vm.mr.canRemoveSourceBranch = false;
- wrapper.vm.mr.shouldRemoveSourceBranch = true;
- wrapper.vm.mr.state = 'readyToMerge';
-
- await nextTick();
- const tooltip = wrapper.find('[data-testid="question-o-icon"]');
-
- expect(wrapper.text()).toContain('Deletes the source branch');
- expect(tooltip.attributes('title')).toBe(
- 'A user with write access to the source branch selected this option',
- );
- });
-
- it('does not render in merged state', async () => {
- wrapper.vm.mr.canRemoveSourceBranch = false;
- wrapper.vm.mr.shouldRemoveSourceBranch = true;
- wrapper.vm.mr.state = 'merged';
-
- await nextTick();
- expect(wrapper.text()).toContain('The source branch has been deleted');
- expect(wrapper.text()).not.toContain('Deletes the source branch');
- });
- });
-
describe('rendering deployments', () => {
const changes = [
{
@@ -1062,7 +994,7 @@ describe('MrWidgetOptions', () => {
await createComponent();
- expect(pollRequest).toHaveBeenCalledTimes(6);
+ expect(pollRequest).toHaveBeenCalledTimes(4);
});
});
@@ -1100,14 +1032,14 @@ describe('MrWidgetOptions', () => {
registerExtension(pollingErrorExtension);
await createComponent();
- expect(pollRequest).toHaveBeenCalledTimes(6);
+ expect(pollRequest).toHaveBeenCalledTimes(4);
});
it('captures sentry error and displays error when poll has failed', async () => {
registerExtension(pollingErrorExtension);
await createComponent();
- expect(Sentry.captureException).toHaveBeenCalledTimes(5);
+ expect(Sentry.captureException).toHaveBeenCalled();
expect(Sentry.captureException).toHaveBeenCalledWith(new Error('Fetch error'));
expect(wrapper.findComponent(StatusIcon).props('iconName')).toBe('failed');
});
@@ -1126,7 +1058,7 @@ describe('MrWidgetOptions', () => {
expect(
wrapper.find('[data-testid="widget-extension"] [data-testid="toggle-button"]').exists(),
).toBe(false);
- expect(Sentry.captureException).toHaveBeenCalledTimes(5);
+ expect(Sentry.captureException).toHaveBeenCalled();
expect(Sentry.captureException).toHaveBeenCalledWith(new Error('Fetch error'));
expect(wrapper.findComponent(StatusIcon).props('iconName')).toBe('failed');
});
diff --git a/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js b/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js
index fc760f5c5be..0246a8d4b0f 100644
--- a/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js
+++ b/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js
@@ -25,10 +25,6 @@ describe('getStateKey', () => {
expect(bound()).toEqual('readyToMerge');
- context.canMerge = false;
-
- expect(bound()).toEqual('notAllowedToMerge');
-
context.autoMergeEnabled = true;
context.hasMergeableDiscussionsState = true;
@@ -105,22 +101,4 @@ describe('getStateKey', () => {
expect(bound()).toEqual('rebase');
});
-
- it.each`
- canMerge | isSHAMismatch | stateKey
- ${true} | ${true} | ${'shaMismatch'}
- ${false} | ${true} | ${'notAllowedToMerge'}
- ${false} | ${false} | ${'notAllowedToMerge'}
- `(
- 'returns $stateKey when canMerge is $canMerge and isSHAMismatch is $isSHAMismatch',
- ({ canMerge, isSHAMismatch, stateKey }) => {
- const bound = getStateKey.bind({
- canMerge,
- isSHAMismatch,
- commitsCount: 2,
- });
-
- expect(bound()).toEqual(stateKey);
- },
- );
});
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 31a5bc737ba..8577cad1011 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -153,11 +153,6 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures do
end
it 'logs' do
- allow(Gitlab::AppJsonLogger).to receive(:info).with(
- hash_including(
- "class" => "AuthorizedProjectUpdate::ProjectRecalculatePerUserWorker"
- )
- )
expect(Gitlab::AppJsonLogger).to receive(:info).with(
message: 'Actor was :ci',
project_id: project.id
@@ -751,11 +746,6 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures do
it 'logs' do
expect(Gitlab::AppJsonLogger).to receive(:info).with(
- hash_including(
- "class" => "AuthorizedProjectUpdate::ProjectRecalculatePerUserWorker"
- )
- ).once
- expect(Gitlab::AppJsonLogger).to receive(:info).with(
message: 'Actor was :ci',
project_id: project.id
).once
diff --git a/spec/lib/gitlab/memory/reports_daemon_spec.rb b/spec/lib/gitlab/memory/reports_daemon_spec.rb
index feac5e2bfb2..75334834c5b 100644
--- a/spec/lib/gitlab/memory/reports_daemon_spec.rb
+++ b/spec/lib/gitlab/memory/reports_daemon_spec.rb
@@ -36,14 +36,14 @@ RSpec.describe Gitlab::Memory::ReportsDaemon do
message: 'finished',
pid: Process.pid,
worker_id: 'worker_1',
- report: 'jemalloc_stats'
+ perf_report: 'jemalloc_stats'
)).twice
daemon.send(:run_thread)
end
it 'sets real time duration gauge' do
- expect(report_duration_counter).to receive(:increment).with({ report: 'jemalloc_stats' }, an_instance_of(Integer))
+ expect(report_duration_counter).to receive(:increment).with({ report: 'jemalloc_stats' }, an_instance_of(Float))
daemon.send(:run_thread)
end
diff --git a/spec/serializers/issue_entity_spec.rb b/spec/serializers/issue_entity_spec.rb
index 6b9c703c627..9335ca61b7d 100644
--- a/spec/serializers/issue_entity_spec.rb
+++ b/spec/serializers/issue_entity_spec.rb
@@ -39,6 +39,13 @@ RSpec.describe IssueEntity do
expect(subject).to include(:time_estimate, :total_time_spent, :human_time_estimate, :human_total_time_spent)
end
+ describe 'current_user' do
+ it 'has the exprected permissions' do
+ expect(subject[:current_user]).to include(:can_create_note, :can_update, :can_set_issue_metadata,
+ :can_award_emoji)
+ end
+ end
+
context 'when issue got moved' do
let(:public_project) { create(:project, :public) }
let(:member) { create(:user) }
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 2316575f164..5daaa1d39cb 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -129,6 +129,12 @@ module Ci
let!(:build2_project2) { create(:ci_build, :pending, :queued, pipeline: pipeline2) }
let!(:build1_project3) { create(:ci_build, :pending, :queued, pipeline: pipeline3) }
+ it 'picks builds one-by-one' do
+ expect(Ci::Build).to receive(:find).with(pending_job.id).and_call_original
+
+ expect(execute(shared_runner)).to eq(build1_project1)
+ end
+
context 'when using fair scheduling' do
context 'when all builds are pending' do
it 'prefers projects without builds first' do
@@ -739,16 +745,6 @@ module Ci
end
end
- context 'when a long queue is created' do
- it 'picks builds one-by-one' do
- expect(Ci::Build).to receive(:find).with(pending_job.id).and_call_original
-
- expect(execute(specific_runner)).to eq(pending_job)
- end
-
- include_examples 'handles runner assignment'
- end
-
context 'when using pending builds table' do
include_examples 'handles runner assignment'
diff --git a/spec/services/merge_requests/reload_diffs_service_spec.rb b/spec/services/merge_requests/reload_diffs_service_spec.rb
index 3d5b65207e6..ed89a02b570 100644
--- a/spec/services/merge_requests/reload_diffs_service_spec.rb
+++ b/spec/services/merge_requests/reload_diffs_service_spec.rb
@@ -34,7 +34,10 @@ RSpec.describe MergeRequests::ReloadDiffsService, :use_clean_rails_memory_store_
context 'cache clearing' do
it 'clears the cache for older diffs on the merge request' do
- expect_any_instance_of(Redis).to receive(:del).once.and_call_original
+ redis = instance_double(Redis)
+ expect(Gitlab::Redis::Cache).to receive(:with).and_yield(redis)
+
+ expect(redis).to receive(:del).once
expect(Rails.cache).to receive(:delete).once.and_call_original
subject.execute
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 47cd78873f8..921d6503099 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -208,6 +208,7 @@ RSpec.configure do |config|
include StubFeatureFlags
include StubSnowplow
+ include StubMember
if ENV['CI'] || ENV['RETRIES']
# This includes the first try, i.e. tests will be run 4 times before failing.
diff --git a/spec/support/helpers/stub_member.rb b/spec/support/helpers/stub_member.rb
new file mode 100644
index 00000000000..b8fb7bce234
--- /dev/null
+++ b/spec/support/helpers/stub_member.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module StubMember
+ def self.included(base)
+ GroupMember.prepend(StubbedMember::GroupMember)
+ ProjectMember.prepend(StubbedMember::ProjectMember)
+ end
+end
diff --git a/spec/support/helpers/stubbed_member.rb b/spec/support/helpers/stubbed_member.rb
new file mode 100644
index 00000000000..bf700229656
--- /dev/null
+++ b/spec/support/helpers/stubbed_member.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+# Extend the ProjectMember & GroupMember class with the ability to
+# to run project_authorizations refresh jobs inline.
+
+# This is needed so that calls like `group.add_member(user)` or `create(:project_member)`
+# in the specs can be run without including `:sidekiq_inline` trait.
+module StubbedMember
+ extend ActiveSupport::Concern
+
+ module ClearDeduplicationData
+ private
+
+ def clear_deduplication_data!
+ Gitlab::Redis::Queues.with do |redis|
+ redis.scan_each(match: '*duplicate*').each do |key|
+ redis.del(key)
+ end
+ end
+ end
+ end
+
+ module GroupMember
+ include ClearDeduplicationData
+
+ private
+
+ def refresh_member_authorized_projects(blocking:)
+ return super unless blocking
+
+ # First, we remove all the keys associated with deduplication from Redis.
+ # We can't perform a full flush with `Gitlab::Redis::Queues.with(&:flushdb)`
+ # because that is going to remove other, unrelated enqueued jobs as well,
+ # and that is going to fail some specs.
+ clear_deduplication_data!
+
+ # then we run `super`, which will enqueue a project authorizations refresh job
+ super
+
+ # then we drain (run) the jobs that were enqueued, but only for the worker class we are interested in.
+ AuthorizedProjectsWorker.drain
+ ensure
+ clear_deduplication_data!
+ end
+ end
+
+ module ProjectMember
+ include ClearDeduplicationData
+
+ private
+
+ def refresh_member_authorized_projects(blocking:)
+ return super unless blocking
+
+ clear_deduplication_data!
+
+ super
+
+ AuthorizedProjectUpdate::ProjectRecalculatePerUserWorker.drain
+ ensure
+ clear_deduplication_data!
+ end
+ end
+end
diff --git a/spec/workers/concerns/waitable_worker_spec.rb b/spec/workers/concerns/waitable_worker_spec.rb
index f6d4cc4679d..bf156c3b8cb 100644
--- a/spec/workers/concerns/waitable_worker_spec.rb
+++ b/spec/workers/concerns/waitable_worker_spec.rb
@@ -30,19 +30,33 @@ RSpec.describe WaitableWorker do
describe '.bulk_perform_and_wait' do
context '1 job' do
- it 'inlines the job' do
- args_list = [[1]]
- expect(worker).to receive(:bulk_perform_inline).with(args_list).and_call_original
- expect(Gitlab::AppJsonLogger).to(
- receive(:info).with(a_hash_including('message' => 'running inline',
- 'class' => 'Gitlab::Foo::Bar::DummyWorker',
- 'job_status' => 'running',
- 'queue' => 'foo_bar_dummy'))
- .once)
-
- worker.bulk_perform_and_wait(args_list)
-
- expect(worker.counter).to eq(1)
+ it 'runs the jobs asynchronously' do
+ arguments = [[1]]
+
+ expect(worker).to receive(:bulk_perform_async).with(arguments)
+
+ worker.bulk_perform_and_wait(arguments)
+ end
+
+ context 'when the feature flag `always_async_project_authorizations_refresh` is turned off' do
+ before do
+ stub_feature_flags(always_async_project_authorizations_refresh: false)
+ end
+
+ it 'inlines the job' do
+ args_list = [[1]]
+ expect(worker).to receive(:bulk_perform_inline).with(args_list).and_call_original
+ expect(Gitlab::AppJsonLogger).to(
+ receive(:info).with(a_hash_including('message' => 'running inline',
+ 'class' => 'Gitlab::Foo::Bar::DummyWorker',
+ 'job_status' => 'running',
+ 'queue' => 'foo_bar_dummy'))
+ .once)
+
+ worker.bulk_perform_and_wait(args_list)
+
+ expect(worker.counter).to eq(1)
+ end
end
end