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
fba1d515
Commit
fba1d515
authored
Mar 11, 2020
by
Jarka Košanová
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add health status data to the graphQL endpoint
- calculate epic health status based on issues
parent
0f758429
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
178 additions
and
6 deletions
+178
-6
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+25
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+69
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+11
-0
ee/app/graphql/types/epic_health_status_type.rb
ee/app/graphql/types/epic_health_status_type.rb
+14
-0
ee/app/graphql/types/epic_type.rb
ee/app/graphql/types/epic_type.rb
+6
-0
ee/app/models/ee/issue.rb
ee/app/models/ee/issue.rb
+1
-0
ee/app/services/epics/descendant_count_service.rb
ee/app/services/epics/descendant_count_service.rb
+18
-0
ee/changelogs/unreleased/199184-health-status-display.yml
ee/changelogs/unreleased/199184-health-status-display.yml
+5
-0
ee/spec/graphql/types/epic_type_spec.rb
ee/spec/graphql/types/epic_type_spec.rb
+1
-1
ee/spec/models/issue_spec.rb
ee/spec/models/issue_spec.rb
+10
-0
ee/spec/services/epics/descendant_count_service_spec.rb
ee/spec/services/epics/descendant_count_service_spec.rb
+18
-5
No files found.
doc/api/graphql/reference/gitlab_schema.graphql
View file @
fba1d515
...
@@ -2023,6 +2023,11 @@ type Epic implements Noteable {
...
@@ -2023,6 +2023,11 @@ type Epic implements Noteable {
"""
"""
hasIssues
:
Boolean
!
hasIssues
:
Boolean
!
"""
Current
health
status
of
the
epic
"""
healthStatus
:
EpicHealthStatus
"""
"""
ID
of
the
epic
ID
of
the
epic
"""
"""
...
@@ -2294,6 +2299,26 @@ type EpicEdge {
...
@@ -2294,6 +2299,26 @@ type EpicEdge {
node
:
Epic
node
:
Epic
}
}
"""
Health status of child issues
"""
type
EpicHealthStatus
{
"""
Number
of
issues
at
risk
"""
issuesAtRisk
:
Int
"""
Number
of
issues
that
need
attention
"""
issuesNeedingAttention
:
Int
"""
Number
of
issues
on
track
"""
issuesOnTrack
:
Int
}
"""
"""
Relationship between an epic and an issue
Relationship between an epic and an issue
"""
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
fba1d515
...
@@ -5186,6 +5186,20 @@
...
@@ -5186,6 +5186,20 @@
"isDeprecated"
:
false
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
"deprecationReason"
:
null
},
},
{
"name"
:
"healthStatus"
,
"description"
:
"Current health status of the epic"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"EpicHealthStatus"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
{
"name"
:
"id"
,
"name"
:
"id"
,
"description"
:
"ID of the epic"
,
"description"
:
"ID of the epic"
,
...
@@ -13084,6 +13098,61 @@
...
@@ -13084,6 +13098,61 @@
"enumValues"
:
null
,
"enumValues"
:
null
,
"possibleTypes"
:
null
"possibleTypes"
:
null
},
},
{
"kind"
:
"OBJECT"
,
"name"
:
"EpicHealthStatus"
,
"description"
:
"Health status of child issues"
,
"fields"
:
[
{
"name"
:
"issuesAtRisk"
,
"description"
:
"Number of issues at risk"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Int"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"issuesNeedingAttention"
,
"description"
:
"Number of issues that need attention"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Int"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"issuesOnTrack"
,
"description"
:
"Number of issues on track"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Int"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"inputFields"
:
null
,
"interfaces"
:
[
],
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
{
"kind"
:
"OBJECT"
,
"kind"
:
"OBJECT"
,
"name"
:
"TimelogConnection"
,
"name"
:
"TimelogConnection"
,
...
...
doc/api/graphql/reference/index.md
View file @
fba1d515
...
@@ -327,6 +327,7 @@ Represents an epic.
...
@@ -327,6 +327,7 @@ Represents an epic.
|
`group`
| Group! | Group to which the epic belongs |
|
`group`
| Group! | Group to which the epic belongs |
|
`hasChildren`
| Boolean! | Indicates if the epic has children |
|
`hasChildren`
| Boolean! | Indicates if the epic has children |
|
`hasIssues`
| Boolean! | Indicates if the epic has direct issues |
|
`hasIssues`
| Boolean! | Indicates if the epic has direct issues |
|
`healthStatus`
| EpicHealthStatus | Current health status of the epic |
|
`id`
| ID! | ID of the epic |
|
`id`
| ID! | ID of the epic |
|
`iid`
| ID! | Internal ID of the epic |
|
`iid`
| ID! | Internal ID of the epic |
|
`parent`
| Epic | Parent epic of the epic |
|
`parent`
| Epic | Parent epic of the epic |
...
@@ -366,6 +367,16 @@ Total weight of open and closed descendant issues
...
@@ -366,6 +367,16 @@ Total weight of open and closed descendant issues
|
`closedIssues`
| Int | Total weight of completed (closed) issues in this epic, including epic descendants |
|
`closedIssues`
| Int | Total weight of completed (closed) issues in this epic, including epic descendants |
|
`openedIssues`
| Int | Total weight of opened issues in this epic, including epic descendants |
|
`openedIssues`
| Int | Total weight of opened issues in this epic, including epic descendants |
## EpicHealthStatus
Health status of child issues
| Name | Type | Description |
| --- | ---- | ---------- |
|
`issuesAtRisk`
| Int | Number of issues at risk |
|
`issuesNeedingAttention`
| Int | Number of issues that need attention |
|
`issuesOnTrack`
| Int | Number of issues on track |
## EpicIssue
## EpicIssue
Relationship between an epic and an issue
Relationship between an epic and an issue
...
...
ee/app/graphql/types/epic_health_status_type.rb
0 → 100644
View file @
fba1d515
# frozen_string_literal: true
module
Types
# rubocop: disable Graphql/AuthorizeTypes
class
EpicHealthStatusType
<
BaseObject
graphql_name
'EpicHealthStatus'
description
'Health status of child issues'
field
:issues_on_track
,
GraphQL
::
INT_TYPE
,
null:
true
,
description:
'Number of issues on track'
field
:issues_needing_attention
,
GraphQL
::
INT_TYPE
,
null:
true
,
description:
'Number of issues that need attention'
field
:issues_at_risk
,
GraphQL
::
INT_TYPE
,
null:
true
,
description:
'Number of issues at risk'
end
# rubocop: enable Graphql/AuthorizeTypes
end
ee/app/graphql/types/epic_type.rb
View file @
fba1d515
...
@@ -138,5 +138,11 @@ module Types
...
@@ -138,5 +138,11 @@ module Types
resolve:
->
(
epic
,
args
,
ctx
)
do
resolve:
->
(
epic
,
args
,
ctx
)
do
Gitlab
::
Graphql
::
Aggregations
::
Epics
::
LazyEpicAggregate
.
new
(
ctx
,
epic
.
id
,
WEIGHT_SUM
)
Gitlab
::
Graphql
::
Aggregations
::
Epics
::
LazyEpicAggregate
.
new
(
ctx
,
epic
.
id
,
WEIGHT_SUM
)
end
end
field
:health_status
,
Types
::
EpicHealthStatusType
,
null:
true
,
complexity:
10
,
description:
'Current health status of the epic'
,
resolve:
->
(
epic
,
args
,
ctx
)
do
Epics
::
DescendantCountService
.
new
(
epic
,
ctx
[
:current_user
])
end
end
end
end
end
ee/app/models/ee/issue.rb
View file @
fba1d515
...
@@ -26,6 +26,7 @@ module EE
...
@@ -26,6 +26,7 @@ module EE
issue_ids
=
EpicIssue
.
where
(
epic_id:
epics
).
select
(
:issue_id
)
issue_ids
=
EpicIssue
.
where
(
epic_id:
epics
).
select
(
:issue_id
)
id_in
(
issue_ids
)
id_in
(
issue_ids
)
end
end
scope
:counts_by_health_status
,
->
{
reorder
(
nil
).
group
(
:health_status
).
count
}
has_one
:epic_issue
has_one
:epic_issue
has_one
:epic
,
through: :epic_issue
has_one
:epic
,
through: :epic_issue
...
...
ee/app/services/epics/descendant_count_service.rb
View file @
fba1d515
...
@@ -31,6 +31,18 @@ module Epics
...
@@ -31,6 +31,18 @@ module Epics
issues_count
.
fetch
(
closed_state_id
,
0
)
issues_count
.
fetch
(
closed_state_id
,
0
)
end
end
def
issues_on_track
issue_health_statuses
.
fetch
(
'on_track'
,
0
)
end
def
issues_needing_attention
issue_health_statuses
.
fetch
(
'needs_attention'
,
0
)
end
def
issues_at_risk
issue_health_statuses
.
fetch
(
'at_risk'
,
0
)
end
private
private
def
epics_count
def
epics_count
...
@@ -45,6 +57,12 @@ module Epics
...
@@ -45,6 +57,12 @@ module Epics
end
end
end
end
def
issue_health_statuses
strong_memoize
(
:issue_health_statuses
)
do
Issue
.
in_epics
(
accessible_epics
).
counts_by_health_status
end
end
def
accessible_epics
def
accessible_epics
strong_memoize
(
:epics
)
do
strong_memoize
(
:epics
)
do
epic
.
base_and_descendants
epic
.
base_and_descendants
...
...
ee/changelogs/unreleased/199184-health-status-display.yml
0 → 100644
View file @
fba1d515
---
title
:
Add health status data to the epic GraphQL endpoint
merge_request
:
25989
author
:
type
:
added
ee/spec/graphql/types/epic_type_spec.rb
View file @
fba1d515
...
@@ -11,7 +11,7 @@ describe GitlabSchema.types['Epic'] do
...
@@ -11,7 +11,7 @@ describe GitlabSchema.types['Epic'] do
closed_at created_at updated_at children has_children has_issues
closed_at created_at updated_at children has_children has_issues
web_path web_url relation_path reference issues user_permissions
web_path web_url relation_path reference issues user_permissions
notes discussions relative_position subscribed participants
notes discussions relative_position subscribed participants
descendant_counts descendant_weight_sum upvotes downvotes
descendant_counts descendant_weight_sum upvotes downvotes
health_status
]
]
end
end
...
...
ee/spec/models/issue_spec.rb
View file @
fba1d515
...
@@ -67,6 +67,16 @@ describe Issue do
...
@@ -67,6 +67,16 @@ describe Issue do
end
end
end
end
describe
'.counts_by_health_status'
do
it
'returns counts grouped by health_status'
do
create
(
:issue
,
health_status: :on_track
)
create
(
:issue
,
health_status: :on_track
)
create
(
:issue
,
health_status: :at_risk
)
expect
(
Issue
.
counts_by_health_status
).
to
eq
({
'on_track'
=>
2
,
'at_risk'
=>
1
}
)
end
end
context
'epics'
do
context
'epics'
do
let_it_be
(
:epic1
)
{
create
(
:epic
)
}
let_it_be
(
:epic1
)
{
create
(
:epic
)
}
let_it_be
(
:epic2
)
{
create
(
:epic
)
}
let_it_be
(
:epic2
)
{
create
(
:epic
)
}
...
...
ee/spec/services/epics/descendant_count_service_spec.rb
View file @
fba1d515
...
@@ -11,12 +11,13 @@ describe Epics::DescendantCountService do
...
@@ -11,12 +11,13 @@ describe Epics::DescendantCountService do
let_it_be
(
:epic2
)
{
create
(
:epic
,
group:
subgroup
,
parent:
parent_epic
,
state: :closed
)
}
let_it_be
(
:epic2
)
{
create
(
:epic
,
group:
subgroup
,
parent:
parent_epic
,
state: :closed
)
}
let_it_be
(
:project
)
{
create
(
:project
,
:private
,
group:
group
)}
let_it_be
(
:project
)
{
create
(
:project
,
:private
,
group:
group
)}
let_it_be
(
:issue1
)
{
create
(
:issue
,
project:
project
,
state: :opened
)
}
let_it_be
(
:issue1
)
{
create
(
:issue
,
project:
project
,
state: :opened
,
health_status: :on_track
)
}
let_it_be
(
:issue2
)
{
create
(
:issue
,
project:
project
,
state: :closed
)
}
let_it_be
(
:issue2
)
{
create
(
:issue
,
project:
project
,
state: :closed
,
health_status: :on_track
)
}
let_it_be
(
:issue3
)
{
create
(
:issue
,
project:
project
,
state: :opened
)
}
let_it_be
(
:issue3
)
{
create
(
:issue
,
project:
project
,
state: :opened
)
}
let_it_be
(
:issue4
)
{
create
(
:issue
,
project:
project
,
state: :closed
)
}
let_it_be
(
:issue4
)
{
create
(
:issue
,
project:
project
,
state: :closed
,
health_status: :needs_attention
)
}
let_it_be
(
:issue5
)
{
create
(
:issue
,
:confidential
,
project:
project
,
state: :opened
)
}
let_it_be
(
:issue5
)
{
create
(
:issue
,
:confidential
,
project:
project
,
state: :opened
,
health_status: :at_risk
)
}
let_it_be
(
:issue6
)
{
create
(
:issue
,
:confidential
,
project:
project
,
state: :closed
)
}
let_it_be
(
:issue6
)
{
create
(
:issue
,
:confidential
,
project:
project
,
state: :closed
,
health_status: :at_risk
)
}
let_it_be
(
:epic_issue1
)
{
create
(
:epic_issue
,
epic:
parent_epic
,
issue:
issue1
)
}
let_it_be
(
:epic_issue1
)
{
create
(
:epic_issue
,
epic:
parent_epic
,
issue:
issue1
)
}
let_it_be
(
:epic_issue2
)
{
create
(
:epic_issue
,
epic:
parent_epic
,
issue:
issue2
)
}
let_it_be
(
:epic_issue2
)
{
create
(
:epic_issue
,
epic:
parent_epic
,
issue:
issue2
)
}
let_it_be
(
:epic_issue3
)
{
create
(
:epic_issue
,
epic:
epic1
,
issue:
issue3
)
}
let_it_be
(
:epic_issue3
)
{
create
(
:epic_issue
,
epic:
epic1
,
issue:
issue3
)
}
...
@@ -51,4 +52,16 @@ describe Epics::DescendantCountService do
...
@@ -51,4 +52,16 @@ describe Epics::DescendantCountService do
describe
'#closed_issues'
do
describe
'#closed_issues'
do
it_behaves_like
'descendants state count'
,
:closed_issues
,
3
it_behaves_like
'descendants state count'
,
:closed_issues
,
3
end
end
describe
'#issues_on_track'
do
it_behaves_like
'descendants state count'
,
:issues_on_track
,
2
end
describe
'#issues_needing_attention'
do
it_behaves_like
'descendants state count'
,
:issues_needing_attention
,
1
end
describe
'#issues_at_risk'
do
it_behaves_like
'descendants state count'
,
:issues_at_risk
,
2
end
end
end
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