Commit b69ade5d authored by Robert Speicher's avatar Robert Speicher

Merge branch '43557-osw-present-merge-sha-commit' into 'master'

Resolve "Display merge commit SHA in merge widget after merge"

Closes #43557

See merge request gitlab-org/gitlab-ce!18722
parents 4ac42e48 3063225c
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import loadingIcon from '~/vue_shared/components/loading_icon.vue'; import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import mrWidgetAuthorTime from '../../components/mr_widget_author_time.vue'; import mrWidgetAuthorTime from '../../components/mr_widget_author_time.vue';
import statusIcon from '../mr_widget_status_icon.vue'; import statusIcon from '../mr_widget_status_icon.vue';
import eventHub from '../../event_hub'; import eventHub from '../../event_hub';
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
mrWidgetAuthorTime, mrWidgetAuthorTime,
loadingIcon, loadingIcon,
statusIcon, statusIcon,
ClipboardButton,
}, },
props: { props: {
mr: { mr: {
...@@ -162,6 +164,18 @@ ...@@ -162,6 +164,18 @@
<span class="label-branch"> <span class="label-branch">
<a :href="mr.targetBranchPath">{{ mr.targetBranch }}</a> <a :href="mr.targetBranchPath">{{ mr.targetBranch }}</a>
</span> </span>
with
<a
:href="mr.mergeCommitPath"
class="commit-sha js-mr-merged-commit-sha"
>
{{ mr.shortMergeCommitSha }}
</a>
<clipboard-button
:title="__('Copy commit SHA to clipboard')"
:text="mr.shortMergeCommitSha"
css-class="btn-default btn-transparent btn-clipboard js-mr-merged-copy-sha"
/>
</p> </p>
<p v-if="mr.sourceBranchRemoved"> <p v-if="mr.sourceBranchRemoved">
{{ s__("mrWidget|The source branch has been removed") }} {{ s__("mrWidget|The source branch has been removed") }}
......
...@@ -20,6 +20,7 @@ export default class MergeRequestStore { ...@@ -20,6 +20,7 @@ export default class MergeRequestStore {
this.sourceBranch = data.source_branch; this.sourceBranch = data.source_branch;
this.mergeStatus = data.merge_status; this.mergeStatus = data.merge_status;
this.commitMessage = data.merge_commit_message; this.commitMessage = data.merge_commit_message;
this.shortMergeCommitSha = data.short_merge_commit_sha;
this.commitMessageWithDescription = data.merge_commit_message_with_description; this.commitMessageWithDescription = data.merge_commit_message_with_description;
this.commitsCount = data.commits_count; this.commitsCount = data.commits_count;
this.divergedCommitsCount = data.diverged_commits_count; this.divergedCommitsCount = data.diverged_commits_count;
...@@ -65,6 +66,7 @@ export default class MergeRequestStore { ...@@ -65,6 +66,7 @@ export default class MergeRequestStore {
this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path; this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path;
this.mergeCheckPath = data.merge_check_path; this.mergeCheckPath = data.merge_check_path;
this.mergeActionsContentPath = data.commit_change_content_path; this.mergeActionsContentPath = data.commit_change_content_path;
this.mergeCommitPath = data.merge_commit_path;
this.isRemovingSourceBranch = this.isRemovingSourceBranch || false; this.isRemovingSourceBranch = this.isRemovingSourceBranch || false;
this.isOpen = data.state === 'opened'; this.isOpen = data.state === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false; this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
......
...@@ -1007,6 +1007,10 @@ class MergeRequest < ActiveRecord::Base ...@@ -1007,6 +1007,10 @@ class MergeRequest < ActiveRecord::Base
@merge_commit ||= project.commit(merge_commit_sha) if merge_commit_sha @merge_commit ||= project.commit(merge_commit_sha) if merge_commit_sha
end end
def short_merge_commit_sha
Commit.truncate_sha(merge_commit_sha) if merge_commit_sha
end
def can_be_reverted?(current_user) def can_be_reverted?(current_user)
return false unless merge_commit return false unless merge_commit
......
...@@ -2,6 +2,7 @@ class MergeRequestWidgetEntity < IssuableEntity ...@@ -2,6 +2,7 @@ class MergeRequestWidgetEntity < IssuableEntity
expose :state expose :state
expose :in_progress_merge_commit_sha expose :in_progress_merge_commit_sha
expose :merge_commit_sha expose :merge_commit_sha
expose :short_merge_commit_sha
expose :merge_error expose :merge_error
expose :merge_params expose :merge_params
expose :merge_status expose :merge_status
...@@ -207,6 +208,12 @@ class MergeRequestWidgetEntity < IssuableEntity ...@@ -207,6 +208,12 @@ class MergeRequestWidgetEntity < IssuableEntity
commit_change_content_project_merge_request_path(merge_request.project, merge_request) commit_change_content_project_merge_request_path(merge_request.project, merge_request)
end end
expose :merge_commit_path do |merge_request|
if merge_request.merge_commit_sha
project_commit_path(merge_request.project, merge_request.merge_commit_sha)
end
end
private private
delegate :current_user, to: :request delegate :current_user, to: :request
......
---
title: Display merge commit SHA in merge widget after merge
merge_request: 18722
author:
type: added
...@@ -10,6 +10,15 @@ describe 'User accepts a merge request', :js do ...@@ -10,6 +10,15 @@ describe 'User accepts a merge request', :js do
sign_in(user) sign_in(user)
end end
it 'presents merged merge request content' do
visit(merge_request_path(merge_request))
click_button('Merge')
expect(page).to have_content("The changes were merged into #{merge_request.target_branch} with \
#{merge_request.short_merge_commit_sha}")
end
context 'with removing the source branch' do context 'with removing the source branch' do
before do before do
visit(merge_request_path(merge_request)) visit(merge_request_path(merge_request))
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
"in_progress_merge_commit_sha": { "type": ["string", "null"] }, "in_progress_merge_commit_sha": { "type": ["string", "null"] },
"merge_error": { "type": ["string", "null"] }, "merge_error": { "type": ["string", "null"] },
"merge_commit_sha": { "type": ["string", "null"] }, "merge_commit_sha": { "type": ["string", "null"] },
"short_merge_commit_sha": { "type": ["string", "null"] },
"merge_params": { "type": ["object", "null"] }, "merge_params": { "type": ["object", "null"] },
"merge_status": { "type": "string" }, "merge_status": { "type": "string" },
"merge_user_id": { "type": ["integer", "null"] }, "merge_user_id": { "type": ["integer", "null"] },
...@@ -100,6 +101,7 @@ ...@@ -100,6 +101,7 @@
"merge_commit_message_with_description": { "type": "string" }, "merge_commit_message_with_description": { "type": "string" },
"diverged_commits_count": { "type": "integer" }, "diverged_commits_count": { "type": "integer" },
"commit_change_content_path": { "type": "string" }, "commit_change_content_path": { "type": "string" },
"merge_commit_path": { "type": ["string", "null"] },
"remove_wip_path": { "type": ["string", "null"] }, "remove_wip_path": { "type": ["string", "null"] },
"commits_count": { "type": "integer" }, "commits_count": { "type": "integer" },
"remove_source_branch": { "type": ["boolean", "null"] }, "remove_source_branch": { "type": ["boolean", "null"] },
......
...@@ -6,6 +6,14 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper'; ...@@ -6,6 +6,14 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('MRWidgetMerged', () => { describe('MRWidgetMerged', () => {
let vm; let vm;
const targetBranch = 'foo'; 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(() => { beforeEach(() => {
const Component = Vue.extend(mergedComponent); const Component = Vue.extend(mergedComponent);
...@@ -31,6 +39,9 @@ describe('MRWidgetMerged', () => { ...@@ -31,6 +39,9 @@ describe('MRWidgetMerged', () => {
readableClosedAt: '', readableClosedAt: '',
}, },
updatedAt: 'mergedUpdatedAt', updatedAt: 'mergedUpdatedAt',
shortMergeCommitSha: 'asdf1234',
mergeCommitPath: 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d',
sourceBranch: 'bar',
targetBranch, targetBranch,
}; };
...@@ -140,6 +151,17 @@ describe('MRWidgetMerged', () => { ...@@ -140,6 +151,17 @@ describe('MRWidgetMerged', () => {
expect(vm.$el.textContent).toContain('Cherry-pick'); expect(vm.$el.textContent).toContain('Cherry-pick');
}); });
it('shows button to copy commit SHA to clipboard', () => {
expect(selectors.copyMergeShaButton).toExist();
expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(vm.mr.shortMergeCommitSha);
});
it('shows merge commit SHA link', () => {
expect(selectors.mergeCommitShaLink).toExist();
expect(selectors.mergeCommitShaLink.text).toContain(vm.mr.shortMergeCommitSha);
expect(selectors.mergeCommitShaLink.href).toBe(vm.mr.mergeCommitPath);
});
it('should not show source branch removed text', (done) => { it('should not show source branch removed text', (done) => {
vm.mr.sourceBranchRemoved = false; vm.mr.sourceBranchRemoved = false;
......
...@@ -18,6 +18,7 @@ export default { ...@@ -18,6 +18,7 @@ export default {
human_total_time_spent: null, human_total_time_spent: null,
in_progress_merge_commit_sha: null, in_progress_merge_commit_sha: null,
merge_commit_sha: '53027d060246c8f47e4a9310fb332aa52f221775', merge_commit_sha: '53027d060246c8f47e4a9310fb332aa52f221775',
short_merge_commit_sha: '53027d06',
merge_error: null, merge_error: null,
merge_params: { merge_params: {
force_remove_source_branch: null, force_remove_source_branch: null,
...@@ -215,4 +216,5 @@ export default { ...@@ -215,4 +216,5 @@ export default {
diverged_commits_count: 0, diverged_commits_count: 0,
only_allow_merge_if_pipeline_succeeds: false, only_allow_merge_if_pipeline_succeeds: false,
commit_change_content_path: '/root/acets-app/merge_requests/22/commit_change_content', commit_change_content_path: '/root/acets-app/merge_requests/22/commit_change_content',
merge_commit_path: 'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775',
}; };
...@@ -1069,6 +1069,22 @@ describe MergeRequest do ...@@ -1069,6 +1069,22 @@ describe MergeRequest do
end end
end end
describe '#short_merge_commit_sha' do
let(:merge_request) { build_stubbed(:merge_request) }
it 'returns short id when there is a merge_commit_sha' do
merge_request.merge_commit_sha = 'f7ce827c314c9340b075657fd61c789fb01cf74d'
expect(merge_request.short_merge_commit_sha).to eq('f7ce827c')
end
it 'returns nil when there is no merge_commit_sha' do
merge_request.merge_commit_sha = nil
expect(merge_request.short_merge_commit_sha).to be_nil
end
end
describe '#can_be_reverted?' do describe '#can_be_reverted?' do
context 'when there is no merge_commit for the MR' do context 'when there is no merge_commit for the MR' do
before do before do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment