Commit 3efe1a8a authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'add_latest_pipeline_link_to_api' into 'master'

Add latest pipelines link to api

See merge request gitlab-org/gitlab!16534
parents 016913c0 59db520f
...@@ -199,12 +199,7 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -199,12 +199,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end end
def latest_pipeline def latest_pipeline
ref = params['ref'].presence || @project.default_branch @project.latest_pipeline_for_ref(params['ref'])
sha = @project.commit(ref)&.sha
@project.ci_pipelines
.newest_first(ref: ref, sha: sha)
.first
&.present(current_user: current_user) &.present(current_user: current_user)
end end
......
...@@ -753,6 +753,15 @@ class Project < ApplicationRecord ...@@ -753,6 +753,15 @@ class Project < ApplicationRecord
latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound.new("Couldn't find job #{job_name}")) latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound.new("Couldn't find job #{job_name}"))
end end
def latest_pipeline_for_ref(ref = default_branch)
ref = ref.presence || default_branch
sha = commit(ref)&.sha
return unless sha
ci_pipelines.newest_first(ref: ref, sha: sha).first
end
def merge_base_commit(first_commit_id, second_commit_id) def merge_base_commit(first_commit_id, second_commit_id)
sha = repository.merge_base(first_commit_id, second_commit_id) sha = repository.merge_base(first_commit_id, second_commit_id)
commit_by(oid: sha) if sha commit_by(oid: sha) if sha
......
...@@ -69,6 +69,19 @@ module API ...@@ -69,6 +69,19 @@ module API
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
desc 'Gets a the latest pipeline for the project branch' do
detail 'This feature was introduced in GitLab 12.3'
success Entities::Pipeline
end
params do
optional :ref, type: String, desc: 'branch ref of pipeline'
end
get ':id/pipelines/latest' do
authorize! :read_pipeline, latest_pipeline
present latest_pipeline, with: Entities::Pipeline
end
desc 'Gets a specific pipeline for the project' do desc 'Gets a specific pipeline for the project' do
detail 'This feature was introduced in GitLab 8.11' detail 'This feature was introduced in GitLab 8.11'
success Entities::Pipeline success Entities::Pipeline
...@@ -144,7 +157,15 @@ module API ...@@ -144,7 +157,15 @@ module API
helpers do helpers do
def pipeline def pipeline
@pipeline ||= user_project.ci_pipelines.find(params[:pipeline_id]) strong_memoize(:pipeline) do
user_project.ci_pipelines.find(params[:pipeline_id])
end
end
def latest_pipeline
strong_memoize(:latest_pipeline) do
user_project.latest_pipeline_for_ref(params[:ref])
end
end end
end end
end end
......
...@@ -2027,6 +2027,43 @@ describe Project do ...@@ -2027,6 +2027,43 @@ describe Project do
end end
end end
describe '#latest_pipeline_for_ref' do
let(:project) { create(:project, :repository) }
let(:second_branch) { project.repository.branches[2] }
let!(:pipeline_for_default_branch) do
create(:ci_empty_pipeline, project: project, sha: project.commit.id,
ref: project.default_branch)
end
let!(:pipeline_for_second_branch) do
create(:ci_empty_pipeline, project: project, sha: second_branch.target,
ref: second_branch.name)
end
before do
create(:ci_empty_pipeline, project: project, sha: project.commit.parent.id,
ref: project.default_branch)
end
context 'default repository branch' do
subject { project.latest_pipeline_for_ref(project.default_branch) }
it { is_expected.to eq(pipeline_for_default_branch) }
end
context 'provided ref' do
subject { project.latest_pipeline_for_ref(second_branch.name) }
it { is_expected.to eq(pipeline_for_second_branch) }
end
context 'bad ref' do
subject { project.latest_pipeline_for_ref(SecureRandom.uuid) }
it { is_expected.to be_nil }
end
end
describe '#latest_successful_build_for_sha' do describe '#latest_successful_build_for_sha' do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:pipeline) { create_pipeline(project) } let(:pipeline) { create_pipeline(project) }
......
...@@ -459,6 +459,54 @@ describe API::Pipelines do ...@@ -459,6 +459,54 @@ describe API::Pipelines do
end end
end end
describe 'GET /projects/:id/pipelines/latest' do
context 'authorized user' do
let(:second_branch) { project.repository.branches[2] }
let!(:second_pipeline) do
create(:ci_empty_pipeline, project: project, sha: second_branch.target,
ref: second_branch.name, user: user)
end
before do
create(:ci_empty_pipeline, project: project, sha: project.commit.parent.id,
ref: project.default_branch, user: user)
end
context 'default repository branch' do
it 'gets the latest pipleine' do
get api("/projects/#{project.id}/pipelines/latest", user)
expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/pipeline/detail')
expect(json_response['ref']).to eq(project.default_branch)
expect(json_response['sha']).to eq(project.commit.id)
end
end
context 'ref parameter' do
it 'gets the latest pipleine' do
get api("/projects/#{project.id}/pipelines/latest", user), params: { ref: second_branch.name }
expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/pipeline/detail')
expect(json_response['ref']).to eq(second_branch.name)
expect(json_response['sha']).to eq(second_branch.target)
end
end
end
context 'unauthorized user' do
it 'does not return a project pipeline' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member)
expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response['id']).to be nil
end
end
end
describe 'GET /projects/:id/pipelines/:pipeline_id/variables' do describe 'GET /projects/:id/pipelines/:pipeline_id/variables' do
subject { get api("/projects/#{project.id}/pipelines/#{pipeline.id}/variables", api_user) } subject { get api("/projects/#{project.id}/pipelines/#{pipeline.id}/variables", api_user) }
......
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