Read about our upcoming Code of Conduct on this issue

Commit 1710cd1c authored by haseeb's avatar haseeb Committed by Sean McGivern
Browse files

expose metrics in merge request api

parent 536036481b4b
---
title: expose more metrics in merge requests api
merge_request: 16589
author: haseebeqx
type: added
......@@ -261,20 +261,20 @@ Parameters:
"upvotes": 0,
"downvotes": 0,
"author": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2012-04-29T08:46:00Z"
"state" : "active",
"web_url" : "https://gitlab.example.com/root",
"avatar_url" : null,
"username" : "root",
"id" : 1,
"name" : "Administrator"
},
"assignee": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2012-04-29T08:46:00Z"
"state" : "active",
"web_url" : "https://gitlab.example.com/root",
"avatar_url" : null,
"username" : "root",
"id" : 1,
"name" : "Administrator"
},
"source_project_id": 2,
"target_project_id": 3,
......@@ -308,6 +308,26 @@ Parameters:
"total_time_spent": 0,
"human_time_estimate": null,
"human_total_time_spent": null
},
"closed_at": "2018-01-19T14:36:11.086Z",
"latest_build_started_at": null,
"latest_build_finished_at": null,
"first_deployed_to_production_at": null,
"pipeline": {
"id": 8,
"ref": "master",
"sha": "2dc6aa325a317eda67812f05600bdf0fcdc70ab0",
"status": "created"
},
"merged_by": null,
"merged_at": null,
"closed_by": {
"state" : "active",
"web_url" : "https://gitlab.example.com/root",
"avatar_url" : null,
"username" : "root",
"id" : 1,
"name" : "Administrator"
}
}
```
......
......@@ -481,6 +481,10 @@ class ExternalIssue < Grape::Entity
expose :id
end
class PipelineBasic < Grape::Entity
expose :id, :sha, :ref, :status
end
class MergeRequestSimple < ProjectEntity
expose :title
expose :web_url do |merge_request, options|
......@@ -546,6 +550,42 @@ class MergeRequest < MergeRequestBasic
expose :changes_count do |merge_request, _options|
merge_request.merge_request_diff.real_size
end
expose :merged_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.merged_by
end
expose :merged_at do |merge_request, _options|
merge_request.metrics&.merged_at
end
expose :closed_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.latest_closed_by
end
expose :closed_at do |merge_request, _options|
merge_request.metrics&.latest_closed_at
end
expose :latest_build_started_at, if: -> (_, options) { build_available?(options) } do |merge_request, _options|
merge_request.metrics&.latest_build_started_at
end
expose :latest_build_finished_at, if: -> (_, options) { build_available?(options) } do |merge_request, _options|
merge_request.metrics&.latest_build_finished_at
end
expose :first_deployed_to_production_at, if: -> (_, options) { build_available?(options) } do |merge_request, _options|
merge_request.metrics&.first_deployed_to_production_at
end
expose :pipeline, using: Entities::PipelineBasic, if: -> (_, options) { build_available?(options) } do |merge_request, _options|
merge_request.metrics&.pipeline
end
def build_available?(options)
options[:project]&.feature_available?(:builds, options[:current_user])
end
end
class MergeRequestChanges < MergeRequest
......@@ -909,10 +949,6 @@ class JobArtifactFile < Grape::Entity
expose :filename, :size
end
class PipelineBasic < Grape::Entity
expose :id, :sha, :ref, :status
end
class JobBasic < Grape::Entity
expose :id, :status, :stage, :name, :ref, :tag, :coverage
expose :created_at, :started_at, :finished_at
......
......@@ -222,7 +222,7 @@ def handle_merge_request_errors!(errors)
get ':id/merge_requests/:merge_request_iid/changes' do
merge_request = find_merge_request_with_access(params[:merge_request_iid])
present merge_request, with: Entities::MergeRequestChanges, current_user: current_user
present merge_request, with: Entities::MergeRequestChanges, current_user: current_user, project: user_project
end
desc 'Get the merge request pipelines' do
......
......@@ -9,6 +9,7 @@
let(:non_member) { create(:user) }
let!(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
let(:pipeline) { create(:ci_empty_pipeline) }
let(:milestone1) { create(:milestone, title: '0.9', project: project) }
let!(:merge_request) { create(:merge_request, :simple, milestone: milestone1, author: user, assignee: user, source_project: project, target_project: project, title: "Test", created_at: base_time) }
let!(:merge_request_closed) { create(:merge_request, state: "closed", milestone: milestone1, author: user, assignee: user, source_project: project, target_project: project, title: "Closed test", created_at: base_time + 1.second) }
......@@ -500,6 +501,45 @@
expect(json_response['changes_count']).to eq(merge_request.merge_request_diff.real_size)
end
context 'merge_request_metrics' do
before do
merge_request.metrics.update!(merged_by: user,
latest_closed_by: user,
latest_closed_at: 1.hour.ago,
merged_at: 2.hours.ago,
pipeline: pipeline,
latest_build_started_at: 3.hours.ago,
latest_build_finished_at: 1.hour.ago,
first_deployed_to_production_at: 3.minutes.ago)
end
it 'has fields from merge request metrics' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
expect(json_response).to include('merged_by',
'merged_at',
'closed_by',
'closed_at',
'latest_build_started_at',
'latest_build_finished_at',
'first_deployed_to_production_at',
'pipeline')
end
it 'returns correct values' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.reload.iid}", user)
expect(json_response['merged_by']['id']).to eq(merge_request.metrics.merged_by_id)
expect(Time.parse json_response['merged_at']).to be_like_time(merge_request.metrics.merged_at)
expect(json_response['closed_by']['id']).to eq(merge_request.metrics.latest_closed_by_id)
expect(Time.parse json_response['closed_at']).to be_like_time(merge_request.metrics.latest_closed_at)
expect(json_response['pipeline']['id']).to eq(merge_request.metrics.pipeline_id)
expect(Time.parse json_response['latest_build_started_at']).to be_like_time(merge_request.metrics.latest_build_started_at)
expect(Time.parse json_response['latest_build_finished_at']).to be_like_time(merge_request.metrics.latest_build_finished_at)
expect(Time.parse json_response['first_deployed_to_production_at']).to be_like_time(merge_request.metrics.first_deployed_to_production_at)
end
end
it "returns a 404 error if merge_request_iid not found" do
get api("/projects/#{project.id}/merge_requests/999", user)
expect(response).to have_gitlab_http_status(404)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment