Commit 19d134a4 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'include-pipeline-source-in-api' into 'master'

Add ability to filter pipelines by source in API

See merge request gitlab-org/gitlab!67846
parents f56300b0 3cb95106
...@@ -29,6 +29,9 @@ module Ci ...@@ -29,6 +29,9 @@ module Ci
items = by_username(items) items = by_username(items)
items = by_yaml_errors(items) items = by_yaml_errors(items)
items = by_updated_at(items) items = by_updated_at(items)
items = by_source(items) if Feature.enabled?(:pipeline_source_filter, project, default_enabled: :yaml)
sort_items(items) sort_items(items)
end end
...@@ -87,6 +90,12 @@ module Ci ...@@ -87,6 +90,12 @@ module Ci
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def by_source(items)
return items unless ::Ci::Pipeline.sources.key?(params[:source])
items.with_pipeline_source(params[:source])
end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def by_ref(items) def by_ref(items)
if params[:ref].present? if params[:ref].present?
......
...@@ -318,6 +318,7 @@ module Ci ...@@ -318,6 +318,7 @@ module Ci
scope :created_before_id, -> (id) { where('ci_pipelines.id < ?', id) } scope :created_before_id, -> (id) { where('ci_pipelines.id < ?', id) }
scope :before_pipeline, -> (pipeline) { created_before_id(pipeline.id).outside_pipeline_family(pipeline) } scope :before_pipeline, -> (pipeline) { created_before_id(pipeline.id).outside_pipeline_family(pipeline) }
scope :eager_load_project, -> { eager_load(project: [:route, { namespace: :route }]) } scope :eager_load_project, -> { eager_load(project: [:route, { namespace: :route }]) }
scope :with_pipeline_source, -> (source) { where(source: source)}
scope :outside_pipeline_family, ->(pipeline) do scope :outside_pipeline_family, ->(pipeline) do
where.not(id: pipeline.same_family_pipeline_ids) where.not(id: pipeline.same_family_pipeline_ids)
......
---
name: pipeline_source_filter
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67846
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338347
milestone: '14.2'
type: development
group: group::pipeline execution
default_enabled: false
...@@ -52,13 +52,14 @@ module API ...@@ -52,13 +52,14 @@ module API
desc: 'Order pipelines' desc: 'Order pipelines'
optional :sort, type: String, values: %w[asc desc], default: 'desc', optional :sort, type: String, values: %w[asc desc], default: 'desc',
desc: 'Sort pipelines' desc: 'Sort pipelines'
optional :source, type: String, values: ::Ci::Pipeline.sources.keys
end end
get ':id/pipelines' do get ':id/pipelines' do
authorize! :read_pipeline, user_project authorize! :read_pipeline, user_project
authorize! :read_build, user_project authorize! :read_build, user_project
pipelines = ::Ci::PipelinesFinder.new(user_project, current_user, params).execute pipelines = ::Ci::PipelinesFinder.new(user_project, current_user, params).execute
present paginate(pipelines), with: Entities::Ci::PipelineBasic present paginate(pipelines), with: Entities::Ci::PipelineBasic, project: user_project
end end
desc 'Create a new pipeline' do desc 'Create a new pipeline' do
......
...@@ -7,6 +7,8 @@ module API ...@@ -7,6 +7,8 @@ module API
expose :id, :project_id, :sha, :ref, :status expose :id, :project_id, :sha, :ref, :status
expose :created_at, :updated_at expose :created_at, :updated_at
expose :source, if: ->(pipeline, options) { ::Feature.enabled?(:pipeline_source_filter, options[:project], default_enabled: :yaml) }
expose :web_url do |pipeline, _options| expose :web_url do |pipeline, _options|
Gitlab::Routing.url_helpers.project_pipeline_url(pipeline.project, pipeline) Gitlab::Routing.url_helpers.project_pipeline_url(pipeline.project, pipeline)
end end
......
...@@ -252,6 +252,29 @@ RSpec.describe Ci::PipelinesFinder do ...@@ -252,6 +252,29 @@ RSpec.describe Ci::PipelinesFinder do
end end
end end
context 'when source is specified' do
let(:params) { { source: 'web' } }
let!(:web_pipeline) { create(:ci_pipeline, project: project, source: 'web') }
let!(:push_pipeline) { create(:ci_pipeline, project: project, source: 'push') }
let!(:api_pipeline) { create(:ci_pipeline, project: project, source: 'api') }
context 'when `pipeline_source_filter` feature flag is disabled' do
before do
stub_feature_flags(pipeline_source_filter: false)
end
it 'returns all the pipelines' do
is_expected.to contain_exactly(web_pipeline, push_pipeline, api_pipeline)
end
end
context 'when `pipeline_source_filter` feature flag is enabled' do
it 'returns only the matched pipeline' do
is_expected.to eq([web_pipeline])
end
end
end
describe 'ordering' do describe 'ordering' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"sha": { "type": "string" }, "sha": { "type": "string" },
"ref": { "type": "string" }, "ref": { "type": "string" },
"status": { "type": "string" }, "status": { "type": "string" },
"source": { "type": "string" },
"web_url": { "type": ["string", "null"] }, "web_url": { "type": ["string", "null"] },
"created_at": { "type": ["string", "null"], "format": "date-time" }, "created_at": { "type": ["string", "null"], "format": "date-time" },
"updated_at": { "type": ["string", "null"], "format": "date-time" } "updated_at": { "type": ["string", "null"], "format": "date-time" }
......
...@@ -263,6 +263,20 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do ...@@ -263,6 +263,20 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end end
end end
describe '.with_pipeline_source' do
subject { described_class.with_pipeline_source(source) }
let(:source) { 'web' }
let_it_be(:push_pipeline) { create(:ci_pipeline, source: :push) }
let_it_be(:web_pipeline) { create(:ci_pipeline, source: :web) }
let_it_be(:api_pipeline) { create(:ci_pipeline, source: :api) }
it 'contains pipelines created due to specified source' do
expect(subject).to contain_exactly(web_pipeline)
end
end
describe '.ci_sources' do describe '.ci_sources' do
subject { described_class.ci_sources } subject { described_class.ci_sources }
......
...@@ -34,8 +34,29 @@ RSpec.describe API::Ci::Pipelines do ...@@ -34,8 +34,29 @@ RSpec.describe API::Ci::Pipelines do
expect(json_response.first['sha']).to match(/\A\h{40}\z/) expect(json_response.first['sha']).to match(/\A\h{40}\z/)
expect(json_response.first['id']).to eq pipeline.id expect(json_response.first['id']).to eq pipeline.id
expect(json_response.first['web_url']).to be_present expect(json_response.first['web_url']).to be_present
end
describe 'keys in the response' do
context 'when `pipeline_source_filter` feature flag is disabled' do
before do
stub_feature_flags(pipeline_source_filter: false)
end
it 'does not includes pipeline source' do
get api("/projects/#{project.id}/pipelines", user)
expect(json_response.first.keys).to contain_exactly(*%w[id project_id sha ref status web_url created_at updated_at]) expect(json_response.first.keys).to contain_exactly(*%w[id project_id sha ref status web_url created_at updated_at])
end end
end
context 'when `pipeline_source_filter` feature flag is disabled' do
it 'includes pipeline source' do
get api("/projects/#{project.id}/pipelines", user)
expect(json_response.first.keys).to contain_exactly(*%w[id project_id sha ref status web_url created_at updated_at source])
end
end
end
context 'when parameter is passed' do context 'when parameter is passed' do
%w[running pending].each do |target| %w[running pending].each do |target|
...@@ -294,6 +315,48 @@ RSpec.describe API::Ci::Pipelines do ...@@ -294,6 +315,48 @@ RSpec.describe API::Ci::Pipelines do
end end
end end
end end
context 'when a source is specified' do
before do
create(:ci_pipeline, project: project, source: :push)
create(:ci_pipeline, project: project, source: :web)
create(:ci_pipeline, project: project, source: :api)
end
context 'when `pipeline_source_filter` feature flag is disabled' do
before do
stub_feature_flags(pipeline_source_filter: false)
end
it 'returns all pipelines' do
get api("/projects/#{project.id}/pipelines", user), params: { source: 'web' }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
expect(json_response.length).to be >= 3
end
end
context 'when `pipeline_source_filter` feature flag is enabled' do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), params: { source: 'web' }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
json_response.each { |r| expect(r['source']).to eq('web') }
end
context 'when source is invalid' do
it 'returns bad_request' do
get api("/projects/#{project.id}/pipelines", user), params: { source: 'invalid-source' }
expect(response).to have_gitlab_http_status(:bad_request)
end
end
end
end
end end
end end
......
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