Skip to content

Commit ca4ce75

Browse files
fix(workflows): Fix empty results in Workflows query type (#526)
Fixes #503 - Add nil check for CreatedAt/UpdatedAt timestamps to prevent panics - Add 'None' option to Time Field dropdown (default) to return all workflows - Improve time filtering logic with better nil handling - Add debug logging for troubleshooting ## Testing - ✅ All existing tests pass - ✅ Tested locally with docker-compose - ✅ Verified workflows are returned when Time Field is "None" - ✅ Verified time filtering works with CreatedAt/UpdatedAt options
1 parent 82af5d0 commit ca4ce75

File tree

6 files changed

+56
-11
lines changed

6 files changed

+56
-11
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"grafana-github-datasource": patch
3+
---
4+
5+
Fix empty results in Workflows query type. Added nil check for CreatedAt/UpdatedAt timestamps and added "None" option to Time Field dropdown (default) to return all workflows without time filtering.

docs/sources/query/_index.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,10 +554,16 @@ List GitHub Actions workflows defined in a repository.
554554
| ---------- | -------------------------------------------------- | -------- |
555555
| owner | GitHub user or organization that owns the repository | Yes |
556556
| repository | Name of the repository | Yes |
557-
| Time Field | The time field to filter the responses on, can be: `CreatedAt` or `UpdatedAt` | Yes |
557+
| Time Field | The time field to filter the responses on, can be: `None` (returns all workflows), `CreatedAt`, or `UpdatedAt` | Yes |
558558

559559
##### Sample queries
560560

561+
Show all workflows in the `grafana/grafana` repository:
562+
563+
- Owner: `grafana`
564+
- Repository: `grafana`
565+
- Time Field: `None`
566+
561567
Show all workflows created within the `grafana/grafana` repository within the current time range:
562568

563569
- Owner: `grafana`

pkg/github/workflows.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ func GetWorkflows(ctx context.Context, client models.Client, opts models.ListWor
6363
return nil, fmt.Errorf("listing workflows: opts=%+v %w", opts, err)
6464
}
6565

66+
// If time field is None, return all workflows without filtering
67+
if opts.TimeField == models.WorkflowTimeFieldNone {
68+
return WorkflowsWrapper(data.Workflows), nil
69+
}
70+
71+
// Otherwise, apply time filtering based on the selected time field
6672
workflows, err := keepWorkflowsInTimeRange(data.Workflows, opts.TimeField, timeRange)
6773
if err != nil {
6874
return nil, fmt.Errorf("filtering workflows by time range: timeField=%d timeRange=%+v %w", opts.TimeField, timeRange, err)
@@ -72,27 +78,52 @@ func GetWorkflows(ctx context.Context, client models.Client, opts models.ListWor
7278
}
7379

7480
func keepWorkflowsInTimeRange(workflows []*googlegithub.Workflow, timeField models.WorkflowTimeField, timeRange backend.TimeRange) ([]*googlegithub.Workflow, error) {
81+
// If time range is empty/unset, return all workflows (similar to Tags, Releases, etc.)
82+
if timeRange.From.Unix() <= 0 && timeRange.To.Unix() <= 0 {
83+
return workflows, nil
84+
}
85+
7586
out := make([]*googlegithub.Workflow, 0)
87+
nilCount := 0
88+
excludedCount := 0
7689

7790
for _, workflow := range workflows {
91+
var shouldInclude bool
92+
7893
switch timeField {
7994
case models.WorkflowCreatedAt:
80-
if workflow.CreatedAt.Before(timeRange.From) || workflow.CreatedAt.After(timeRange.To) {
95+
if workflow.CreatedAt == nil {
96+
// If filtering by CreatedAt but CreatedAt is nil, exclude the workflow
97+
nilCount++
8198
continue
8299
}
100+
// Include if CreatedAt is within the time range (inclusive)
101+
createdAtTime := workflow.CreatedAt.Time
102+
shouldInclude = !createdAtTime.Before(timeRange.From) && !createdAtTime.After(timeRange.To)
103+
if !shouldInclude {
104+
excludedCount++
105+
}
83106

84107
case models.WorkflowUpdatedAt:
85-
if workflow.UpdatedAt != nil {
86-
if workflow.UpdatedAt.Before(timeRange.From) || workflow.UpdatedAt.After(timeRange.To) {
87-
continue
88-
}
108+
if workflow.UpdatedAt == nil {
109+
// If filtering by UpdatedAt but UpdatedAt is nil, exclude the workflow
110+
nilCount++
111+
continue
112+
}
113+
// Include if UpdatedAt is within the time range (inclusive)
114+
updatedAtTime := workflow.UpdatedAt.Time
115+
shouldInclude = !updatedAtTime.Before(timeRange.From) && !updatedAtTime.After(timeRange.To)
116+
if !shouldInclude {
117+
excludedCount++
89118
}
90119

91120
default:
92121
return nil, backend.DownstreamError(fmt.Errorf("unexpected time field: %d", timeField))
93122
}
94123

95-
out = append(out, workflow)
124+
if shouldInclude {
125+
out = append(out, workflow)
126+
}
96127
}
97128

98129
return out, nil

pkg/models/workflows.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import "time"
66
type WorkflowTimeField uint32
77

88
const (
9+
// WorkflowTimeFieldNone indicates no time filtering should be applied
10+
WorkflowTimeFieldNone WorkflowTimeField = iota
911
// WorkflowCreatedAt is used when filtering when an workflow was created
10-
WorkflowCreatedAt WorkflowTimeField = iota
12+
WorkflowCreatedAt
1113
// WorkflowUpdatedAt is used when filtering when an Workflow was updated
1214
WorkflowUpdatedAt
1315
)

src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export enum IssueTimeField {
4949
}
5050

5151
export enum WorkflowsTimeField {
52+
None,
5253
CreatedAt,
5354
UpdatedAt,
5455
}

src/views/QueryEditorWorkflows.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ const timeFieldOptions: Array<SelectableValue<WorkflowsTimeField>> = Object.keys
1818
};
1919
});
2020

21-
const defaultTimeField = 0 as WorkflowsTimeField;
21+
const defaultTimeField = WorkflowsTimeField.None;
2222

2323
const QueryEditorWorkflows = (props: Props) => {
2424
return (
2525
<>
2626
<InlineField
2727
labelWidth={LeftColumnWidth * 2}
2828
label="Time Field"
29-
tooltip="The time field to filter on the time range"
29+
tooltip="Select 'None' to return all workflows, or choose a time field to filter by the dashboard time range"
3030
>
3131
<Select
3232
width={RightColumnWidth}
3333
options={timeFieldOptions}
34-
value={props.timeField || defaultTimeField}
34+
value={props.timeField !== undefined ? props.timeField : defaultTimeField}
3535
onChange={(opt) => {
3636
props.onChange({
3737
...props,

0 commit comments

Comments
 (0)