From c2dde81205965f6e91de1bd97b5a2d37fe90ac2b Mon Sep 17 00:00:00 2001 From: Dylan Griffith <dyl.griffith@gmail.com> Date: Thu, 2 Dec 2021 17:03:18 +1100 Subject: [PATCH] Ensure ci_pipelines.iid set before transaction in commit status API Prior to this we were using `create!` which triggered the `ensure_project_iid!` in a callback. This causes a `CrossDatabaseModificationAcrossUnsupportedTablesError`. To avoid this we will create the `iid` before saving. This is consistent with all other places we create pipelines. This change still doesn't allow us to remove `spec/requests/api/commit_statuses_spec.rb` from the allowlist as there are other calls to `project.ci_pipelines.create!` in this file. We need a more holistic solution for that which is being discussed in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75316 . --- lib/api/commit_statuses.rb | 5 ++++- spec/requests/api/commit_statuses_spec.rb | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 1785362656e4..c89abf72e2de 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -78,13 +78,16 @@ class CommitStatuses < ::API::Base name = params[:name] || params[:context] || 'default' - pipeline ||= user_project.ci_pipelines.create!( + pipeline ||= user_project.ci_pipelines.build( source: :external, sha: commit.sha, ref: ref, user: current_user, protected: user_project.protected_for?(ref)) + pipeline.ensure_project_iid! + pipeline.save! + authorize! :update_pipeline, pipeline status = GenericCommitStatus.running_or_pending.find_or_initialize_by( diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index 47bc3eb74a64..155d9a36e176 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -131,7 +131,7 @@ def create_status(commit, opts = {}) %w[pending running success failed canceled].each do |status| context "for #{status}" do context 'when pipeline for sha does not exists' do - it 'creates commit status' do + it 'creates commit status and sets pipeline iid' do post api(post_url, developer), params: { state: status } expect(response).to have_gitlab_http_status(:created) @@ -145,6 +145,8 @@ def create_status(commit, opts = {}) if status == 'failed' expect(CommitStatus.find(json_response['id'])).to be_api_failure end + + expect(::Ci::Pipeline.last.iid).not_to be_nil end end end -- GitLab