summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/ci/build.rb6
-rw-r--r--app/models/ci/pipeline.rb18
-rw-r--r--app/models/concerns/has_ref.rb55
-rw-r--r--changelogs/unreleased/expose-merge-ref-to-runner.yml5
-rw-r--r--lib/api/entities.rb10
-rw-r--r--spec/models/ci/build_spec.rb23
-rw-r--r--spec/models/concerns/has_ref_spec.rb131
-rw-r--r--spec/requests/api/runner_spec.rb30
8 files changed, 245 insertions, 33 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 6b2b7e77180..21863a8197d 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -46,6 +46,7 @@ module Ci
delegate :terminal_specification, to: :runner_session, allow_nil: true
delegate :gitlab_deploy_token, to: :project
delegate :trigger_short_token, to: :trigger_request, allow_nil: true
+ delegate :merge_request?, to: :pipeline
##
# Since Gitlab 11.5, deployments records started being created right after
@@ -652,6 +653,11 @@ module Ci
project.ci_variables_for(ref: git_ref, environment: environment)
end
+ def git_depth
+ yaml_variables&.find { |variable| variable[:key] == 'GIT_DEPTH' }
+ &.dig(:value).to_i
+ end
+
def steps
[Gitlab::Ci::Build::Step.from_commands(self),
Gitlab::Ci::Build::Step.from_after_script(self)].compact
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index f0ae516a2f8..70ae5deb63b 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -395,10 +395,6 @@ module Ci
@commit ||= Commit.lazy(project, sha)
end
- def branch?
- super && !merge_request?
- end
-
def stuck?
pending_builds.any?(&:stuck?)
end
@@ -736,20 +732,6 @@ module Ci
end
end
- def git_ref
- if merge_request?
- ##
- # In the future, we're going to change this ref to
- # merge request's merged reference, such as "refs/merge-requests/:iid/merge".
- # In order to do that, we have to update GitLab-Runner's source pulling
- # logic.
- # See https://gitlab.com/gitlab-org/gitlab-runner/merge_requests/1092
- Gitlab::Git::BRANCH_REF_PREFIX + ref.to_s
- else
- super
- end
- end
-
def latest_builds_status
return 'failed' unless yaml_errors.blank?
diff --git a/app/models/concerns/has_ref.rb b/app/models/concerns/has_ref.rb
index d7089294efc..a80e4a508aa 100644
--- a/app/models/concerns/has_ref.rb
+++ b/app/models/concerns/has_ref.rb
@@ -4,14 +4,61 @@ module HasRef
extend ActiveSupport::Concern
def branch?
- !tag?
+ !tag? && !merge_request?
end
def git_ref
- if branch?
- Gitlab::Git::BRANCH_REF_PREFIX + ref.to_s
+ if merge_request?
+ ##
+ # In the future, we're going to change this ref to
+ # merge request's merged reference, such as "refs/merge-requests/:iid/merge".
+ # In order to do that, we have to update GitLab-Runner's source pulling
+ # logic.
+ # See https://gitlab.com/gitlab-org/gitlab-runner/merge_requests/1092
+ git_branch_ref
+ elsif branch?
+ git_branch_ref
elsif tag?
- Gitlab::Git::TAG_REF_PREFIX + ref.to_s
+ git_tag_ref
end
end
+
+ def ref_type
+ if merge_request?
+ 'branch'
+ elsif branch?
+ 'branch'
+ elsif tag?
+ 'tag'
+ end
+ end
+
+ def refspecs
+ spec = []
+
+ if git_depth > 0
+ if branch? || merge_request?
+ spec << "+#{git_branch_ref}:refs/remotes/origin/#{ref}"
+ elsif tag?
+ spec << "+#{git_tag_ref}:#{git_tag_ref}"
+ end
+ else
+ if branch? || merge_request? || tag?
+ spec << '+refs/heads/*:refs/remotes/origin/*'
+ spec << '+refs/tags/*:refs/tags/*'
+ end
+ end
+
+ spec
+ end
+
+ private
+
+ def git_branch_ref
+ Gitlab::Git::BRANCH_REF_PREFIX + ref.to_s
+ end
+
+ def git_tag_ref
+ Gitlab::Git::TAG_REF_PREFIX + ref.to_s
+ end
end
diff --git a/changelogs/unreleased/expose-merge-ref-to-runner.yml b/changelogs/unreleased/expose-merge-ref-to-runner.yml
new file mode 100644
index 00000000000..945f4f6e05a
--- /dev/null
+++ b/changelogs/unreleased/expose-merge-ref-to-runner.yml
@@ -0,0 +1,5 @@
+---
+title: Expose refspecs and depth to runner
+merge_request: 25233
+author:
+type: added
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 27da2c2e5ed..8f337ea2a90 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -1376,13 +1376,9 @@ module API
class GitInfo < Grape::Entity
expose :repo_url, :ref, :sha, :before_sha
- expose :ref_type do |model|
- if model.tag
- 'tag'
- else
- 'branch'
- end
- end
+ expose :ref_type
+ expose :refspecs
+ expose :git_depth, as: :depth
end
class RunnerInfo < Grape::Entity
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 47865e4d08f..385aac6fbc1 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -23,6 +23,7 @@ describe Ci::Build do
it { is_expected.to validate_presence_of(:ref) }
it { is_expected.to respond_to(:has_trace?) }
it { is_expected.to respond_to(:trace) }
+ it { is_expected.to delegate_method(:merge_request?).to(:pipeline) }
it { is_expected.to be_a(ArtifactMigratable) }
@@ -3502,6 +3503,28 @@ describe Ci::Build do
end
end
+ describe '#git_depth' do
+ subject { build.git_depth }
+
+ context 'when GIT_DEPTH variable exists' do
+ before do
+ allow(build).to receive(:yaml_variables) do
+ [{ key: 'GIT_DEPTH', value: '1' }]
+ end
+ end
+
+ it 'returns the value' do
+ is_expected.to eq(1)
+ end
+ end
+
+ context 'when GIT_DEPTH variable does not exist' do
+ it 'returns zero' do
+ is_expected.to eq(0)
+ end
+ end
+ end
+
describe '#archived?' do
context 'when build is degenerated' do
subject { create(:ci_build, :degenerated) }
diff --git a/spec/models/concerns/has_ref_spec.rb b/spec/models/concerns/has_ref_spec.rb
index 8aed72d77a4..677cf0c2762 100644
--- a/spec/models/concerns/has_ref_spec.rb
+++ b/spec/models/concerns/has_ref_spec.rb
@@ -13,17 +13,27 @@ describe HasRef do
build.tag = false
end
- it 'return true when tag is set to false' do
+ it 'return true' do
is_expected.to be_truthy
end
end
- context 'is not a tag' do
+ context 'is a tag' do
before do
build.tag = true
end
- it 'return false when tag is set to true' do
+ it 'return false' do
+ is_expected.to be_falsey
+ end
+ end
+
+ context 'when build is associated with a merge request' do
+ before do
+ allow(build).to receive(:merge_request?) { true }
+ end
+
+ it 'return false' do
is_expected.to be_falsey
end
end
@@ -55,5 +65,120 @@ describe HasRef do
is_expected.to start_with(Gitlab::Git::BRANCH_REF_PREFIX)
end
end
+
+ context 'when build is associated with a merge request' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ before do
+ allow(build).to receive(:merge_request?) { true }
+ end
+
+ it 'returns a branch ref' do
+ is_expected.to start_with(Gitlab::Git::BRANCH_REF_PREFIX)
+ end
+ end
+ end
+
+ describe '#ref_type' do
+ subject { build.ref_type }
+
+ context 'when ref is branch' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ it 'returns a correct ref type' do
+ is_expected.to eq('branch')
+ end
+ end
+
+ context 'when ref is tag' do
+ let(:build) { create(:ci_build, tag: true) }
+
+ it 'returns a correct ref type' do
+ is_expected.to eq('tag')
+ end
+ end
+
+ context 'when build is associated with a merge request' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ before do
+ allow(build).to receive(:merge_request?) { true }
+ end
+
+ it 'returns a correct ref type' do
+ is_expected.to eq('branch')
+ end
+ end
+ end
+
+ describe '#refspecs' do
+ subject { build.refspecs }
+
+ context 'when depth is specified' do
+ before do
+ allow(build).to receive(:git_depth) { 1 }
+ end
+
+ context 'when ref is branch' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ it 'returns correct refspecs' do
+ is_expected.to include("+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}")
+ end
+ end
+
+ context 'when ref is tag' do
+ let(:build) { create(:ci_build, tag: true) }
+
+ it 'returns correct refspecs' do
+ is_expected.to include("+refs/tags/#{build.ref}:refs/tags/#{build.ref}")
+ end
+ end
+
+ context 'when build is associated with a merge request' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ before do
+ allow(build).to receive(:merge_request?) { true }
+ end
+
+ it 'returns correct refspecs' do
+ is_expected.to include("+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}")
+ end
+ end
+ end
+
+ context 'when depth is not specified' do
+ context 'when ref is branch' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ it 'returns correct refspecs' do
+ is_expected.to contain_exactly('+refs/heads/*:refs/remotes/origin/*',
+ '+refs/tags/*:refs/tags/*')
+ end
+ end
+
+ context 'when ref is tag' do
+ let(:build) { create(:ci_build, tag: true) }
+
+ it 'returns correct refspecs' do
+ is_expected.to contain_exactly('+refs/heads/*:refs/remotes/origin/*',
+ '+refs/tags/*:refs/tags/*')
+ end
+ end
+
+ context 'when build is associated with a merge request' do
+ let(:build) { create(:ci_build, tag: false) }
+
+ before do
+ allow(build).to receive(:merge_request?) { true }
+ end
+
+ it 'returns correct refspecs' do
+ is_expected.to contain_exactly('+refs/heads/*:refs/remotes/origin/*',
+ '+refs/tags/*:refs/tags/*')
+ end
+ end
+ end
end
end
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index d7ddd97e8c8..fa3982f3d25 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -417,7 +417,9 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
'ref' => job.ref,
'sha' => job.sha,
'before_sha' => job.before_sha,
- 'ref_type' => 'branch' }
+ 'ref_type' => 'branch',
+ 'refspecs' => %w[+refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*],
+ 'depth' => 0 }
end
let(:expected_steps) do
@@ -489,6 +491,19 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
expect(response).to have_gitlab_http_status(201)
expect(json_response['git_info']['ref_type']).to eq('tag')
end
+
+ context 'when GIT_DEPTH is specified' do
+ before do
+ allow_any_instance_of(Ci::Build).to receive(:git_depth) { 1 }
+ end
+
+ it 'specifies refspecs' do
+ request_job
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['git_info']['refspecs']).to include("+refs/tags/#{job.ref}:refs/tags/#{job.ref}")
+ end
+ end
end
context 'when job is made for branch' do
@@ -498,6 +513,19 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
expect(response).to have_gitlab_http_status(201)
expect(json_response['git_info']['ref_type']).to eq('branch')
end
+
+ context 'when GIT_DEPTH is specified' do
+ before do
+ allow_any_instance_of(Ci::Build).to receive(:git_depth) { 1 }
+ end
+
+ it 'specifies refspecs' do
+ request_job
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['git_info']['refspecs']).to include("+refs/heads/#{job.ref}:refs/remotes/origin/#{job.ref}")
+ end
+ end
end
it 'updates runner info' do