Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
2a960b9e
Commit
2a960b9e
authored
Mar 21, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
2a8a9d75
785b5f0f
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
313 additions
and
18 deletions
+313
-18
app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
...ue_merge_request_widget/components/mr_widget_pipeline.vue
+60
-10
app/models/ci/pipeline.rb
app/models/ci/pipeline.rb
+4
-0
app/models/merge_request.rb
app/models/merge_request.rb
+1
-1
changelogs/unreleased/nfriend-update-merge-request-widget-pipeline-block.yml
...ed/nfriend-update-merge-request-widget-pipeline-block.yml
+6
-0
spec/features/merge_request/user_sees_merge_widget_spec.rb
spec/features/merge_request/user_sees_merge_widget_spec.rb
+113
-0
spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
...ripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
+80
-3
spec/javascripts/vue_mr_widget/mock_data.js
spec/javascripts/vue_mr_widget/mock_data.js
+11
-0
spec/models/ci/pipeline_spec.rb
spec/models/ci/pipeline_spec.rb
+24
-0
spec/models/environment_status_spec.rb
spec/models/environment_status_spec.rb
+2
-2
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+12
-2
No files found.
app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
View file @
2a960b9e
<
script
>
/* eslint-disable vue/require-default-prop */
import
{
GlTooltipDirective
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
sprintf
,
__
}
from
'
~/locale
'
;
import
PipelineStage
from
'
~/pipelines/components/stage.vue
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
...
...
@@ -14,9 +15,13 @@ export default {
CiIcon
,
Icon
,
TooltipOnTruncate
,
GlLink
,
LinkedPipelinesMiniList
:
()
=>
import
(
'
ee_component/vue_shared/components/linked_pipelines_mini_list.vue
'
),
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
},
mixins
:
[
mrWidgetPipelineMixin
],
props
:
{
pipeline
:
{
...
...
@@ -78,11 +83,17 @@ export default {
false
,
);
},
isTriggeredByMergeRequest
()
{
return
Boolean
(
this
.
pipeline
.
merge_request
);
},
isMergeRequestPipeline
()
{
return
Boolean
(
this
.
pipeline
.
flags
&&
this
.
pipeline
.
flags
.
merge_request_pipeline
);
},
},
};
</
script
>
<
template
>
<div
v-if=
"hasPipeline || hasCIError"
class=
"ci-widget media"
>
<div
v-if=
"hasPipeline || hasCIError"
class=
"ci-widget media
js-ci-widget
"
>
<template
v-if=
"hasCIError"
>
<div
class=
"add-border ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-default"
...
...
@@ -98,21 +109,58 @@ export default {
<div
class=
"ci-widget-container d-flex"
>
<div
class=
"ci-widget-content"
>
<div
class=
"media-body"
>
<div
class=
"font-weight-bold"
>
Pipeline
<
a
:href=
"pipeline.path"
class=
"pipeline-id font-weight-normal pipeline-number"
>
#
{{
pipeline
.
id
}}
</
a
<div
class=
"font-weight-bold
js-pipeline-info-container
"
>
{{
s__
(
'
Pipeline|Pipeline
'
)
}}
<
gl-link
:href=
"pipeline.path"
class=
"pipeline-id font-weight-normal pipeline-number"
>
#
{{
pipeline
.
id
}}
</
gl-link
>
{{
pipeline
.
details
.
status
.
label
}}
<template
v-if=
"hasCommitInfo"
>
for
<
a
{{
s__
(
'
Pipeline|for
'
)
}}
<
gl-link
:href=
"pipeline.commit.commit_path"
class=
"commit-sha js-commit-link font-weight-normal"
>
{{
pipeline
.
commit
.
short_id
}}
</
a
>
{{
pipeline
.
commit
.
short_id
}}
</
gl-link
>
on
{{
s__
(
'
Pipeline|on
'
)
}}
<template
v-if=
"isTriggeredByMergeRequest"
>
<gl-link
v-gl-tooltip
:href=
"pipeline.merge_request.path"
:title=
"pipeline.merge_request.title"
class=
"font-weight-normal"
>
!
{{
pipeline
.
merge_request
.
iid
}}
</gl-link
>
{{
s__
(
'
Pipeline|with
'
)
}}
<tooltip-on-truncate
:title=
"pipeline.merge_request.source_branch"
truncate-target=
"child"
class=
"label-branch label-truncate"
>
<gl-link
:href=
"pipeline.merge_request.source_branch_path"
class=
"font-weight-normal"
>
{{
pipeline
.
merge_request
.
source_branch
}}
</gl-link
>
</tooltip-on-truncate>
<template
v-if=
"isMergeRequestPipeline"
>
{{
s__
(
'
Pipeline|into
'
)
}}
<tooltip-on-truncate
:title=
"pipeline.merge_request.target_branch"
truncate-target=
"child"
class=
"label-branch label-truncate"
>
<gl-link
:href=
"pipeline.merge_request.target_branch_path"
class=
"font-weight-normal"
>
{{
pipeline
.
merge_request
.
target_branch
}}
</gl-link
>
</tooltip-on-truncate>
</
template
>
</template>
<tooltip-on-truncate
v-else
:title=
"sourceBranch"
truncate-target=
"child"
class=
"label-branch label-truncate"
...
...
@@ -120,7 +168,9 @@ export default {
/>
</template>
</div>
<div
v-if=
"pipeline.coverage"
class=
"coverage"
>
Coverage {{ pipeline.coverage }}%
</div>
<div
v-if=
"pipeline.coverage"
class=
"coverage"
>
{{ s__('Pipeline|Coverage') }} {{ pipeline.coverage }}%
</div>
</div>
</div>
<div>
...
...
app/models/ci/pipeline.rb
View file @
2a960b9e
...
...
@@ -746,6 +746,10 @@ module Ci
triggered_by_merge_request?
&&
target_sha
==
merge_request
.
target_branch_sha
end
def
matches_sha_or_source_sha?
(
sha
)
self
.
sha
==
sha
||
self
.
source_sha
==
sha
end
private
def
ci_yaml_from_repo
...
...
app/models/merge_request.rb
View file @
2a960b9e
...
...
@@ -234,7 +234,7 @@ class MergeRequest < ActiveRecord::Base
# branch head commit, for example checking if a merge request can be merged.
# For more information check: https://gitlab.com/gitlab-org/gitlab-ce/issues/40004
def
actual_head_pipeline
head_pipeline
&
.
sha
==
diff_head_sha
?
head_pipeline
:
nil
head_pipeline
&
.
matches_sha_or_source_sha?
(
diff_head_sha
)
?
head_pipeline
:
nil
end
def
merge_pipeline
...
...
changelogs/unreleased/nfriend-update-merge-request-widget-pipeline-block.yml
0 → 100644
View file @
2a960b9e
---
title
:
Update pipeline block on merge request page to accommodate post-merge pipeline
information
merge_request
:
25745
author
:
type
:
added
spec/features/merge_request/user_sees_merge_widget_spec.rb
View file @
2a960b9e
...
...
@@ -145,6 +145,119 @@ describe 'Merge request > User sees merge widget', :js do
end
end
context
'when merge request has a branch pipeline as the head pipeline'
do
let!
(
:pipeline
)
do
create
(
:ci_pipeline
,
ref:
merge_request
.
source_branch
,
sha:
merge_request
.
source_branch_sha
,
project:
merge_request
.
source_project
)
end
before
do
merge_request
.
update_head_pipeline
visit
project_merge_request_path
(
project
,
merge_request
)
end
it
'shows head pipeline information'
do
within
'.ci-widget-content'
do
expect
(
page
).
to
have_content
(
"Pipeline #
#{
pipeline
.
id
}
pending "
\
"for
#{
pipeline
.
short_sha
}
"
\
"on
#{
pipeline
.
ref
}
"
)
end
end
end
context
'when merge request has a detached merge request pipeline as the head pipeline'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
:with_detached_merge_request_pipeline
,
source_project:
source_project
,
target_project:
target_project
)
end
let!
(
:pipeline
)
do
merge_request
.
all_pipelines
.
last
end
let
(
:source_project
)
{
project
}
let
(
:target_project
)
{
project
}
before
do
merge_request
.
update_head_pipeline
visit
project_merge_request_path
(
project
,
merge_request
)
end
it
'shows head pipeline information'
do
within
'.ci-widget-content'
do
expect
(
page
).
to
have_content
(
"Pipeline #
#{
pipeline
.
id
}
pending "
\
"for
#{
pipeline
.
short_sha
}
"
\
"on
#{
merge_request
.
to_reference
}
"
\
"with
#{
merge_request
.
source_branch
}
"
)
end
end
context
'when source project is a forked project'
do
let
(
:source_project
)
{
fork_project
(
project
,
user
,
repository:
true
)
}
it
'shows head pipeline information'
do
within
'.ci-widget-content'
do
expect
(
page
).
to
have_content
(
"Pipeline #
#{
pipeline
.
id
}
pending "
\
"for
#{
pipeline
.
short_sha
}
"
\
"on
#{
merge_request
.
to_reference
}
"
\
"with
#{
merge_request
.
source_branch
}
"
)
end
end
end
end
context
'when merge request has a merge request pipeline as the head pipeline'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
:with_merge_request_pipeline
,
source_project:
source_project
,
target_project:
target_project
,
merge_sha:
merge_sha
)
end
let!
(
:pipeline
)
do
merge_request
.
all_pipelines
.
last
end
let
(
:source_project
)
{
project
}
let
(
:target_project
)
{
project
}
let
(
:merge_sha
)
{
project
.
commit
.
sha
}
before
do
merge_request
.
update_head_pipeline
visit
project_merge_request_path
(
project
,
merge_request
)
end
it
'shows head pipeline information'
do
within
'.ci-widget-content'
do
expect
(
page
).
to
have_content
(
"Pipeline #
#{
pipeline
.
id
}
pending "
\
"for
#{
pipeline
.
short_sha
}
"
\
"on
#{
merge_request
.
to_reference
}
"
\
"with
#{
merge_request
.
source_branch
}
"
\
"into
#{
merge_request
.
target_branch
}
"
)
end
end
context
'when source project is a forked project'
do
let
(
:source_project
)
{
fork_project
(
project
,
user
,
repository:
true
)
}
let
(
:merge_sha
)
{
source_project
.
commit
.
sha
}
it
'shows head pipeline information'
do
within
'.ci-widget-content'
do
expect
(
page
).
to
have_content
(
"Pipeline #
#{
pipeline
.
id
}
pending "
\
"for
#{
pipeline
.
short_sha
}
"
\
"on
#{
merge_request
.
to_reference
}
"
\
"with
#{
merge_request
.
source_branch
}
"
\
"into
#{
merge_request
.
target_branch
}
"
)
end
end
end
end
context
'view merge request with MWBS button'
do
before
do
commit_status
=
create
(
:commit_status
,
project:
project
,
status:
'pending'
)
...
...
spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
View file @
2a960b9e
import
Vue
from
'
vue
'
;
import
pipelineComponent
from
'
~/vue_merge_request_widget/components/mr_widget_pipeline.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
trimText
}
from
'
spec/helpers/vue_component_helper
'
;
import
mockData
from
'
../mock_data
'
;
describe
(
'
MRWidgetPipeline
'
,
()
=>
{
...
...
@@ -123,7 +124,7 @@ describe('MRWidgetPipeline', () => {
describe
(
'
without commit path
'
,
()
=>
{
beforeEach
(()
=>
{
const
mockCopy
=
Object
.
assign
({},
mockData
);
const
mockCopy
=
JSON
.
parse
(
JSON
.
stringify
(
mockData
)
);
delete
mockCopy
.
pipeline
.
commit
;
vm
=
mountComponent
(
Component
,
{
...
...
@@ -164,7 +165,7 @@ describe('MRWidgetPipeline', () => {
describe
(
'
without coverage
'
,
()
=>
{
it
(
'
should not render a coverage
'
,
()
=>
{
const
mockCopy
=
Object
.
assign
({},
mockData
);
const
mockCopy
=
JSON
.
parse
(
JSON
.
stringify
(
mockData
)
);
delete
mockCopy
.
pipeline
.
coverage
;
vm
=
mountComponent
(
Component
,
{
...
...
@@ -180,7 +181,7 @@ describe('MRWidgetPipeline', () => {
describe
(
'
without a pipeline graph
'
,
()
=>
{
it
(
'
should not render a pipeline graph
'
,
()
=>
{
const
mockCopy
=
Object
.
assign
({},
mockData
);
const
mockCopy
=
JSON
.
parse
(
JSON
.
stringify
(
mockData
)
);
delete
mockCopy
.
pipeline
.
details
.
stages
;
vm
=
mountComponent
(
Component
,
{
...
...
@@ -193,5 +194,81 @@ describe('MRWidgetPipeline', () => {
expect
(
vm
.
$el
.
querySelector
(
'
.js-mini-pipeline-graph
'
)).
toEqual
(
null
);
});
});
describe
(
'
without pipeline.merge_request
'
,
()
=>
{
it
(
'
should render info that includes the commit and branch details
'
,
()
=>
{
const
mockCopy
=
JSON
.
parse
(
JSON
.
stringify
(
mockData
));
delete
mockCopy
.
pipeline
.
merge_request
;
const
{
pipeline
}
=
mockCopy
;
vm
=
mountComponent
(
Component
,
{
pipeline
,
hasCi
:
true
,
ciStatus
:
'
success
'
,
troubleshootingDocsPath
:
'
help
'
,
sourceBranchLink
:
mockCopy
.
source_branch_link
,
});
const
expected
=
`Pipeline #
${
pipeline
.
id
}
${
pipeline
.
details
.
status
.
label
}
for
${
pipeline
.
commit
.
short_id
}
on
${
mockCopy
.
source_branch_link
}
`
;
const
actual
=
trimText
(
vm
.
$el
.
querySelector
(
'
.js-pipeline-info-container
'
).
innerText
);
expect
(
actual
).
toBe
(
expected
);
});
});
describe
(
'
with pipeline.merge_request and flags.merge_request_pipeline
'
,
()
=>
{
it
(
'
should render info that includes the commit, MR, source branch, and target branch details
'
,
()
=>
{
const
mockCopy
=
JSON
.
parse
(
JSON
.
stringify
(
mockData
));
const
{
pipeline
}
=
mockCopy
;
pipeline
.
flags
.
merge_request_pipeline
=
true
;
pipeline
.
flags
.
detached_merge_request_pipeline
=
false
;
vm
=
mountComponent
(
Component
,
{
pipeline
,
hasCi
:
true
,
ciStatus
:
'
success
'
,
troubleshootingDocsPath
:
'
help
'
,
sourceBranchLink
:
mockCopy
.
source_branch_link
,
});
const
expected
=
`Pipeline #
${
pipeline
.
id
}
${
pipeline
.
details
.
status
.
label
}
for
${
pipeline
.
commit
.
short_id
}
on !
${
pipeline
.
merge_request
.
iid
}
with
${
pipeline
.
merge_request
.
source_branch
}
into
${
pipeline
.
merge_request
.
target_branch
}
`
;
const
actual
=
trimText
(
vm
.
$el
.
querySelector
(
'
.js-pipeline-info-container
'
).
innerText
);
expect
(
actual
).
toBe
(
expected
);
});
});
describe
(
'
with pipeline.merge_request and flags.detached_merge_request_pipeline
'
,
()
=>
{
it
(
'
should render info that includes the commit, MR, and source branch details
'
,
()
=>
{
const
mockCopy
=
JSON
.
parse
(
JSON
.
stringify
(
mockData
));
const
{
pipeline
}
=
mockCopy
;
pipeline
.
flags
.
merge_request_pipeline
=
false
;
pipeline
.
flags
.
detached_merge_request_pipeline
=
true
;
vm
=
mountComponent
(
Component
,
{
pipeline
,
hasCi
:
true
,
ciStatus
:
'
success
'
,
troubleshootingDocsPath
:
'
help
'
,
sourceBranchLink
:
mockCopy
.
source_branch_link
,
});
const
expected
=
`Pipeline #
${
pipeline
.
id
}
${
pipeline
.
details
.
status
.
label
}
for
${
pipeline
.
commit
.
short_id
}
on !
${
pipeline
.
merge_request
.
iid
}
with
${
pipeline
.
merge_request
.
source_branch
}
`
;
const
actual
=
trimText
(
vm
.
$el
.
querySelector
(
'
.js-pipeline-info-container
'
).
innerText
);
expect
(
actual
).
toBe
(
expected
);
});
});
});
});
spec/javascripts/vue_mr_widget/mock_data.js
View file @
2a960b9e
...
...
@@ -134,6 +134,8 @@ export default {
yaml_errors
:
false
,
retryable
:
true
,
cancelable
:
false
,
merge_request_pipeline
:
false
,
detached_merge_request_pipeline
:
true
,
},
ref
:
{
name
:
'
daaaa
'
,
...
...
@@ -141,6 +143,15 @@ export default {
tag
:
false
,
branch
:
true
,
},
merge_request
:
{
iid
:
1
,
path
:
'
/root/detached-merge-request-pipelines/merge_requests/1
'
,
title
:
'
Update README.md
'
,
source_branch
:
'
feature-1
'
,
source_branch_path
:
'
/root/detached-merge-request-pipelines/branches/feature-1
'
,
target_branch
:
'
master
'
,
target_branch_path
:
'
/root/detached-merge-request-pipelines/branches/master
'
,
},
commit
:
{
id
:
'
104096c51715e12e7ae41f9333e9fa35b73f385d
'
,
short_id
:
'
104096c5
'
,
...
...
spec/models/ci/pipeline_spec.rb
View file @
2a960b9e
...
...
@@ -366,6 +366,30 @@ describe Ci::Pipeline, :mailer do
end
end
describe
'#matches_sha_or_source_sha?'
do
subject
{
pipeline
.
matches_sha_or_source_sha?
(
sample_sha
)
}
let
(
:sample_sha
)
{
Digest
::
SHA1
.
hexdigest
(
SecureRandom
.
hex
)
}
context
'when sha matches'
do
let
(
:pipeline
)
{
build
(
:ci_pipeline
,
sha:
sample_sha
)
}
it
{
is_expected
.
to
be_truthy
}
end
context
'when source_sha matches'
do
let
(
:pipeline
)
{
build
(
:ci_pipeline
,
source_sha:
sample_sha
)
}
it
{
is_expected
.
to
be_truthy
}
end
context
'when both sha and source_sha do not matche'
do
let
(
:pipeline
)
{
build
(
:ci_pipeline
,
sha:
'test'
,
source_sha:
'test'
)
}
it
{
is_expected
.
to
be_falsy
}
end
end
describe
'.triggered_for_branch'
do
subject
{
described_class
.
triggered_for_branch
(
ref
)
}
...
...
spec/models/environment_status_spec.rb
View file @
2a960b9e
...
...
@@ -64,8 +64,8 @@ describe EnvironmentStatus do
end
describe
'.for_merge_request'
do
let
(
:admin
)
{
create
(
:admin
)
}
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
sha:
sha
)
}
let
(
:admin
)
{
create
(
:admin
)
}
let
!
(
:pipeline
)
{
create
(
:ci_pipeline
,
sha:
sha
,
merge_requests_as_head_pipeline:
[
merge_request
]
)
}
it
'is based on merge_request.diff_head_sha'
do
expect
(
merge_request
).
to
receive
(
:diff_head_sha
)
...
...
spec/models/merge_request_spec.rb
View file @
2a960b9e
...
...
@@ -1186,8 +1186,10 @@ describe MergeRequest do
end
context
'head pipeline'
do
let
(
:diff_head_sha
)
{
Digest
::
SHA1
.
hexdigest
(
SecureRandom
.
hex
)
}
before
do
allow
(
subject
).
to
receive
(
:diff_head_sha
).
and_return
(
'lastsha'
)
allow
(
subject
).
to
receive
(
:diff_head_sha
).
and_return
(
diff_head_sha
)
end
describe
'#head_pipeline'
do
...
...
@@ -1215,7 +1217,15 @@ describe MergeRequest do
end
it
'returns the pipeline for MR with recent pipeline'
do
pipeline
=
create
(
:ci_empty_pipeline
,
sha:
'lastsha'
)
pipeline
=
create
(
:ci_empty_pipeline
,
sha:
diff_head_sha
)
subject
.
update_attribute
(
:head_pipeline_id
,
pipeline
.
id
)
expect
(
subject
.
actual_head_pipeline
).
to
eq
(
subject
.
head_pipeline
)
expect
(
subject
.
actual_head_pipeline
).
to
eq
(
pipeline
)
end
it
'returns the pipeline for MR with recent merge request pipeline'
do
pipeline
=
create
(
:ci_empty_pipeline
,
sha:
'merge-sha'
,
source_sha:
diff_head_sha
)
subject
.
update_attribute
(
:head_pipeline_id
,
pipeline
.
id
)
expect
(
subject
.
actual_head_pipeline
).
to
eq
(
subject
.
head_pipeline
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment