diff options
-rw-r--r-- | app/models/ci/build.rb | 6 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 18 | ||||
-rw-r--r-- | app/models/concerns/has_ref.rb | 55 | ||||
-rw-r--r-- | changelogs/unreleased/expose-merge-ref-to-runner.yml | 5 | ||||
-rw-r--r-- | lib/api/entities.rb | 10 | ||||
-rw-r--r-- | spec/models/ci/build_spec.rb | 23 | ||||
-rw-r--r-- | spec/models/concerns/has_ref_spec.rb | 131 | ||||
-rw-r--r-- | spec/requests/api/runner_spec.rb | 30 |
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 |