2018-03-05 22:24:16 +00:00
|
|
|
<script>
|
2020-10-22 12:08:41 +00:00
|
|
|
import {
|
|
|
|
GlIcon,
|
|
|
|
GlButton,
|
|
|
|
GlButtonGroup,
|
|
|
|
GlDropdown,
|
|
|
|
GlDropdownItem,
|
2021-03-08 00:09:10 +00:00
|
|
|
GlFormCheckbox,
|
2020-10-22 12:08:41 +00:00
|
|
|
GlSprintf,
|
|
|
|
GlLink,
|
|
|
|
GlTooltipDirective,
|
2021-01-04 18:10:11 +00:00
|
|
|
GlSkeletonLoader,
|
2020-10-22 12:08:41 +00:00
|
|
|
} from '@gitlab/ui';
|
2021-02-14 18:09:20 +00:00
|
|
|
import { isEmpty } from 'lodash';
|
2019-12-06 21:07:54 +00:00
|
|
|
import readyToMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/ready_to_merge';
|
2021-01-04 18:10:11 +00:00
|
|
|
import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql';
|
2021-02-14 18:09:20 +00:00
|
|
|
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
|
2021-03-22 15:09:31 +00:00
|
|
|
import createFlash from '~/flash';
|
2017-05-09 04:15:34 +00:00
|
|
|
import simplePoll from '~/lib/utils/simple_poll';
|
2020-09-23 15:10:14 +00:00
|
|
|
import { __ } from '~/locale';
|
2021-01-04 18:10:11 +00:00
|
|
|
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
2021-02-01 15:08:56 +00:00
|
|
|
import MergeRequest from '../../../merge_request';
|
2021-02-14 18:09:20 +00:00
|
|
|
import { AUTO_MERGE_STRATEGIES, DANGER, INFO, WARNING } from '../../constants';
|
|
|
|
import eventHub from '../../event_hub';
|
2021-01-04 18:10:11 +00:00
|
|
|
import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
|
|
|
|
import MergeRequestStore from '../../stores/mr_widget_store';
|
2018-01-24 16:54:06 +00:00
|
|
|
import statusIcon from '../mr_widget_status_icon.vue';
|
2019-02-07 15:14:56 +00:00
|
|
|
import CommitEdit from './commit_edit.vue';
|
|
|
|
import CommitMessageDropdown from './commit_message_dropdown.vue';
|
2021-02-14 18:09:20 +00:00
|
|
|
import CommitsHeader from './commits_header.vue';
|
|
|
|
import SquashBeforeMerge from './squash_before_merge.vue';
|
2020-08-13 12:09:50 +00:00
|
|
|
|
|
|
|
const PIPELINE_RUNNING_STATE = 'running';
|
|
|
|
const PIPELINE_FAILED_STATE = 'failed';
|
|
|
|
const PIPELINE_PENDING_STATE = 'pending';
|
|
|
|
const PIPELINE_SUCCESS_STATE = 'success';
|
|
|
|
|
|
|
|
const MERGE_FAILED_STATUS = 'failed';
|
|
|
|
const MERGE_SUCCESS_STATUS = 'success';
|
|
|
|
const MERGE_HOOK_VALIDATION_ERROR_STATUS = 'hook_validation_error';
|
2017-05-09 04:15:34 +00:00
|
|
|
|
|
|
|
export default {
|
2018-03-05 22:24:16 +00:00
|
|
|
name: 'ReadyToMerge',
|
2021-01-04 18:10:11 +00:00
|
|
|
apollo: {
|
|
|
|
state: {
|
|
|
|
query: readyToMergeQuery,
|
|
|
|
skip() {
|
|
|
|
return !this.glFeatures.mergeRequestWidgetGraphql;
|
|
|
|
},
|
|
|
|
variables() {
|
|
|
|
return this.mergeRequestQueryVariables;
|
|
|
|
},
|
|
|
|
manual: true,
|
|
|
|
result({ data }) {
|
|
|
|
this.state = {
|
|
|
|
...data.project.mergeRequest,
|
2021-02-04 12:09:25 +00:00
|
|
|
mergeRequestsFfOnlyEnabled: data.project.mergeRequestsFfOnlyEnabled,
|
|
|
|
onlyAllowMergeIfPipelineSucceeds: data.project.onlyAllowMergeIfPipelineSucceeds,
|
2021-01-04 18:10:11 +00:00
|
|
|
};
|
2021-02-11 15:09:11 +00:00
|
|
|
this.removeSourceBranch =
|
|
|
|
data.project.mergeRequest.shouldRemoveSourceBranch ||
|
|
|
|
data.project.mergeRequest.forceRemoveSourceBranch ||
|
|
|
|
false;
|
2021-01-04 18:10:11 +00:00
|
|
|
this.commitMessage = data.project.mergeRequest.defaultMergeCommitMessage;
|
|
|
|
this.squashBeforeMerge = data.project.mergeRequest.squashOnMerge;
|
|
|
|
this.isSquashReadOnly = data.project.squashReadOnly;
|
|
|
|
this.squashCommitMessage = data.project.mergeRequest.defaultSquashCommitMessage;
|
|
|
|
this.loading = false;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2018-03-05 22:24:16 +00:00
|
|
|
components: {
|
|
|
|
statusIcon,
|
2019-01-15 09:11:34 +00:00
|
|
|
SquashBeforeMerge,
|
2019-02-07 15:14:56 +00:00
|
|
|
CommitsHeader,
|
|
|
|
CommitEdit,
|
|
|
|
CommitMessageDropdown,
|
2019-12-06 12:06:21 +00:00
|
|
|
GlIcon,
|
2020-05-07 15:09:29 +00:00
|
|
|
GlSprintf,
|
|
|
|
GlLink,
|
2020-08-21 00:10:44 +00:00
|
|
|
GlButton,
|
2020-10-22 12:08:41 +00:00
|
|
|
GlButtonGroup,
|
|
|
|
GlDropdown,
|
|
|
|
GlDropdownItem,
|
2021-03-08 00:09:10 +00:00
|
|
|
GlFormCheckbox,
|
2021-01-04 18:10:11 +00:00
|
|
|
GlSkeletonLoader,
|
2020-08-13 12:09:50 +00:00
|
|
|
MergeTrainHelperText: () =>
|
|
|
|
import('ee_component/vue_merge_request_widget/components/merge_train_helper_text.vue'),
|
2019-12-06 21:07:54 +00:00
|
|
|
MergeImmediatelyConfirmationDialog: () =>
|
|
|
|
import(
|
|
|
|
'ee_component/vue_merge_request_widget/components/merge_immediately_confirmation_dialog.vue'
|
|
|
|
),
|
2018-03-05 22:24:16 +00:00
|
|
|
},
|
2020-10-22 12:08:41 +00:00
|
|
|
directives: {
|
|
|
|
GlTooltip: GlTooltipDirective,
|
|
|
|
},
|
2021-01-04 18:10:11 +00:00
|
|
|
mixins: [readyToMergeMixin, glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
|
2017-05-09 04:15:34 +00:00
|
|
|
props: {
|
|
|
|
mr: { type: Object, required: true },
|
|
|
|
service: { type: Object, required: true },
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
2021-01-04 18:10:11 +00:00
|
|
|
loading: this.glFeatures.mergeRequestWidgetGraphql,
|
|
|
|
state: {},
|
2017-05-19 17:33:03 +00:00
|
|
|
removeSourceBranch: this.mr.shouldRemoveSourceBranch,
|
2017-05-09 04:15:34 +00:00
|
|
|
isMakingRequest: false,
|
|
|
|
isMergingImmediately: false,
|
|
|
|
commitMessage: this.mr.commitMessage,
|
2020-07-07 00:08:58 +00:00
|
|
|
squashBeforeMerge: this.mr.squashIsSelected,
|
|
|
|
isSquashReadOnly: this.mr.squashIsReadonly,
|
2019-02-07 15:14:56 +00:00
|
|
|
squashCommitMessage: this.mr.squashCommitMessage,
|
2017-05-09 04:15:34 +00:00
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
2021-01-04 18:10:11 +00:00
|
|
|
stateData() {
|
|
|
|
return this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr;
|
|
|
|
},
|
|
|
|
hasCI() {
|
|
|
|
return this.stateData.hasCI || this.stateData.hasCi;
|
|
|
|
},
|
2019-06-11 14:19:22 +00:00
|
|
|
isAutoMergeAvailable() {
|
2021-01-04 18:10:11 +00:00
|
|
|
return !isEmpty(this.stateData.availableAutoMergeStrategies);
|
|
|
|
},
|
|
|
|
pipeline() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
2021-03-25 06:09:02 +00:00
|
|
|
return this.state.headPipeline;
|
2021-01-04 18:10:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.pipeline;
|
|
|
|
},
|
|
|
|
isPipelineFailed() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return ['FAILED', 'CANCELED'].indexOf(this.pipeline?.status) !== -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.isPipelineFailed;
|
|
|
|
},
|
|
|
|
isMergeAllowed() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.state.mergeable || false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.isMergeAllowed;
|
|
|
|
},
|
|
|
|
canRemoveSourceBranch() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.state.userPermissions.removeSourceBranch;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.canRemoveSourceBranch;
|
|
|
|
},
|
|
|
|
commits() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.state.commitsWithoutMergeCommits.nodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.commits;
|
|
|
|
},
|
|
|
|
commitsCount() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.state.commitCount || 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.commitsCount;
|
|
|
|
},
|
|
|
|
preferredAutoMergeStrategy() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return MergeRequestStore.getPreferredAutoMergeStrategy(
|
|
|
|
this.state.availableAutoMergeStrategies,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.preferredAutoMergeStrategy;
|
|
|
|
},
|
|
|
|
isSHAMismatch() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.mr.sha !== this.state.diffHeadSha;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.isSHAMismatch;
|
|
|
|
},
|
|
|
|
squashIsSelected() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.squashReadOnly ? this.state.squashOnMerge : this.state.squash;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.squashIsSelected;
|
|
|
|
},
|
|
|
|
isPipelineActive() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return this.pipeline?.active || false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.mr.isPipelineActive;
|
2017-09-01 00:46:18 +00:00
|
|
|
},
|
2017-09-11 11:47:33 +00:00
|
|
|
status() {
|
2021-01-04 18:10:11 +00:00
|
|
|
const ciStatus = this.glFeatures.mergeRequestWidgetGraphql
|
|
|
|
? this.pipeline?.status.toLowerCase()
|
|
|
|
: this.mr.ciStatus;
|
2017-05-09 04:15:34 +00:00
|
|
|
|
2021-01-04 18:10:11 +00:00
|
|
|
if ((this.hasCI && !ciStatus) || this.hasPipelineMustSucceedConflict) {
|
2020-08-13 12:09:50 +00:00
|
|
|
return PIPELINE_FAILED_STATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isAutoMergeAvailable) {
|
|
|
|
return PIPELINE_PENDING_STATE;
|
|
|
|
}
|
|
|
|
|
2021-01-04 18:10:11 +00:00
|
|
|
if (this.pipeline && this.isPipelineFailed) {
|
2020-08-13 12:09:50 +00:00
|
|
|
return PIPELINE_FAILED_STATE;
|
2017-09-11 11:47:33 +00:00
|
|
|
}
|
|
|
|
|
2020-08-13 12:09:50 +00:00
|
|
|
return PIPELINE_SUCCESS_STATE;
|
2017-09-11 11:47:33 +00:00
|
|
|
},
|
2020-02-26 09:08:47 +00:00
|
|
|
mergeButtonVariant() {
|
2020-08-13 12:09:50 +00:00
|
|
|
if (this.status === PIPELINE_FAILED_STATE) {
|
|
|
|
return DANGER;
|
2017-05-09 04:15:34 +00:00
|
|
|
}
|
2020-08-13 12:09:50 +00:00
|
|
|
|
|
|
|
if (this.status === PIPELINE_PENDING_STATE) {
|
|
|
|
return INFO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PIPELINE_SUCCESS_STATE;
|
2017-05-09 04:15:34 +00:00
|
|
|
},
|
2017-09-11 11:47:33 +00:00
|
|
|
iconClass() {
|
2020-08-13 12:09:50 +00:00
|
|
|
if (this.shouldRenderMergeTrainHelperText && !this.mr.preventMerge) {
|
|
|
|
return PIPELINE_RUNNING_STATE;
|
|
|
|
}
|
|
|
|
|
2018-10-30 20:28:31 +00:00
|
|
|
if (
|
2020-08-13 12:09:50 +00:00
|
|
|
this.status === PIPELINE_FAILED_STATE ||
|
2018-10-30 20:28:31 +00:00
|
|
|
!this.commitMessage.length ||
|
2021-01-04 18:10:11 +00:00
|
|
|
!this.isMergeAllowed ||
|
2018-10-30 20:28:31 +00:00
|
|
|
this.mr.preventMerge
|
|
|
|
) {
|
2020-08-13 12:09:50 +00:00
|
|
|
return WARNING;
|
2017-09-11 11:47:33 +00:00
|
|
|
}
|
2020-08-13 12:09:50 +00:00
|
|
|
|
|
|
|
return PIPELINE_SUCCESS_STATE;
|
2017-09-11 11:47:33 +00:00
|
|
|
},
|
2017-05-09 04:15:34 +00:00
|
|
|
mergeButtonText() {
|
|
|
|
if (this.isMergingImmediately) {
|
2019-02-07 15:14:56 +00:00
|
|
|
return __('Merge in progress');
|
2019-09-18 14:02:45 +00:00
|
|
|
}
|
|
|
|
if (this.isAutoMergeAvailable) {
|
2019-06-11 14:19:22 +00:00
|
|
|
return this.autoMergeText;
|
2017-05-09 04:15:34 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 14:19:22 +00:00
|
|
|
return __('Merge');
|
2017-05-09 04:15:34 +00:00
|
|
|
},
|
2020-05-07 15:09:29 +00:00
|
|
|
hasPipelineMustSucceedConflict() {
|
2021-01-04 18:10:11 +00:00
|
|
|
return !this.hasCI && this.stateData.onlyAllowMergeIfPipelineSucceeds;
|
2020-05-07 15:09:29 +00:00
|
|
|
},
|
2017-05-19 17:33:03 +00:00
|
|
|
isRemoveSourceBranchButtonDisabled() {
|
2018-03-08 13:33:59 +00:00
|
|
|
return this.isMergeButtonDisabled;
|
2017-05-19 17:33:03 +00:00
|
|
|
},
|
2017-05-09 04:15:34 +00:00
|
|
|
shouldShowSquashBeforeMerge() {
|
2021-01-04 18:10:11 +00:00
|
|
|
const { enableSquashBeforeMerge } = this.mr;
|
2020-07-07 00:08:58 +00:00
|
|
|
|
2021-01-04 18:10:11 +00:00
|
|
|
if (this.isSquashReadOnly && !this.squashIsSelected) {
|
2020-07-07 00:08:58 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-01-04 18:10:11 +00:00
|
|
|
return enableSquashBeforeMerge && this.commitsCount > 1;
|
2017-05-09 04:15:34 +00:00
|
|
|
},
|
2017-09-01 00:46:18 +00:00
|
|
|
shouldShowMergeControls() {
|
2021-01-04 18:10:11 +00:00
|
|
|
return this.isMergeAllowed || this.isAutoMergeAvailable;
|
2017-05-09 04:15:34 +00:00
|
|
|
},
|
2019-03-13 15:44:16 +00:00
|
|
|
shouldShowSquashEdit() {
|
|
|
|
return this.squashBeforeMerge && this.shouldShowSquashBeforeMerge;
|
|
|
|
},
|
|
|
|
shouldShowMergeEdit() {
|
2021-01-04 18:10:11 +00:00
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
return !this.state.mergeRequestsFfOnlyEnabled;
|
|
|
|
}
|
|
|
|
|
2019-03-13 15:44:16 +00:00
|
|
|
return !this.mr.ffOnlyEnabled;
|
|
|
|
},
|
2019-12-06 12:06:21 +00:00
|
|
|
shaMismatchLink() {
|
2020-09-23 15:10:14 +00:00
|
|
|
return this.mr.mergeRequestDiffsPath;
|
2019-12-06 12:06:21 +00:00
|
|
|
},
|
2019-02-07 15:14:56 +00:00
|
|
|
},
|
2021-02-04 12:09:25 +00:00
|
|
|
mounted() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
eventHub.$on('ApprovalUpdated', this.updateGraphqlState);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
beforeDestroy() {
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
eventHub.$off('ApprovalUpdated', this.updateGraphqlState);
|
|
|
|
}
|
|
|
|
},
|
2019-02-07 15:14:56 +00:00
|
|
|
methods: {
|
2021-02-04 12:09:25 +00:00
|
|
|
updateGraphqlState() {
|
|
|
|
return this.$apollo.queries.state.refetch();
|
|
|
|
},
|
2019-02-07 15:14:56 +00:00
|
|
|
updateMergeCommitMessage(includeDescription) {
|
2021-01-04 18:10:11 +00:00
|
|
|
const commitMessage = this.glFeatures.mergeRequestWidgetGraphql
|
|
|
|
? this.state.defaultMergeCommitMessage
|
|
|
|
: this.mr.commitMessage;
|
|
|
|
const commitMessageWithDescription = this.glFeatures.mergeRequestWidgetGraphql
|
|
|
|
? this.state.defaultMergeCommitMessageWithDescription
|
|
|
|
: this.mr.commitMessageWithDescription;
|
2019-02-07 15:14:56 +00:00
|
|
|
this.commitMessage = includeDescription ? commitMessageWithDescription : commitMessage;
|
2017-05-09 04:15:34 +00:00
|
|
|
},
|
2019-06-11 14:19:22 +00:00
|
|
|
handleMergeButtonClick(useAutoMerge, mergeImmediately = false) {
|
|
|
|
if (mergeImmediately) {
|
2017-05-09 04:15:34 +00:00
|
|
|
this.isMergingImmediately = true;
|
|
|
|
}
|
2021-01-04 18:10:11 +00:00
|
|
|
const latestSha = this.glFeatures.mergeRequestWidgetGraphql
|
|
|
|
? this.state.diffHeadSha
|
|
|
|
: this.mr.latestSHA;
|
2017-05-09 04:15:34 +00:00
|
|
|
|
|
|
|
const options = {
|
2021-01-04 18:10:11 +00:00
|
|
|
sha: latestSha || this.mr.sha,
|
2017-05-09 04:15:34 +00:00
|
|
|
commit_message: this.commitMessage,
|
2021-01-04 18:10:11 +00:00
|
|
|
auto_merge_strategy: useAutoMerge ? this.preferredAutoMergeStrategy : undefined,
|
2017-05-09 04:15:34 +00:00
|
|
|
should_remove_source_branch: this.removeSourceBranch === true,
|
2019-01-15 09:11:34 +00:00
|
|
|
squash: this.squashBeforeMerge,
|
2017-05-09 04:15:34 +00:00
|
|
|
};
|
|
|
|
|
2020-01-27 21:08:47 +00:00
|
|
|
// If users can't alter the squash message (e.g. for 1-commit merge requests),
|
|
|
|
// we shouldn't send the commit message because that would make the backend
|
|
|
|
// do unnecessary work.
|
|
|
|
if (this.shouldShowSquashBeforeMerge) {
|
|
|
|
options.squash_commit_message = this.squashCommitMessage;
|
|
|
|
}
|
|
|
|
|
2017-05-09 04:15:34 +00:00
|
|
|
this.isMakingRequest = true;
|
2018-10-30 20:28:31 +00:00
|
|
|
this.service
|
|
|
|
.merge(options)
|
2020-12-23 21:10:24 +00:00
|
|
|
.then((res) => res.data)
|
|
|
|
.then((data) => {
|
2020-08-13 12:09:50 +00:00
|
|
|
const hasError =
|
|
|
|
data.status === MERGE_FAILED_STATUS ||
|
|
|
|
data.status === MERGE_HOOK_VALIDATION_ERROR_STATUS;
|
2017-05-09 04:15:34 +00:00
|
|
|
|
2020-03-11 09:09:48 +00:00
|
|
|
if (AUTO_MERGE_STRATEGIES.includes(data.status)) {
|
2017-05-09 04:15:34 +00:00
|
|
|
eventHub.$emit('MRWidgetUpdateRequested');
|
2020-08-13 12:09:50 +00:00
|
|
|
} else if (data.status === MERGE_SUCCESS_STATUS) {
|
2017-05-09 04:15:34 +00:00
|
|
|
this.initiateMergePolling();
|
|
|
|
} else if (hasError) {
|
2017-12-15 06:11:00 +00:00
|
|
|
eventHub.$emit('FailedToMerge', data.merge_error);
|
2017-05-09 04:15:34 +00:00
|
|
|
}
|
2021-02-04 12:09:25 +00:00
|
|
|
|
|
|
|
if (this.glFeatures.mergeRequestWidgetGraphql) {
|
|
|
|
this.updateGraphqlState();
|
|
|
|
}
|
2017-05-09 04:15:34 +00:00
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
this.isMakingRequest = false;
|
2021-03-22 15:09:31 +00:00
|
|
|
createFlash({
|
|
|
|
message: __('Something went wrong. Please try again.'),
|
|
|
|
});
|
2017-05-09 04:15:34 +00:00
|
|
|
});
|
|
|
|
},
|
2019-12-06 21:07:54 +00:00
|
|
|
handleMergeImmediatelyButtonClick() {
|
|
|
|
if (this.isMergeImmediatelyDangerous) {
|
|
|
|
this.$refs.confirmationDialog.show();
|
|
|
|
} else {
|
|
|
|
this.handleMergeButtonClick(false, true);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onMergeImmediatelyConfirmation() {
|
|
|
|
this.handleMergeButtonClick(false, true);
|
|
|
|
},
|
2017-05-09 04:15:34 +00:00
|
|
|
initiateMergePolling() {
|
2019-03-11 20:18:36 +00:00
|
|
|
simplePoll(
|
|
|
|
(continuePolling, stopPolling) => {
|
|
|
|
this.handleMergePolling(continuePolling, stopPolling);
|
|
|
|
},
|
|
|
|
{ timeout: 0 },
|
|
|
|
);
|
2017-05-09 04:15:34 +00:00
|
|
|
},
|
|
|
|
handleMergePolling(continuePolling, stopPolling) {
|
2018-10-30 20:28:31 +00:00
|
|
|
this.service
|
|
|
|
.poll()
|
2020-12-23 21:10:24 +00:00
|
|
|
.then((res) => res.data)
|
|
|
|
.then((data) => {
|
2017-12-15 06:11:00 +00:00
|
|
|
if (data.state === 'merged') {
|
2017-05-09 04:15:34 +00:00
|
|
|
// If state is merged we should update the widget and stop the polling
|
|
|
|
eventHub.$emit('MRWidgetUpdateRequested');
|
|
|
|
eventHub.$emit('FetchActionsContent');
|
2018-01-17 14:09:59 +00:00
|
|
|
MergeRequest.setStatusBoxToMerged();
|
2018-01-15 17:06:38 +00:00
|
|
|
MergeRequest.hideCloseButton();
|
|
|
|
MergeRequest.decreaseCounter();
|
2017-05-09 04:15:34 +00:00
|
|
|
stopPolling();
|
|
|
|
|
2019-07-09 08:44:19 +00:00
|
|
|
refreshUserMergeRequestCounts();
|
|
|
|
|
2017-05-09 04:15:34 +00:00
|
|
|
// If user checked remove source branch and we didn't remove the branch yet
|
|
|
|
// we should start another polling for source branch remove process
|
2017-12-15 06:11:00 +00:00
|
|
|
if (this.removeSourceBranch && data.source_branch_exists) {
|
2017-05-09 04:15:34 +00:00
|
|
|
this.initiateRemoveSourceBranchPolling();
|
|
|
|
}
|
2017-12-15 06:11:00 +00:00
|
|
|
} else if (data.merge_error) {
|
|
|
|
eventHub.$emit('FailedToMerge', data.merge_error);
|
2017-05-09 04:15:34 +00:00
|
|
|
stopPolling();
|
|
|
|
} else {
|
|
|
|
// MR is not merged yet, continue polling until the state becomes 'merged'
|
|
|
|
continuePolling();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(() => {
|
2021-03-22 15:09:31 +00:00
|
|
|
createFlash({
|
|
|
|
message: __('Something went wrong while merging this merge request. Please try again.'),
|
|
|
|
});
|
2019-03-11 20:18:36 +00:00
|
|
|
stopPolling();
|
2017-05-09 04:15:34 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
initiateRemoveSourceBranchPolling() {
|
|
|
|
// We need to show source branch is being removed spinner in another component
|
|
|
|
eventHub.$emit('SetBranchRemoveFlag', [true]);
|
|
|
|
|
|
|
|
simplePoll((continuePolling, stopPolling) => {
|
|
|
|
this.handleRemoveBranchPolling(continuePolling, stopPolling);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
handleRemoveBranchPolling(continuePolling, stopPolling) {
|
2018-10-30 20:28:31 +00:00
|
|
|
this.service
|
|
|
|
.poll()
|
2020-12-23 21:10:24 +00:00
|
|
|
.then((res) => res.data)
|
|
|
|
.then((data) => {
|
2017-05-09 04:15:34 +00:00
|
|
|
// If source branch exists then we should continue polling
|
|
|
|
// because removing a source branch is a background task and takes time
|
2017-12-15 06:11:00 +00:00
|
|
|
if (data.source_branch_exists) {
|
2017-05-09 04:15:34 +00:00
|
|
|
continuePolling();
|
|
|
|
} else {
|
|
|
|
// Branch is removed. Update widget, stop polling and hide the spinner
|
|
|
|
eventHub.$emit('MRWidgetUpdateRequested', () => {
|
|
|
|
eventHub.$emit('SetBranchRemoveFlag', [false]);
|
|
|
|
});
|
|
|
|
stopPolling();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(() => {
|
2021-03-22 15:09:31 +00:00
|
|
|
createFlash({
|
|
|
|
message: __('Something went wrong while deleting the source branch. Please try again.'),
|
|
|
|
});
|
2017-05-09 04:15:34 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
2018-03-05 22:24:16 +00:00
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
2019-02-07 15:14:56 +00:00
|
|
|
<div>
|
2021-01-04 18:10:11 +00:00
|
|
|
<div v-if="loading" class="mr-widget-body">
|
|
|
|
<div class="gl-w-full mr-ready-to-merge-loader">
|
|
|
|
<gl-skeleton-loader :width="418" :height="30">
|
|
|
|
<rect x="0" y="3" width="24" height="24" rx="4" />
|
|
|
|
<rect x="32" y="0" width="70" height="30" rx="4" />
|
|
|
|
<rect x="110" y="7" width="150" height="16" rx="4" />
|
|
|
|
<rect x="268" y="7" width="150" height="16" rx="4" />
|
|
|
|
</gl-skeleton-loader>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<template v-else>
|
|
|
|
<div class="mr-widget-body media" :class="{ 'gl-pb-3': shouldRenderMergeTrainHelperText }">
|
|
|
|
<status-icon :status="iconClass" />
|
|
|
|
<div class="media-body">
|
2021-03-08 18:09:12 +00:00
|
|
|
<div class="mr-widget-body-controls gl-display-flex gl-align-items-center">
|
|
|
|
<gl-button-group class="gl-align-self-start">
|
2021-01-04 18:10:11 +00:00
|
|
|
<gl-button
|
|
|
|
size="medium"
|
|
|
|
category="primary"
|
2021-03-15 21:09:16 +00:00
|
|
|
class="accept-merge-request"
|
|
|
|
data-testid="merge-button"
|
2021-01-04 18:10:11 +00:00
|
|
|
:variant="mergeButtonVariant"
|
|
|
|
:disabled="isMergeButtonDisabled"
|
|
|
|
:loading="isMakingRequest"
|
2021-02-05 15:09:28 +00:00
|
|
|
data-qa-selector="merge_button"
|
2021-01-04 18:10:11 +00:00
|
|
|
@click="handleMergeButtonClick(isAutoMergeAvailable)"
|
|
|
|
>{{ mergeButtonText }}</gl-button
|
2020-10-22 12:08:41 +00:00
|
|
|
>
|
2021-01-04 18:10:11 +00:00
|
|
|
<gl-dropdown
|
|
|
|
v-if="shouldShowMergeImmediatelyDropdown"
|
|
|
|
v-gl-tooltip.hover.focus="__('Select merge moment')"
|
|
|
|
:disabled="isMergeButtonDisabled"
|
|
|
|
variant="info"
|
|
|
|
data-qa-selector="merge_moment_dropdown"
|
|
|
|
toggle-class="btn-icon js-merge-moment"
|
|
|
|
>
|
|
|
|
<template #button-content>
|
|
|
|
<gl-icon name="chevron-down" class="mr-0" />
|
|
|
|
<span class="sr-only">{{ __('Select merge moment') }}</span>
|
|
|
|
</template>
|
|
|
|
<gl-dropdown-item
|
|
|
|
icon-name="warning"
|
|
|
|
button-class="accept-merge-request js-merge-immediately-button"
|
2021-03-15 21:09:16 +00:00
|
|
|
data-qa-selector="merge_immediately_menu_item"
|
2021-01-04 18:10:11 +00:00
|
|
|
@click="handleMergeImmediatelyButtonClick"
|
|
|
|
>
|
|
|
|
{{ __('Merge immediately') }}
|
|
|
|
</gl-dropdown-item>
|
|
|
|
<merge-immediately-confirmation-dialog
|
|
|
|
ref="confirmationDialog"
|
|
|
|
:docs-url="mr.mergeImmediatelyDocsPath"
|
|
|
|
@mergeImmediately="onMergeImmediatelyConfirmation"
|
2019-02-07 15:14:56 +00:00
|
|
|
/>
|
2021-01-04 18:10:11 +00:00
|
|
|
</gl-dropdown>
|
|
|
|
</gl-button-group>
|
2021-03-08 18:09:12 +00:00
|
|
|
<div
|
|
|
|
v-if="shouldShowMergeControls"
|
|
|
|
class="gl-display-flex gl-align-items-center gl-flex-wrap"
|
|
|
|
>
|
|
|
|
<gl-form-checkbox
|
|
|
|
v-if="canRemoveSourceBranch"
|
|
|
|
id="remove-source-branch-input"
|
|
|
|
v-model="removeSourceBranch"
|
|
|
|
:disabled="isRemoveSourceBranchButtonDisabled"
|
|
|
|
class="js-remove-source-branch-checkbox gl-mx-3 gl-display-flex gl-align-items-center"
|
|
|
|
>
|
|
|
|
{{ __('Delete source branch') }}
|
|
|
|
</gl-form-checkbox>
|
|
|
|
|
|
|
|
<!-- Placeholder for EE extension of this component -->
|
|
|
|
<squash-before-merge
|
|
|
|
v-if="shouldShowSquashBeforeMerge"
|
|
|
|
v-model="squashBeforeMerge"
|
|
|
|
:help-path="mr.squashBeforeMergeHelpPath"
|
|
|
|
:is-disabled="isSquashReadOnly"
|
|
|
|
class="gl-mx-3"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<template v-else>
|
|
|
|
<div class="bold js-resolve-mr-widget-items-message gl-ml-3">
|
|
|
|
<div
|
|
|
|
v-if="hasPipelineMustSucceedConflict"
|
|
|
|
class="gl-display-flex gl-align-items-center"
|
|
|
|
data-testid="pipeline-succeed-conflict"
|
2021-03-08 00:09:10 +00:00
|
|
|
>
|
2021-03-08 18:09:12 +00:00
|
|
|
<gl-sprintf :message="pipelineMustSucceedConflictText" />
|
|
|
|
<gl-link
|
|
|
|
:href="mr.pipelineMustSucceedDocsPath"
|
|
|
|
target="_blank"
|
|
|
|
class="gl-display-flex gl-ml-2"
|
2020-07-08 00:09:06 +00:00
|
|
|
>
|
2021-03-08 18:09:12 +00:00
|
|
|
<gl-icon name="question" />
|
|
|
|
</gl-link>
|
2020-07-08 00:09:06 +00:00
|
|
|
</div>
|
2021-03-08 18:09:12 +00:00
|
|
|
<gl-sprintf v-else :message="mergeDisabledText" />
|
|
|
|
</div>
|
|
|
|
</template>
|
2021-01-04 18:10:11 +00:00
|
|
|
</div>
|
|
|
|
<div v-if="isSHAMismatch" class="d-flex align-items-center mt-2 js-sha-mismatch">
|
|
|
|
<gl-icon name="warning-solid" class="text-warning mr-1" />
|
|
|
|
<span class="text-warning">
|
|
|
|
<gl-sprintf
|
|
|
|
:message="
|
|
|
|
__('New changes were added. %{linkStart}Reload the page to review them%{linkEnd}')
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<template #link="{ content }">
|
|
|
|
<gl-link :href="mr.mergeRequestDiffsPath">{{ content }}</gl-link>
|
|
|
|
</template>
|
|
|
|
</gl-sprintf>
|
|
|
|
</span>
|
|
|
|
</div>
|
2019-12-06 12:06:21 +00:00
|
|
|
</div>
|
2017-08-07 02:29:37 +00:00
|
|
|
</div>
|
2021-01-04 18:10:11 +00:00
|
|
|
<merge-train-helper-text
|
|
|
|
v-if="shouldRenderMergeTrainHelperText"
|
2021-02-04 12:09:25 +00:00
|
|
|
:pipeline-id="pipelineId"
|
2021-01-04 18:10:11 +00:00
|
|
|
:pipeline-link="pipeline.path"
|
|
|
|
:merge-train-length="stateData.mergeTrainsCount"
|
|
|
|
:merge-train-when-pipeline-succeeds-docs-path="mr.mergeTrainWhenPipelineSucceedsDocsPath"
|
|
|
|
/>
|
|
|
|
<template v-if="shouldShowMergeControls">
|
2021-03-15 21:09:16 +00:00
|
|
|
<div
|
|
|
|
v-if="!shouldShowMergeEdit"
|
|
|
|
class="mr-fast-forward-message"
|
|
|
|
data-qa-selector="fast_forward_message_content"
|
|
|
|
>
|
2021-01-04 18:10:11 +00:00
|
|
|
{{ __('Fast-forward merge without a merge commit') }}
|
|
|
|
</div>
|
|
|
|
<commits-header
|
|
|
|
v-if="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"
|
2019-02-07 15:14:56 +00:00
|
|
|
v-model="squashCommitMessage"
|
2021-01-04 18:10:11 +00:00
|
|
|
:label="__('Squash commit message')"
|
|
|
|
input-id="squash-message-edit"
|
|
|
|
squash
|
|
|
|
>
|
|
|
|
<commit-message-dropdown
|
|
|
|
slot="header"
|
|
|
|
v-model="squashCommitMessage"
|
|
|
|
:commits="commits"
|
2019-02-07 15:14:56 +00:00
|
|
|
/>
|
2021-01-04 18:10:11 +00:00
|
|
|
</commit-edit>
|
|
|
|
<commit-edit
|
|
|
|
v-if="shouldShowMergeEdit"
|
|
|
|
v-model="commitMessage"
|
|
|
|
:label="__('Merge commit message')"
|
|
|
|
input-id="merge-message-edit"
|
|
|
|
>
|
|
|
|
<label slot="checkbox">
|
|
|
|
<input
|
|
|
|
id="include-description"
|
|
|
|
type="checkbox"
|
|
|
|
@change="updateMergeCommitMessage($event.target.checked)"
|
|
|
|
/>
|
|
|
|
{{ __('Include merge request description') }}
|
|
|
|
</label>
|
|
|
|
</commit-edit>
|
|
|
|
</ul>
|
|
|
|
</commits-header>
|
|
|
|
</template>
|
2019-02-07 15:14:56 +00:00
|
|
|
</template>
|
2018-03-05 22:24:16 +00:00
|
|
|
</div>
|
|
|
|
</template>
|