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
a062e45a
Commit
a062e45a
authored
Oct 22, 2021
by
Mireya Andres
Committed by
Frédéric Caplette
Oct 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Show linked pipelines mini graph in the pipeline editor
parent
53dbde8b
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
225 additions
and
4 deletions
+225
-4
app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue
...eline_editor/components/header/pipeline_editor_header.vue
+1
-0
app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_mini_graph.vue
...e_editor/components/header/pipeline_editor_mini_graph.vue
+52
-0
app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
...pts/pipeline_editor/components/header/pipeline_status.vue
+3
-1
app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_messages.vue
...ipeline_editor/components/ui/pipeline_editor_messages.vue
+7
-0
app/assets/javascripts/pipeline_editor/constants.js
app/assets/javascripts/pipeline_editor/constants.js
+1
-0
app/assets/javascripts/pipeline_editor/index.js
app/assets/javascripts/pipeline_editor/index.js
+1
-0
app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
...sets/javascripts/pipeline_editor/pipeline_editor_home.vue
+1
-0
locale/gitlab.pot
locale/gitlab.pot
+6
-0
spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
...ditor/components/header/pipline_editor_mini_graph_spec.js
+95
-3
spec/frontend/pipeline_editor/components/ui/pipeline_editor_messages_spec.js
...ine_editor/components/ui/pipeline_editor_messages_spec.js
+2
-0
spec/frontend/pipeline_editor/mock_data.js
spec/frontend/pipeline_editor/mock_data.js
+56
-0
No files found.
app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_header.vue
View file @
a062e45a
...
...
@@ -63,6 +63,7 @@ export default {
v-if=
"showPipelineStatus"
:commit-sha=
"commitSha"
:class=
"$options.pipelineStatusClasses"
v-on=
"$listeners"
/>
<validation-segment
:class=
"validationStyling"
:ci-config=
"ciConfigData"
/>
</div>
...
...
app/assets/javascripts/pipeline_editor/components/header/pipeline_editor_mini_graph.vue
View file @
a062e45a
<
script
>
import
{
__
}
from
'
~/locale
'
;
import
PipelineMiniGraph
from
'
~/pipelines/components/pipelines_list/pipeline_mini_graph.vue
'
;
import
getLinkedPipelinesQuery
from
'
~/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
'
;
import
{
PIPELINE_FAILURE
}
from
'
../../constants
'
;
export
default
{
i18n
:
{
linkedPipelinesFetchError
:
__
(
'
Unable to fetch upstream and downstream pipelines.
'
),
},
components
:
{
PipelineMiniGraph
,
LinkedPipelinesMiniList
:
()
=>
import
(
'
ee_component/vue_shared/components/linked_pipelines_mini_list.vue
'
),
},
inject
:
[
'
projectFullPath
'
],
props
:
{
pipeline
:
{
type
:
Object
,
required
:
true
,
},
},
apollo
:
{
linkedPipelines
:
{
query
:
getLinkedPipelinesQuery
,
variables
()
{
return
{
fullPath
:
this
.
projectFullPath
,
iid
:
this
.
pipeline
.
iid
,
};
},
skip
()
{
return
!
this
.
pipeline
.
iid
;
},
update
({
project
})
{
return
project
?.
pipeline
;
},
error
()
{
this
.
$emit
(
'
showError
'
,
{
type
:
PIPELINE_FAILURE
,
reasons
:
[
this
.
$options
.
i18n
.
linkedPipelinesFetchError
],
});
},
},
},
computed
:
{
downstreamPipelines
()
{
return
this
.
linkedPipelines
?.
downstream
?.
nodes
||
[];
},
pipelinePath
()
{
return
this
.
pipeline
.
detailedStatus
?.
detailsPath
||
''
;
},
...
...
@@ -38,12 +73,29 @@ export default {
};
});
},
showDownstreamPipelines
()
{
return
this
.
downstreamPipelines
.
length
>
0
;
},
upstreamPipeline
()
{
return
this
.
linkedPipelines
?.
upstream
;
},
},
};
</
script
>
<
template
>
<div
v-if=
"pipelineStages.length > 0"
class=
"stage-cell gl-mr-5"
>
<linked-pipelines-mini-list
v-if=
"upstreamPipeline"
:triggered-by=
"[upstreamPipeline]"
data-testid=
"pipeline-editor-mini-graph-upstream"
/>
<pipeline-mini-graph
class=
"gl-display-inline"
:stages=
"pipelineStages"
/>
<linked-pipelines-mini-list
v-if=
"showDownstreamPipelines"
:triggered=
"downstreamPipelines"
:pipeline-path=
"pipelinePath"
data-testid=
"pipeline-editor-mini-graph-downstream"
/>
</div>
</
template
>
app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
View file @
a062e45a
...
...
@@ -59,11 +59,12 @@ export default {
};
},
update
(
data
)
{
const
{
id
,
commitPath
=
''
,
detailedStatus
=
{},
stages
,
status
}
=
const
{
id
,
iid
,
commitPath
=
''
,
detailedStatus
=
{},
stages
,
status
}
=
data
.
project
?.
pipeline
||
{};
return
{
id
,
iid
,
commitPath
,
detailedStatus
,
stages
,
...
...
@@ -159,6 +160,7 @@ export default {
<pipeline-editor-mini-graph
v-if=
"glFeatures.pipelineEditorMiniGraph"
:pipeline=
"pipeline"
v-on=
"$listeners"
/>
<gl-button
class=
"gl-mt-2 gl-md-mt-0"
...
...
app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_messages.vue
View file @
a062e45a
...
...
@@ -8,6 +8,7 @@ import {
DEFAULT_FAILURE
,
DEFAULT_SUCCESS
,
LOAD_FAILURE_UNKNOWN
,
PIPELINE_FAILURE
,
}
from
'
../../constants
'
;
import
CodeSnippetAlert
from
'
../code_snippet_alert/code_snippet_alert.vue
'
;
import
{
...
...
@@ -24,6 +25,7 @@ export default {
[
COMMIT_FAILURE
]:
s__
(
'
Pipelines|The GitLab CI configuration could not be updated.
'
),
[
DEFAULT_FAILURE
]:
__
(
'
Something went wrong on our end.
'
),
[
LOAD_FAILURE_UNKNOWN
]:
s__
(
'
Pipelines|The CI configuration was not loaded, please try again.
'
),
[
PIPELINE_FAILURE
]:
s__
(
'
Pipelines|There was a problem with loading the pipeline data.
'
),
},
successTexts
:
{
[
COMMIT_SUCCESS
]:
__
(
'
Your changes have been successfully committed.
'
),
...
...
@@ -74,6 +76,11 @@ export default {
text
:
this
.
$options
.
errorTexts
[
COMMIT_FAILURE
],
variant
:
'
danger
'
,
};
case
PIPELINE_FAILURE
:
return
{
text
:
this
.
$options
.
errorTexts
[
PIPELINE_FAILURE
],
variant
:
'
danger
'
,
};
default
:
return
{
text
:
this
.
$options
.
errorTexts
[
DEFAULT_FAILURE
],
...
...
app/assets/javascripts/pipeline_editor/constants.js
View file @
a062e45a
...
...
@@ -16,6 +16,7 @@ export const COMMIT_SUCCESS = 'COMMIT_SUCCESS';
export
const
DEFAULT_FAILURE
=
'
DEFAULT_FAILURE
'
;
export
const
DEFAULT_SUCCESS
=
'
DEFAULT_SUCCESS
'
;
export
const
LOAD_FAILURE_UNKNOWN
=
'
LOAD_FAILURE_UNKNOWN
'
;
export
const
PIPELINE_FAILURE
=
'
PIPELINE_FAILURE
'
;
export
const
CREATE_TAB
=
'
CREATE_TAB
'
;
export
const
LINT_TAB
=
'
LINT_TAB
'
;
...
...
app/assets/javascripts/pipeline_editor/index.js
View file @
a062e45a
...
...
@@ -93,6 +93,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
ciExamplesHelpPagePath
,
ciHelpPagePath
,
configurationPaths
,
dataMethod
:
'
graphql
'
,
defaultBranch
,
emptyStateIllustrationPath
,
helpPaths
,
...
...
app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
View file @
a062e45a
...
...
@@ -58,6 +58,7 @@ export default {
:ci-config-data=
"ciConfigData"
:commit-sha=
"commitSha"
:is-new-ci-config-file=
"isNewCiConfigFile"
v-on=
"$listeners"
/>
<pipeline-editor-tabs
:ci-config-data=
"ciConfigData"
...
...
locale/gitlab.pot
View file @
a062e45a
...
...
@@ -25249,6 +25249,9 @@ msgstr ""
msgid "Pipelines|There are currently no pipelines."
msgstr ""
msgid "Pipelines|There was a problem with loading the pipeline data."
msgstr ""
msgid "Pipelines|There was an error fetching the pipelines. Try again in a few moments or contact your support team."
msgstr ""
...
...
@@ -36292,6 +36295,9 @@ msgstr ""
msgid "Unable to fetch branches list, please close the form and try again"
msgstr ""
msgid "Unable to fetch upstream and downstream pipelines."
msgstr ""
msgid "Unable to fetch vulnerable projects"
msgstr ""
...
...
spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
View file @
a062e45a
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
PipelineEditorMiniGraph
from
'
~/pipeline_editor/components/header/pipeline_editor_mini_graph.vue
'
;
import
PipelineMiniGraph
from
'
~/pipelines/components/pipelines_list/pipeline_mini_graph.vue
'
;
import
{
mockProjectPipeline
}
from
'
../../mock_data
'
;
import
getLinkedPipelinesQuery
from
'
~/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
'
;
import
{
PIPELINE_FAILURE
}
from
'
~/pipeline_editor/constants
'
;
import
{
mockLinkedPipelines
,
mockProjectFullPath
,
mockProjectPipeline
}
from
'
../../mock_data
'
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
VueApollo
);
describe
(
'
Pipeline Status
'
,
()
=>
{
let
wrapper
;
let
mockApollo
;
let
mockLinkedPipelinesQuery
;
const
createComponent
=
({
hasStages
=
true
}
=
{})
=>
{
const
createComponent
=
({
hasStages
=
true
,
options
}
=
{})
=>
{
wrapper
=
shallowMount
(
PipelineEditorMiniGraph
,
{
provide
:
{
dataMethod
:
'
graphql
'
,
projectFullPath
:
mockProjectFullPath
,
},
propsData
:
{
pipeline
:
mockProjectPipeline
({
hasStages
}).
pipeline
,
},
...
options
,
});
};
const
createComponentWithApollo
=
(
hasStages
=
true
)
=>
{
const
handlers
=
[[
getLinkedPipelinesQuery
,
mockLinkedPipelinesQuery
]];
mockApollo
=
createMockApollo
(
handlers
);
createComponent
({
hasStages
,
options
:
{
localVue
,
apolloProvider
:
mockApollo
,
},
});
};
const
findPipelineMiniGraph
=
()
=>
wrapper
.
findComponent
(
PipelineMiniGraph
);
const
findUpstream
=
()
=>
wrapper
.
find
(
'
[data-testid="pipeline-editor-mini-graph-upstream"]
'
);
const
findDownstream
=
()
=>
wrapper
.
find
(
'
[data-testid="pipeline-editor-mini-graph-downstream"]
'
);
beforeEach
(()
=>
{
mockLinkedPipelinesQuery
=
jest
.
fn
();
});
afterEach
(()
=>
{
mockLinkedPipelinesQuery
.
mockReset
();
wrapper
.
destroy
();
});
...
...
@@ -39,4 +75,60 @@ describe('Pipeline Status', () => {
expect
(
findPipelineMiniGraph
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when querying upstream and downstream pipelines
'
,
()
=>
{
describe
(
'
when query succeeds
'
,
()
=>
{
beforeEach
(()
=>
{
mockLinkedPipelinesQuery
.
mockResolvedValue
(
mockLinkedPipelines
());
createComponentWithApollo
();
});
it
(
'
should call the query with the correct variables
'
,
()
=>
{
expect
(
mockLinkedPipelinesQuery
).
toHaveBeenCalledTimes
(
1
);
expect
(
mockLinkedPipelinesQuery
).
toHaveBeenCalledWith
({
fullPath
:
mockProjectFullPath
,
iid
:
mockProjectPipeline
().
pipeline
.
iid
,
});
});
describe
(
'
linked pipeline rendering based on given data
'
,
()
=>
{
it
.
each
`
hasDownstream | hasUpstream | downstreamRenderAction | upstreamRenderAction
${
true
}
|
${
true
}
|
${
'
renders
'
}
|
${
'
renders
'
}
${
true
}
|
${
false
}
|
${
'
renders
'
}
|
${
'
hides
'
}
${
false
}
|
${
true
}
|
${
'
hides
'
}
|
${
'
renders
'
}
${
false
}
|
${
false
}
|
${
'
hides
'
}
|
${
'
hides
'
}
`
(
'
$downstreamRenderAction downstream and $upstreamRenderAction upstream
'
,
async
({
hasDownstream
,
hasUpstream
})
=>
{
mockLinkedPipelinesQuery
.
mockResolvedValue
(
mockLinkedPipelines
({
hasDownstream
,
hasUpstream
}),
);
createComponentWithApollo
();
await
waitForPromises
();
expect
(
findUpstream
().
exists
()).
toBe
(
hasUpstream
);
expect
(
findDownstream
().
exists
()).
toBe
(
hasDownstream
);
},
);
});
});
describe
(
'
when query fails
'
,
()
=>
{
beforeEach
(()
=>
{
mockLinkedPipelinesQuery
.
mockRejectedValue
(
new
Error
());
createComponentWithApollo
();
});
it
(
'
should emit an error event when query fails
'
,
async
()
=>
{
expect
(
wrapper
.
emitted
(
'
showError
'
)).
toHaveLength
(
1
);
expect
(
wrapper
.
emitted
(
'
showError
'
)[
0
]).
toEqual
([
{
type
:
PIPELINE_FAILURE
,
reasons
:
[
wrapper
.
vm
.
$options
.
i18n
.
linkedPipelinesFetchError
],
},
]);
});
});
});
});
spec/frontend/pipeline_editor/components/ui/pipeline_editor_messages_spec.js
View file @
a062e45a
...
...
@@ -11,6 +11,7 @@ import {
DEFAULT_FAILURE
,
DEFAULT_SUCCESS
,
LOAD_FAILURE_UNKNOWN
,
PIPELINE_FAILURE
,
}
from
'
~/pipeline_editor/constants
'
;
beforeEach
(()
=>
{
...
...
@@ -65,6 +66,7 @@ describe('Pipeline Editor messages', () => {
failureType | message | expectedFailureType
${
COMMIT_FAILURE
}
|
${
'
failed commit
'
}
|
${
COMMIT_FAILURE
}
${
LOAD_FAILURE_UNKNOWN
}
|
${
'
loading failure
'
}
|
${
LOAD_FAILURE_UNKNOWN
}
${
PIPELINE_FAILURE
}
|
${
'
pipeline failure
'
}
|
${
PIPELINE_FAILURE
}
${
'
random
'
}
|
${
'
error without a specified type
'
}
|
${
DEFAULT_FAILURE
}
`
(
'
shows a message for $message
'
,
({
failureType
,
expectedFailureType
})
=>
{
createComponent
({
failureType
,
showFailure
:
true
});
...
...
spec/frontend/pipeline_editor/mock_data.js
View file @
a062e45a
...
...
@@ -290,6 +290,62 @@ export const mockProjectPipeline = ({ hasStages = true } = {}) => {
};
};
export
const
mockLinkedPipelines
=
({
hasDownstream
=
true
,
hasUpstream
=
true
}
=
{})
=>
{
let
upstream
=
null
;
let
downstream
=
{
nodes
:
[],
__typename
:
'
PipelineConnection
'
,
};
if
(
hasDownstream
)
{
downstream
=
{
nodes
:
[
{
id
:
'
gid://gitlab/Ci::Pipeline/612
'
,
path
:
'
/root/job-log-sections/-/pipelines/612
'
,
project
:
{
name
:
'
job-log-sections
'
,
__typename
:
'
Project
'
},
detailedStatus
:
{
group
:
'
success
'
,
icon
:
'
status_success
'
,
label
:
'
passed
'
,
__typename
:
'
DetailedStatus
'
,
},
__typename
:
'
Pipeline
'
,
},
],
__typename
:
'
PipelineConnection
'
,
};
}
if
(
hasUpstream
)
{
upstream
=
{
id
:
'
gid://gitlab/Ci::Pipeline/610
'
,
path
:
'
/root/trigger-downstream/-/pipelines/610
'
,
project
:
{
name
:
'
trigger-downstream
'
,
__typename
:
'
Project
'
},
detailedStatus
:
{
group
:
'
success
'
,
icon
:
'
status_success
'
,
label
:
'
passed
'
,
__typename
:
'
DetailedStatus
'
,
},
__typename
:
'
Pipeline
'
,
};
}
return
{
data
:
{
project
:
{
pipeline
:
{
path
:
'
/root/ci-project/-/pipelines/790
'
,
downstream
,
upstream
,
},
__typename
:
'
Project
'
,
},
},
};
};
export
const
mockLintResponse
=
{
valid
:
true
,
mergedYaml
:
mockCiYml
,
...
...
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