Commit 411a3563 authored by Fabio Pitino's avatar Fabio Pitino Committed by Stan Hu

Pass "skip_ci" parameter to MR rebase API

* Let `skip_ci` to be passed to the API endpoint
* Add doc entry
* Add changelog entry
parent 995ed49e
...@@ -449,7 +449,7 @@ class MergeRequest < ApplicationRecord ...@@ -449,7 +449,7 @@ class MergeRequest < ApplicationRecord
# Set off a rebase asynchronously, atomically updating the `rebase_jid` of # Set off a rebase asynchronously, atomically updating the `rebase_jid` of
# the MR so that the status of the operation can be tracked. # the MR so that the status of the operation can be tracked.
def rebase_async(user_id) def rebase_async(user_id, skip_ci: false)
with_rebase_lock do with_rebase_lock do
raise ActiveRecord::StaleObjectError if !open? || rebase_in_progress? raise ActiveRecord::StaleObjectError if !open? || rebase_in_progress?
...@@ -458,7 +458,7 @@ class MergeRequest < ApplicationRecord ...@@ -458,7 +458,7 @@ class MergeRequest < ApplicationRecord
# attribute is set *and* that the sidekiq job is still running. So a JID # attribute is set *and* that the sidekiq job is still running. So a JID
# for a completed RebaseWorker is equivalent to a nil JID. # for a completed RebaseWorker is equivalent to a nil JID.
jid = Sidekiq::Worker.skipping_transaction_check do jid = Sidekiq::Worker.skipping_transaction_check do
RebaseWorker.perform_async(id, user_id) RebaseWorker.perform_async(id, user_id, skip_ci)
end end
update_column(:rebase_jid, jid) update_column(:rebase_jid, jid)
......
...@@ -8,8 +8,9 @@ module MergeRequests ...@@ -8,8 +8,9 @@ module MergeRequests
attr_reader :merge_request attr_reader :merge_request
def execute(merge_request) def execute(merge_request, skip_ci: false)
@merge_request = merge_request @merge_request = merge_request
@skip_ci = skip_ci
if rebase if rebase
success success
...@@ -25,7 +26,7 @@ module MergeRequests ...@@ -25,7 +26,7 @@ module MergeRequests
return false return false
end end
repository.rebase(current_user, merge_request) repository.rebase(current_user, merge_request, skip_ci: @skip_ci)
true true
rescue => e rescue => e
......
...@@ -7,12 +7,12 @@ class RebaseWorker ...@@ -7,12 +7,12 @@ class RebaseWorker
feature_category :source_code_management feature_category :source_code_management
def perform(merge_request_id, current_user_id) def perform(merge_request_id, current_user_id, skip_ci = false)
current_user = User.find(current_user_id) current_user = User.find(current_user_id)
merge_request = MergeRequest.find(merge_request_id) merge_request = MergeRequest.find(merge_request_id)
MergeRequests::RebaseService MergeRequests::RebaseService
.new(merge_request.source_project, current_user) .new(merge_request.source_project, current_user)
.execute(merge_request) .execute(merge_request, skip_ci: skip_ci)
end end
end end
---
title: Allow "skip_ci" flag to be passed to rebase operation
merge_request: 22800
author:
type: added
...@@ -1613,6 +1613,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/rebase ...@@ -1613,6 +1613,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/rebase
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `merge_request_iid` | integer | yes | The internal ID of the merge request | | `merge_request_iid` | integer | yes | The internal ID of the merge request |
| `skip_ci` | boolean | no | Set to `true` to skip creating a CI pipeline |
```bash ```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/76/merge_requests/1/rebase curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/76/merge_requests/1/rebase
......
...@@ -366,7 +366,7 @@ describe Projects::MergeRequestsController do ...@@ -366,7 +366,7 @@ describe Projects::MergeRequestsController do
end end
def expect_rebase_worker_for(user) def expect_rebase_worker_for(user)
expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id) expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id, false)
end end
context 'approvals pending' do context 'approvals pending' do
......
...@@ -439,12 +439,15 @@ module API ...@@ -439,12 +439,15 @@ module API
desc 'Rebase the merge request against its target branch' do desc 'Rebase the merge request against its target branch' do
detail 'This feature was added in GitLab 11.6' detail 'This feature was added in GitLab 11.6'
end end
params do
optional :skip_ci, type: Boolean, desc: 'Do not create CI pipeline'
end
put ':id/merge_requests/:merge_request_iid/rebase' do put ':id/merge_requests/:merge_request_iid/rebase' do
merge_request = find_project_merge_request(params[:merge_request_iid]) merge_request = find_project_merge_request(params[:merge_request_iid])
authorize_push_to_merge_request!(merge_request) authorize_push_to_merge_request!(merge_request)
merge_request.rebase_async(current_user.id) merge_request.rebase_async(current_user.id, skip_ci: params[:skip_ci])
status :accepted status :accepted
present rebase_in_progress: merge_request.rebase_in_progress? present rebase_in_progress: merge_request.rebase_in_progress?
......
...@@ -256,7 +256,8 @@ module Gitlab ...@@ -256,7 +256,8 @@ module Gitlab
branch: encode_binary(branch), branch: encode_binary(branch),
branch_sha: branch_sha, branch_sha: branch_sha,
remote_repository: remote_repository.gitaly_repository, remote_repository: remote_repository.gitaly_repository,
remote_branch: encode_binary(remote_branch) remote_branch: encode_binary(remote_branch),
skip_ci: skip_ci
) )
) )
) )
......
...@@ -1376,7 +1376,7 @@ describe Projects::MergeRequestsController do ...@@ -1376,7 +1376,7 @@ describe Projects::MergeRequestsController do
end end
def expect_rebase_worker_for(user) def expect_rebase_worker_for(user)
expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id) expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id, false)
end end
context 'successfully' do context 'successfully' do
......
...@@ -2022,7 +2022,7 @@ describe MergeRequest do ...@@ -2022,7 +2022,7 @@ describe MergeRequest do
it 'atomically enqueues a RebaseWorker job and updates rebase_jid' do it 'atomically enqueues a RebaseWorker job and updates rebase_jid' do
expect(RebaseWorker) expect(RebaseWorker)
.to receive(:perform_async) .to receive(:perform_async)
.with(merge_request.id, user_id) .with(merge_request.id, user_id, false)
.and_return(rebase_jid) .and_return(rebase_jid)
expect(merge_request).to receive(:expire_etag_cache) expect(merge_request).to receive(:expire_etag_cache)
......
...@@ -2222,16 +2222,34 @@ describe API::MergeRequests do ...@@ -2222,16 +2222,34 @@ describe API::MergeRequests do
end end
describe 'PUT :id/merge_requests/:merge_request_iid/rebase' do describe 'PUT :id/merge_requests/:merge_request_iid/rebase' do
it 'enqueues a rebase of the merge request against the target branch' do context 'when rebase can be performed' do
Sidekiq::Testing.fake! do it 'enqueues a rebase of the merge request against the target branch' do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user) Sidekiq::Testing.fake! do
expect do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user)
end.to change { RebaseWorker.jobs.size }.by(1)
end
expect(response).to have_gitlab_http_status(202)
expect(merge_request.reload).to be_rebase_in_progress
expect(json_response['rebase_in_progress']).to be(true)
end end
expect(response).to have_gitlab_http_status(202) context 'when skip_ci parameter is set' do
expect(RebaseWorker.jobs.size).to eq(1) it 'enqueues a rebase of the merge request with skip_ci flag set' do
expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id, true).and_call_original
expect(merge_request.reload).to be_rebase_in_progress Sidekiq::Testing.fake! do
expect(json_response['rebase_in_progress']).to be(true) expect do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user), params: { skip_ci: true }
end.to change { RebaseWorker.jobs.size }.by(1)
end
expect(response).to have_gitlab_http_status(202)
expect(merge_request.reload).to be_rebase_in_progress
expect(json_response['rebase_in_progress']).to be(true)
end
end
end end
it 'returns 403 if the user cannot push to the branch' do it 'returns 403 if the user cannot push to the branch' do
......
...@@ -15,6 +15,7 @@ describe MergeRequests::RebaseService do ...@@ -15,6 +15,7 @@ describe MergeRequests::RebaseService do
end end
let(:project) { merge_request.project } let(:project) { merge_request.project }
let(:repository) { project.repository.raw } let(:repository) { project.repository.raw }
let(:skip_ci) { false }
subject(:service) { described_class.new(project, user, {}) } subject(:service) { described_class.new(project, user, {}) }
...@@ -115,7 +116,7 @@ describe MergeRequests::RebaseService do ...@@ -115,7 +116,7 @@ describe MergeRequests::RebaseService do
context 'valid params' do context 'valid params' do
shared_examples_for 'a service that can execute a successful rebase' do shared_examples_for 'a service that can execute a successful rebase' do
before do before do
service.execute(merge_request) service.execute(merge_request, skip_ci: skip_ci)
end end
it 'rebases source branch' do it 'rebases source branch' do
...@@ -155,6 +156,12 @@ describe MergeRequests::RebaseService do ...@@ -155,6 +156,12 @@ describe MergeRequests::RebaseService do
it_behaves_like 'a service that can execute a successful rebase' it_behaves_like 'a service that can execute a successful rebase'
end end
context 'when skip_ci flag is set' do
let(:skip_ci) { true }
it_behaves_like 'a service that can execute a successful rebase'
end
context 'fork' do context 'fork' do
describe 'successful fork rebase' do describe 'successful fork rebase' do
let(:forked_project) do let(:forked_project) do
......
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