This repository has been archived by the owner on Dec 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 961
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for getting DORA metrics from projects and groups
- Loading branch information
1 parent
f3f2bd3
commit bd2b78d
Showing
4 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package gitlab | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
// DORAMetric represents a single DORA metric data point. | ||
// | ||
// Gitlab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html | ||
type DORAMetric struct { | ||
Date string `json:"date"` | ||
Value float64 `json:"value"` | ||
} | ||
|
||
// Gets a string representation of a DORAMetric data point | ||
// | ||
// GitLab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html | ||
func (m DORAMetric) String() string { | ||
return Stringify(m) | ||
} | ||
|
||
// GetDORAMetricsOptions represent the request body options for getting | ||
// DORA metrics | ||
// | ||
// GitLab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html | ||
type GetDORAMetricsOptions struct { | ||
Metric DORAMetricType `url:"metric,omitempty" json:"metric,omitempty"` | ||
EndDate *ISOTime `url:"end_date,omitempty" json:"end_date,omitempty"` | ||
EnvironmentTiers *[]string `url:"environment_tiers,omitempty" del:"," json:"environment_tiers,omitempty"` | ||
Interval *DORAMetricInterval `url:"interval,omitempty" json:"interval,omitempty"` | ||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` | ||
|
||
// Deprecated, use environment tiers instead | ||
EnvironmentTier *string `url:"environment_tier,omitempty" json:"environment_tier,omitempty"` | ||
} | ||
|
||
// DORAMetricsService handles communication with the DORA metrics related methods | ||
// of the GitLab API | ||
// | ||
// Gitlab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html | ||
type DORAMetricsService struct { | ||
client *Client | ||
} | ||
|
||
// GetProjectDORAMetrics gets the DORA metrics for a project. | ||
// | ||
// GitLab API Docs: | ||
// https://docs.gitlab.com/ee/api/dora/metrics.html#get-project-level-dora-metrics | ||
func (s *DORAMetricsService) GetProjectDORAMetrics(pid interface{}, opt GetDORAMetricsOptions, options ...RequestOptionFunc) ([]DORAMetric, *Response, error) { | ||
project, err := parseID(pid) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
u := fmt.Sprintf("projects/%s/dora/metrics", PathEscape(project)) | ||
|
||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var metrics []DORAMetric | ||
resp, err := s.client.Do(req, &metrics) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return metrics, resp, err | ||
} | ||
|
||
// GetGroupDORAMetrics gets the DORA metrics for a group. | ||
// | ||
// GitLab API Docs: | ||
// https://docs.gitlab.com/ee/api/dora/metrics.html#get-group-level-dora-metrics | ||
func (s *DORAMetricsService) GetGroupDORAMetrics(gid interface{}, opt GetDORAMetricsOptions, options ...RequestOptionFunc) ([]DORAMetric, *Response, error) { | ||
group, err := parseID(gid) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
u := fmt.Sprintf("groups/%s/dora/metrics", PathEscape(group)) | ||
|
||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var metrics []DORAMetric | ||
resp, err := s.client.Do(req, &metrics) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return metrics, resp, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package gitlab | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDORAMetrics_GetProjectDORAMetrics(t *testing.T) { | ||
mux, client := setup(t) | ||
|
||
mux.HandleFunc("/api/v4/projects/1/dora/metrics", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, http.MethodGet) | ||
query := r.URL.Query() | ||
for k, v := range map[string]string{ | ||
"metric": "deployment_frequency", | ||
"start_date": "2021-03-01", | ||
"end_date": "2021-03-08", | ||
} { | ||
if query.Get(k) != v { | ||
t.Errorf("Query parameter %s: %s, want %s", k, query.Get(k), v) | ||
} | ||
} | ||
|
||
fmt.Fprint(w, ` | ||
[ | ||
{ "date": "2021-03-01", "value": 3 }, | ||
{ "date": "2021-03-02", "value": 6 }, | ||
{ "date": "2021-03-03", "value": 0 }, | ||
{ "date": "2021-03-04", "value": 0 }, | ||
{ "date": "2021-03-05", "value": 0 }, | ||
{ "date": "2021-03-06", "value": 0 }, | ||
{ "date": "2021-03-07", "value": 0 }, | ||
{ "date": "2021-03-08", "value": 4 } | ||
] | ||
`) | ||
}) | ||
|
||
want := []DORAMetric{ | ||
{Date: "2021-03-01", Value: 3}, | ||
{Date: "2021-03-02", Value: 6}, | ||
{Date: "2021-03-03", Value: 0}, | ||
{Date: "2021-03-04", Value: 0}, | ||
{Date: "2021-03-05", Value: 0}, | ||
{Date: "2021-03-06", Value: 0}, | ||
{Date: "2021-03-07", Value: 0}, | ||
{Date: "2021-03-08", Value: 4}, | ||
} | ||
|
||
startDate := ISOTime(time.Date(2021, time.March, 1, 0, 0, 0, 0, time.UTC)) | ||
endDate := ISOTime(time.Date(2021, time.March, 8, 0, 0, 0, 0, time.UTC)) | ||
|
||
d, resp, err := client.DORAMetrics.GetProjectDORAMetrics(1, GetDORAMetricsOptions{ | ||
Metric: DORAMetricDeploymentFrequency, | ||
StartDate: &startDate, | ||
EndDate: &endDate, | ||
}) | ||
require.NoError(t, err) | ||
require.NotNil(t, resp) | ||
require.Equal(t, want, d) | ||
} | ||
|
||
func TestDORAMetrics_GetGroupDORAMetrics(t *testing.T) { | ||
mux, client := setup(t) | ||
|
||
mux.HandleFunc("/api/v4/groups/1/dora/metrics", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, http.MethodGet) | ||
query := r.URL.Query() | ||
for k, v := range map[string]string{ | ||
"metric": "deployment_frequency", | ||
"start_date": "2021-03-01", | ||
"end_date": "2021-03-08", | ||
} { | ||
if query.Get(k) != v { | ||
t.Errorf("Query parameter %s: %s, want %s", k, query.Get(k), v) | ||
} | ||
} | ||
|
||
fmt.Fprint(w, ` | ||
[ | ||
{ "date": "2021-03-01", "value": 3 }, | ||
{ "date": "2021-03-02", "value": 6 }, | ||
{ "date": "2021-03-03", "value": 0 }, | ||
{ "date": "2021-03-04", "value": 0 }, | ||
{ "date": "2021-03-05", "value": 0 }, | ||
{ "date": "2021-03-06", "value": 0 }, | ||
{ "date": "2021-03-07", "value": 0 }, | ||
{ "date": "2021-03-08", "value": 4 } | ||
] | ||
`) | ||
}) | ||
|
||
want := []DORAMetric{ | ||
{Date: "2021-03-01", Value: 3}, | ||
{Date: "2021-03-02", Value: 6}, | ||
{Date: "2021-03-03", Value: 0}, | ||
{Date: "2021-03-04", Value: 0}, | ||
{Date: "2021-03-05", Value: 0}, | ||
{Date: "2021-03-06", Value: 0}, | ||
{Date: "2021-03-07", Value: 0}, | ||
{Date: "2021-03-08", Value: 4}, | ||
} | ||
|
||
startDate := ISOTime(time.Date(2021, time.March, 1, 0, 0, 0, 0, time.UTC)) | ||
endDate := ISOTime(time.Date(2021, time.March, 8, 0, 0, 0, 0, time.UTC)) | ||
|
||
d, resp, err := client.DORAMetrics.GetGroupDORAMetrics(1, GetDORAMetricsOptions{ | ||
Metric: DORAMetricDeploymentFrequency, | ||
StartDate: &startDate, | ||
EndDate: &endDate, | ||
}) | ||
require.NoError(t, err) | ||
require.NotNil(t, resp) | ||
require.Equal(t, want, d) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters