Skip to content

Commit d7abcb6

Browse files
authored
Return assignees with issues queries (#479)
Return a new column in the issues query: `Assignees`. This change allows users to see who is assigned to each GitHub issue directly in their Grafana dashboards and queries. **_BEFORE THE CHANGE_** <img width="2535" alt="Screenshot 2025-06-20 at 17 27 35" src="https://github.com/user-attachments/assets/63ee60c0-8c97-469b-b9de-0fc593419fec" /> **_AFTER THE CHANGE_** <img width="2537" alt="Screenshot 2025-06-20 at 17 26 47" src="https://github.com/user-attachments/assets/a02d41a2-dde7-47a7-8159-887293ebe5e5" />
1 parent 23c1f32 commit d7abcb6

File tree

4 files changed

+66
-31
lines changed

4 files changed

+66
-31
lines changed

docs/sources/query/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ Show all issues with 'sql expressions' in the title:
124124
| closed_at | When the issue was closed: YYYY-MM-DD HH:MM:SS |
125125
| updated_at | When the issue was last updated: YYYY-MM-DD HH:MM:SS |
126126
| labels | Array of labels, for example: `["type/bug", "needs more info"]` |
127+
| assignees | Array of assignees, for example: `["user1", "user2"]` |
127128

128129
### Contributors
129130

pkg/github/issues.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ type Issue struct {
2626
Name string
2727
}
2828
} `graphql:"labels(first: 100)"`
29+
Assignees struct {
30+
Nodes []struct {
31+
models.User
32+
}
33+
} `graphql:"assignees(first: 10)"`
2934
Author struct {
3035
models.User `graphql:"... on User"`
3136
}
@@ -49,6 +54,7 @@ func (c Issues) Frames() data.Frames {
4954
data.NewField("closed_at", nil, []*time.Time{}),
5055
data.NewField("updated_at", nil, []time.Time{}),
5156
data.NewField("labels", nil, []json.RawMessage{}),
57+
data.NewField("assignees", nil, []json.RawMessage{}),
5258
)
5359

5460
for _, v := range c {
@@ -63,8 +69,16 @@ func (c Issues) Frames() data.Frames {
6369
labels[i] = label.Name
6470
}
6571

72+
assignees := make([]string, len(v.Assignees.Nodes))
73+
for i, assignee := range v.Assignees.Nodes {
74+
assignees[i] = assignee.User.Login
75+
}
76+
6677
labelsBytes, _ := json.Marshal(labels)
6778
rawLabelArray := json.RawMessage(labelsBytes)
79+
80+
assigneesBytes, _ := json.Marshal(assignees)
81+
rawAssigneesArray := json.RawMessage(assigneesBytes)
6882

6983
frame.AppendRow(
7084
v.Title,
@@ -77,6 +91,7 @@ func (c Issues) Frames() data.Frames {
7791
closedAt,
7892
v.UpdatedAt.Time,
7993
rawLabelArray,
94+
rawAssigneesArray,
8095
)
8196
}
8297

pkg/github/issues_test.go

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,13 @@ func TestIssuesDataframe(t *testing.T) {
5353
Time: createdAt,
5454
},
5555
Closed: false,
56-
Labels: struct {
57-
Nodes []struct{ Name string }
58-
}{
56+
Labels: struct { Nodes []struct{ Name string } }{
5957
Nodes: []struct{ Name string }{
60-
{Name: "bug"},
61-
{Name: "help wanted"},
58+
{ Name: "bug" },
59+
{ Name: "help wanted" },
6260
},
6361
},
64-
Author: struct {
65-
models.User "graphql:\"... on User\""
66-
}{
62+
Author: struct { models.User "graphql:\"... on User\"" }{
6763
User: models.User{
6864
ID: "1",
6965
Login: "firstUser",
@@ -73,6 +69,12 @@ func TestIssuesDataframe(t *testing.T) {
7369
URL: "",
7470
},
7571
},
72+
Assignees: struct { Nodes []struct { models.User } }{
73+
Nodes: []struct { models.User }{
74+
{ User: models.User{ Login: "firstUser" } },
75+
{ User: models.User{ Login: "secondUser" } },
76+
},
77+
},
7678
Repository: Repository{
7779
Name: "grafana",
7880
Owner: struct{ Login string }{
@@ -102,16 +104,12 @@ func TestIssuesDataframe(t *testing.T) {
102104
Time: createdAt.Add(time.Hour * 6),
103105
},
104106
Closed: true,
105-
Labels: struct {
106-
Nodes []struct{ Name string }
107-
}{
107+
Labels: struct { Nodes []struct{ Name string } }{
108108
Nodes: []struct{ Name string }{
109-
{Name: "enhancement"},
109+
{ Name: "enhancement" },
110110
},
111111
},
112-
Author: struct {
113-
models.User "graphql:\"... on User\""
114-
}{
112+
Author: struct { models.User "graphql:\"... on User\"" }{
115113
User: models.User{
116114
ID: "2",
117115
Login: "secondUser",
@@ -121,6 +119,11 @@ func TestIssuesDataframe(t *testing.T) {
121119
URL: "",
122120
},
123121
},
122+
Assignees: struct { Nodes []struct { models.User } }{
123+
Nodes: []struct { models.User }{
124+
{ User: models.User{ Login: "firstUser" } },
125+
},
126+
},
124127
Repository: Repository{
125128
Name: "grafana",
126129
Owner: struct{ Login string }{
@@ -150,14 +153,10 @@ func TestIssuesDataframe(t *testing.T) {
150153
Time: createdAt,
151154
},
152155
Closed: false,
153-
Labels: struct {
154-
Nodes []struct{ Name string }
155-
}{
156+
Labels: struct { Nodes []struct{ Name string } }{
156157
Nodes: []struct{ Name string }{},
157158
},
158-
Author: struct {
159-
models.User "graphql:\"... on User\""
160-
}{
159+
Author: struct { models.User "graphql:\"... on User\"" }{
161160
User: models.User{
162161
ID: "3",
163162
Login: "firstUser",
@@ -167,6 +166,9 @@ func TestIssuesDataframe(t *testing.T) {
167166
URL: "",
168167
},
169168
},
169+
Assignees: struct { Nodes []struct { models.User }}{
170+
Nodes: []struct { models.User }{},
171+
},
170172
Repository: Repository{
171173
Name: "grafana",
172174
Owner: struct{ Login string }{

pkg/github/testdata/issues.golden.jsonc

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
//
33
// Frame[0]
44
// Name: issues
5-
// Dimensions: 10 Fields by 3 Rows
6-
// +----------------+----------------+----------------------+-----------------+---------------+--------------+---------------------------------+---------------------------------+---------------------------------+-------------------------+
7-
// | Name: title | Name: author | Name: author_company | Name: repo | Name: number | Name: closed | Name: created_at | Name: closed_at | Name: updated_at | Name: labels |
8-
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
9-
// | Type: []string | Type: []string | Type: []string | Type: []string | Type: []int64 | Type: []bool | Type: []time.Time | Type: []*time.Time | Type: []time.Time | Type: []json.RawMessage |
10-
// +----------------+----------------+----------------------+-----------------+---------------+--------------+---------------------------------+---------------------------------+---------------------------------+-------------------------+
11-
// | Issue #1 | firstUser | ACME Corp | grafana/grafana | 1 | false | 2020-08-25 16:21:56 +0000 +0000 | null | 2020-08-25 16:21:56 +0000 +0000 | ["bug","help wanted"] |
12-
// | Issue #2 | secondUser | ACME Corp | grafana/grafana | 2 | true | 2020-08-25 16:21:56 +0000 +0000 | 2020-08-25 22:21:56 +0000 +0000 | 2020-08-25 22:21:56 +0000 +0000 | ["enhancement"] |
13-
// | Issue #3 | firstUser | ACME Corp | grafana/grafana | 3 | false | 2020-08-25 16:21:56 +0000 +0000 | null | 2020-08-25 16:21:56 +0000 +0000 | [] |
14-
// +----------------+----------------+----------------------+-----------------+---------------+--------------+---------------------------------+---------------------------------+---------------------------------+-------------------------+
5+
// Dimensions: 11 Fields by 3 Rows
6+
// +----------------+----------------+----------------------+-----------------+---------------+--------------+---------------------------------+---------------------------------+---------------------------------+-------------------------+----------------------------+
7+
// | Name: title | Name: author | Name: author_company | Name: repo | Name: number | Name: closed | Name: created_at | Name: closed_at | Name: updated_at | Name: labels | Name: assignees |
8+
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
9+
// | Type: []string | Type: []string | Type: []string | Type: []string | Type: []int64 | Type: []bool | Type: []time.Time | Type: []*time.Time | Type: []time.Time | Type: []json.RawMessage | Type: []json.RawMessage |
10+
// +----------------+----------------+----------------------+-----------------+---------------+--------------+---------------------------------+---------------------------------+---------------------------------+-------------------------+----------------------------+
11+
// | Issue #1 | firstUser | ACME Corp | grafana/grafana | 1 | false | 2020-08-25 16:21:56 +0000 +0000 | null | 2020-08-25 16:21:56 +0000 +0000 | ["bug","help wanted"] | ["firstUser","secondUser"] |
12+
// | Issue #2 | secondUser | ACME Corp | grafana/grafana | 2 | true | 2020-08-25 16:21:56 +0000 +0000 | 2020-08-25 22:21:56 +0000 +0000 | 2020-08-25 22:21:56 +0000 +0000 | ["enhancement"] | ["firstUser"] |
13+
// | Issue #3 | firstUser | ACME Corp | grafana/grafana | 3 | false | 2020-08-25 16:21:56 +0000 +0000 | null | 2020-08-25 16:21:56 +0000 +0000 | [] | [] |
14+
// +----------------+----------------+----------------------+-----------------+---------------+--------------+---------------------------------+---------------------------------+---------------------------------+-------------------------+----------------------------+
1515
//
1616
//
1717
// 🌟 This was machine generated. Do not edit. 🌟
@@ -92,6 +92,13 @@
9292
"typeInfo": {
9393
"frame": "json.RawMessage"
9494
}
95+
},
96+
{
97+
"name": "assignees",
98+
"type": "other",
99+
"typeInfo": {
100+
"frame": "json.RawMessage"
101+
}
95102
}
96103
]
97104
},
@@ -151,6 +158,16 @@
151158
"enhancement"
152159
],
153160
[]
161+
],
162+
[
163+
[
164+
"firstUser",
165+
"secondUser"
166+
],
167+
[
168+
"firstUser"
169+
],
170+
[]
154171
]
155172
]
156173
}

0 commit comments

Comments
 (0)