Commit ca6fbe8a authored by Douwe Maan's avatar Douwe Maan

Merge branch '18667-handle-push-opts' into 'master'

Handle 'git push -o ci.skip'

Closes #18667

See merge request gitlab-org/gitlab-ce!15643
parents 28cffb9f ba781484
......@@ -31,7 +31,8 @@ module Ci
seeds_block: block,
variables_attributes: params[:variables_attributes],
project: project,
current_user: current_user)
current_user: current_user,
push_options: params[:push_options])
sequence = Gitlab::Ci::Pipeline::Chain::Sequence
.new(pipeline, command, SEQUENCE)
......
......@@ -174,7 +174,8 @@ class GitPushService < BaseService
params[:newrev],
params[:ref],
@push_commits,
commits_count: commits_count)
commits_count: commits_count,
push_options: params[:push_options] || [])
end
def push_to_existing_branch?
......
......@@ -45,7 +45,8 @@ class GitTagPushService < BaseService
params[:newrev],
params[:ref],
commits,
message)
message,
push_options: params[:push_options] || [])
end
def build_system_push_data
......
......@@ -3,7 +3,7 @@
class PostReceive
include ApplicationWorker
def perform(gl_repository, identifier, changes)
def perform(gl_repository, identifier, changes, push_options = [])
project, is_wiki = Gitlab::GlRepository.parse(gl_repository)
if project.nil?
......@@ -15,7 +15,7 @@ class PostReceive
# Use Sidekiq.logger so arguments can be correlated with execution
# time and thread ID's.
Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS']
post_received = Gitlab::GitPostReceive.new(project, identifier, changes)
post_received = Gitlab::GitPostReceive.new(project, identifier, changes, push_options)
if is_wiki
process_wiki_changes(post_received)
......@@ -38,9 +38,21 @@ class PostReceive
post_received.changes_refs do |oldrev, newrev, ref|
if Gitlab::Git.tag_ref?(ref)
GitTagPushService.new(post_received.project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute
GitTagPushService.new(
post_received.project,
@user,
oldrev: oldrev,
newrev: newrev,
ref: ref,
push_options: post_received.push_options).execute
elsif Gitlab::Git.branch_ref?(ref)
GitPushService.new(post_received.project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute
GitPushService.new(
post_received.project,
@user,
oldrev: oldrev,
newrev: newrev,
ref: ref,
push_options: post_received.push_options).execute
end
changes << Gitlab::DataBuilder::Repository.single_change(oldrev, newrev, ref)
......
---
title: Handle ci.skip push option
merge_request: 15643
author: Jonathon Reinhart
type: added
......@@ -2200,6 +2200,12 @@ with an API call.
If your commit message contains `[ci skip]` or `[skip ci]`, using any
capitalization, the commit will be created but the pipeline will be skipped.
Alternatively, one can pass the `ci.skip` [Git push option][push-option] if
using Git 2.10 or newer:
```
$ git push -o ci.skip
```
## Validate the .gitlab-ci.yml
Each instance of GitLab CI has an embedded debug tool called Lint, which validates the
......@@ -2224,3 +2230,4 @@ GitLab CI/CD with various languages.
[environment]: ../environments.md "CI/CD environments"
[schedules]: ../../user/project/pipelines/schedules.md "Pipelines schedules"
[variables]: ../variables/README.md "CI/CD variables"
[push-option]: https://git-scm.com/docs/git-push#git-push--oltoptiongt
......@@ -256,8 +256,9 @@ module API
post '/post_receive' do
status 200
PostReceive.perform_async(params[:gl_repository], params[:identifier],
params[:changes])
params[:changes], params[:push_options].to_a)
broadcast_message = BroadcastMessage.current&.last&.message
reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
......
......@@ -10,7 +10,7 @@ module Gitlab
:origin_ref, :checkout_sha, :after_sha, :before_sha,
:trigger_request, :schedule, :merge_request,
:ignore_skip_ci, :save_incompleted,
:seeds_block, :variables_attributes
:seeds_block, :variables_attributes, :push_options
) do
include Gitlab::Utils::StrongMemoize
......
......@@ -8,6 +8,7 @@ module Gitlab
include ::Gitlab::Utils::StrongMemoize
SKIP_PATTERN = /\[(ci[ _-]skip|skip[ _-]ci)\]/i
SKIP_PUSH_OPTION = 'ci.skip'
def perform!
if skipped?
......@@ -16,7 +17,7 @@ module Gitlab
end
def skipped?
!@command.ignore_skip_ci && commit_message_skips_ci?
!@command.ignore_skip_ci && (commit_message_skips_ci? || push_option_skips_ci?)
end
def break?
......@@ -32,6 +33,10 @@ module Gitlab
!!(@pipeline.git_commit_message =~ SKIP_PATTERN)
end
end
def push_option_skips_ci?
!!(@command.push_options&.include?(SKIP_PUSH_OPTION))
end
end
end
end
......
......@@ -31,7 +31,11 @@ module Gitlab
}
}
],
total_commits_count: 1
total_commits_count: 1,
push_options: [
"ci.skip",
"custom option"
]
}.freeze
# Produce a hash of post-receive data
......@@ -52,10 +56,12 @@ module Gitlab
# homepage: String,
# },
# commits: Array,
# total_commits_count: Fixnum
# total_commits_count: Fixnum,
# push_options: Array
# }
#
def build(project, user, oldrev, newrev, ref, commits = [], message = nil, commits_count: nil)
# rubocop:disable Metrics/ParameterLists
def build(project, user, oldrev, newrev, ref, commits = [], message = nil, commits_count: nil, push_options: [])
commits = Array(commits)
# Total commits count
......@@ -93,6 +99,7 @@ module Gitlab
project: project.hook_attrs,
commits: commit_attrs,
total_commits_count: commits_count,
push_options: push_options,
# DEPRECATED
repository: project.hook_attrs.slice(:name, :url, :description, :homepage,
:git_http_url, :git_ssh_url, :visibility_level)
......
......@@ -3,12 +3,13 @@
module Gitlab
class GitPostReceive
include Gitlab::Identifier
attr_reader :project, :identifier, :changes
attr_reader :project, :identifier, :changes, :push_options
def initialize(project, identifier, changes)
def initialize(project, identifier, changes, push_options)
@project = project
@identifier = identifier
@changes = deserialize_changes(changes)
@push_options = push_options
end
def identify
......
......@@ -809,7 +809,8 @@ describe API::Internal do
gl_repository: gl_repository,
secret_token: secret_token,
identifier: identifier,
changes: changes
changes: changes,
push_options: push_options
}
end
......@@ -817,6 +818,11 @@ describe API::Internal do
"#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch"
end
let(:push_options) do
['ci.skip',
'another push option']
end
before do
project.add_developer(user)
allow(described_class).to receive(:identify).and_return(user)
......@@ -825,7 +831,7 @@ describe API::Internal do
it 'enqueues a PostReceive worker job' do
expect(PostReceive).to receive(:perform_async)
.with(gl_repository, identifier, changes)
.with(gl_repository, identifier, changes, push_options)
post api("/internal/post_receive"), params: valid_params
end
......
......@@ -19,12 +19,14 @@ describe Ci::CreatePipelineService do
ref: ref_name,
trigger_request: nil,
variables_attributes: nil,
merge_request: nil)
merge_request: nil,
push_options: nil)
params = { ref: ref,
before: '00000000',
after: after,
commits: [{ message: message }],
variables_attributes: variables_attributes }
variables_attributes: variables_attributes,
push_options: push_options }
described_class.new(project, user, params).execute(
source, trigger_request: trigger_request, merge_request: merge_request)
......@@ -357,6 +359,22 @@ describe Ci::CreatePipelineService do
end
end
context 'when push options contain ci.skip' do
let(:push_options) do
['ci.skip',
'another push option']
end
it 'creates a pipline in the skipped state' do
pipeline = execute_service(push_options: push_options)
# TODO: DRY these up with "skips builds creation if the commit message"
expect(pipeline).to be_persisted
expect(pipeline.builds.any?).to be false
expect(pipeline.status).to eq("skipped")
end
end
context 'when there are no jobs for this pipeline' do
before do
config = YAML.dump({ test: { script: 'ls', only: ['feature'] } })
......
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