diff --git a/changelogs/unreleased/issue_27168_2.yml b/changelogs/unreleased/issue_27168_2.yml index c91a95323d520cc3bea9d3d659353b99e1871011..c67692493e0c4c5486c2d2b3c5ba7b1ea570b779 100644 --- a/changelogs/unreleased/issue_27168_2.yml +++ b/changelogs/unreleased/issue_27168_2.yml @@ -1,4 +1,4 @@ --- -title: Preloads head pipeline for each merge request +title: Preloads head pipeline for merge request collection merge_request: author: diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 4b7d6cd840b14469997e821d9eb41c81c23e914d..8bd2065ac34a95634b8604bfe02002fca0c71efb 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -544,6 +544,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps project = merge_request.source_project project.enable_ci pipeline = create :ci_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch + merge_request.update(head_pipeline: pipeline) create :ci_build, pipeline: pipeline end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 0483c6b7879542447d7e177ecfa5346d27df8c5c..bc13a8123a599ef72e8e190562b54a396c2f1b8f 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -354,7 +354,8 @@ describe Projects::MergeRequestsController do end before do - create(:ci_empty_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch) + pipeline = create(:ci_empty_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch) + merge_request.update(head_pipeline: pipeline) end it 'returns :merge_when_pipeline_succeeds' do diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index df2714f91ff2063c5565dfddb282319677fce8b6..57826fe872b0b3db79366e3c5ed9247fe45fdfe9 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -9,10 +9,13 @@ feature 'Cycle Analytics', feature: true, js: true do let(:mr) { create_merge_request_closing_issue(issue, commit_message: "References #{issue.to_reference}") } let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha) } + before { mr.update(head_pipeline: pipeline) } + context 'as an allowed user' do context 'when project is new' do before do - project.team << [user, :master] + project.add_master(user) + mr.update(head_pipeline_id: pipeline.id) login_as(user) visit namespace_project_cycle_analytics_path(project.namespace, project) wait_for_ajax diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index f3ec80bb149298da761d77cd216d40e9bfc9b4ec..414838fa22e3c7de30cb434a4187f9b1bb244423 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -52,6 +52,9 @@ describe 'issuable list', feature: true do create(:issue, project: project, author: user) else create(:merge_request, source_project: project, source_branch: generate(:branch)) + source_branch = FFaker::Name.name + pipeline = create(:ci_empty_pipeline, project: project, ref: source_branch, status: %w(running failed success).sample, sha: 'any') + create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: source_branch, head_pipeline: pipeline) end 2.times do diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 497240803d4427b0e7c65d3cb1fda8345b1f2a24..4f9a69baad857af630571fde04d05b3e4525c39b 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -4,16 +4,18 @@ feature 'Merge immediately', :feature, :js do let(:user) { create(:user) } let(:project) { create(:project, :public) } - let(:merge_request) do + let!(:merge_request) do create(:merge_request_with_diffs, source_project: project, author: user, - title: 'Bug NS-04') + title: 'Bug NS-04', + head_pipeline: pipeline, + source_branch: pipeline.ref) end let(:pipeline) do create(:ci_pipeline, project: project, - sha: merge_request.diff_head_sha, - ref: merge_request.source_branch) + ref: 'master', + sha: project.repository.commit('master').id) end before { project.team << [user, :master] } diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb index cd540ca113a4da818690e2265d14e43762f34490..9367789c7d458dd987e6c7035301f25b3da1e2ff 100644 --- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb @@ -16,7 +16,10 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do ref: merge_request.source_branch) end - before { project.team << [user, :master] } + before do + project.add_master(user) + merge_request.update(head_pipeline_id: pipeline.id) + end context 'when there is active pipeline for merge request' do background do diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb index 449a60c1d0596e9301591ed4685905cd40bdf160..5b2798af32f1b30649c50eeaa4bec868d013a9c2 100644 --- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb +++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' feature 'Mini Pipeline Graph', :js, :feature do let(:user) { create(:user) } let(:project) { create(:project, :public) } - let(:merge_request) { create(:merge_request, source_project: project) } + let(:merge_request) { create(:merge_request, source_project: project, head_pipeline: pipeline) } let(:pipeline) { create(:ci_empty_pipeline, project: project, ref: 'master', status: 'running', sha: project.commit.id) } let(:build) { create(:ci_build, pipeline: pipeline, stage: 'test', commands: 'test') } diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 4a590e3bf689c15e103b9aed020e2791351e7c49..981989b0095677a6232d4894dd790132fd1b0cb1 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -27,6 +27,8 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu status: status) end + before { merge_request.update(head_pipeline: pipeline) } + context 'when merge requests can only be merged if the pipeline succeeds' do before do project.update_attribute(:only_allow_merge_if_pipeline_succeeds, true) diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index d918181a238ad8f8508f77cd48079062bf953ff7..02193dbfc8d83336cc5fe5fcce09c9578ea96245 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -89,6 +89,8 @@ describe 'Merge request', :feature, :js do statuses: [commit_status]) create(:ci_build, :pending, pipeline: pipeline) + merge_request.update(head_pipeline_id: pipeline.id) + visit namespace_project_merge_request_path(project.namespace, project, merge_request) end @@ -101,10 +103,15 @@ describe 'Merge request', :feature, :js do context 'when merge request is in the blocked pipeline state' do before do - create(:ci_pipeline, project: project, - sha: merge_request.diff_head_sha, - ref: merge_request.source_branch, - status: :manual) + pipeline = create( + :ci_pipeline, + project: project, + sha: merge_request.diff_head_sha, + ref: merge_request.source_branch, + status: :manual + ) + + merge_request.update(head_pipeline_id: pipeline.id) visit namespace_project_merge_request_path(project.namespace, project, @@ -129,6 +136,8 @@ describe 'Merge request', :feature, :js do statuses: [commit_status]) create(:ci_build, :pending, pipeline: pipeline) + merge_request.update(head_pipeline_id: pipeline.id) + visit namespace_project_merge_request_path(project.namespace, project, merge_request) end diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb index 0d56bdd0ebd0942b56c5d901b118c128200c8a1d..8753679e23352a08be263983cca3ac518048b3e0 100644 --- a/spec/lib/gitlab/cycle_analytics/events_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb @@ -130,6 +130,8 @@ describe 'cycle analytics events' do end before do + merge_request.update(head_pipeline_id: pipeline.id) + create(:ci_build, pipeline: pipeline, status: :success, author: user) create(:ci_build, pipeline: pipeline, status: :success, author: user) @@ -226,6 +228,8 @@ describe 'cycle analytics events' do end before do + merge_request.update(head_pipeline_id: pipeline.id) + create(:ci_build, pipeline: pipeline, status: :success, author: user) create(:ci_build, pipeline: pipeline, status: :success, author: user) diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 688e731bf156c12d26d239d88eb70e2669acbd0f..63797c0fc0ed6946c2b1345c06de01c48a264da7 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -85,6 +85,7 @@ merge_requests: - merge_requests_closing_issues - metrics - timelogs +- head_pipeline merge_request_diff: - merge_request pipelines: diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 208c8cb1c3d41a25243609b33af287e8c5943146..86ed37b50aa039a0763380159f7c21b16b819ae5 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1044,8 +1044,8 @@ describe Ci::Pipeline, models: true do let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master', sha: 'a288a022a53a5a944fae87bcec6efc87b7061808') } it "returns merge requests whose `diff_head_sha` matches the pipeline's SHA" do - merge_request = create(:merge_request, source_project: project, source_branch: pipeline.ref) allow_any_instance_of(MergeRequest).to receive(:diff_head_sha) { 'a288a022a53a5a944fae87bcec6efc87b7061808' } + merge_request = create(:merge_request, source_project: project, head_pipeline: pipeline, , source_branch: pipeline.ref) expect(pipeline.merge_requests).to eq([merge_request]) end diff --git a/spec/models/cycle_analytics/test_spec.rb b/spec/models/cycle_analytics/test_spec.rb index c2ba012a0e67b5fd99b9678912e03a12669dcecb..d0b919efcf93e69134760e5c6f6e6095af5174e3 100644 --- a/spec/models/cycle_analytics/test_spec.rb +++ b/spec/models/cycle_analytics/test_spec.rb @@ -14,6 +14,7 @@ describe 'CycleAnalytics#test', feature: true do issue = context.create(:issue, project: context.project) merge_request = context.create_merge_request_closing_issue(issue) pipeline = context.create(:ci_pipeline, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, project: context.project) + merge_request.update(head_pipeline: pipeline) { pipeline: pipeline, issue: issue } end, start_time_conditions: [["pipeline is started", -> (context, data) { data[:pipeline].run! }]], diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 6cf3dd30ead92247c83fa8ab996adfb3f7443fbc..45a5cd049a2d8017c4b1320fe12a840dfcbee9e2 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -760,13 +760,9 @@ describe MergeRequest, models: true do describe '#head_pipeline' do describe 'when the source project exists' do it 'returns the latest pipeline' do - pipeline = double(:ci_pipeline, ref: 'master') - - allow(subject).to receive(:diff_head_sha).and_return('123abc') - - expect(subject.source_project).to receive(:pipeline_for). - with('master', '123abc'). - and_return(pipeline) + sha = "123abc" + pipeline = create(:ci_empty_pipeline, project: subject.source_project, ref: 'master', status: 'running', sha: sha) + subject.update(head_pipeline: pipeline) expect(subject.head_pipeline).to eq(pipeline) end @@ -1504,11 +1500,13 @@ describe MergeRequest, models: true do describe '#mergeable_with_slash_command?' do def create_pipeline(status) - create(:ci_pipeline_with_one_job, + pipeline = create(:ci_pipeline_with_one_job, project: project, ref: merge_request.source_branch, sha: merge_request.diff_head_sha, status: status) + + merge_request.update(head_pipeline: pipeline) end let(:project) { create(:project, :public, :repository, only_allow_merge_if_pipeline_succeeds: true) } @@ -1594,7 +1592,7 @@ describe MergeRequest, models: true do context 'with running pipeline' do before do - create_pipeline(:running) + merge_request.update(head_pipeline: create_pipeline(:running)) end it 'is mergeable' do diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index c5a45949841bb5aad0678d95235de5b05b632e48..d92daa345b3089b82fda7a70db38ba38588454ec 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -122,6 +122,7 @@ describe 'cycle analytics events', api: true do mr = create_merge_request_closing_issue(issue, commit_message: "References #{issue.to_reference}") pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha) + mr.update(head_pipeline_id: pipeline.id) pipeline.run create(:ci_build, pipeline: pipeline, status: :success, author: user) diff --git a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb index 769b319327532af98552151014281075c2a44eef..b0304b3b73fe7cbeae9e4870ab678c37952687d5 100644 --- a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb @@ -82,6 +82,10 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do sha: merge_request_head, status: 'success') end + before do + mr_merge_if_green_enabled.update(head_pipeline: triggering_pipeline) + end + it "merges all merge requests with merge when the pipeline succeeds enabled" do expect(MergeWorker).to receive(:perform_async) service.trigger(triggering_pipeline) @@ -124,6 +128,8 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do sha: mr_conflict.diff_head_sha, status: 'success') end + before { mr_conflict.update(head_pipeline_id: conflict_pipeline.id) } + it 'does not merge the merge request' do expect(MergeWorker).not_to receive(:perform_async) diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 31487c0f794e9271c9ab3ac3991e7084c6858fc2..e5071c2f447cba16c9c1fb03596de5021a28fee9 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -174,11 +174,13 @@ describe MergeRequests::UpdateService, services: true do context 'with active pipeline' do before do service_mock = double - create(:ci_pipeline_with_one_job, + pipeline = create(:ci_pipeline_with_one_job, project: project, ref: merge_request.source_branch, sha: merge_request.diff_head_sha) + merge_request.update(head_pipeline_id: pipeline.id) + expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user). and_return(service_mock) expect(service_mock).to receive(:execute).with(merge_request)