337 lines
12 KiB
Ruby
337 lines
12 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
require 'spec_helper'
|
||
|
|
||
|
RSpec.describe Gitlab::Ci::Variables::Builder::Pipeline, feature_category: :pipeline_authoring do
|
||
|
let_it_be(:project) { create_default(:project, :repository, create_tag: 'test').freeze }
|
||
|
let_it_be(:user) { create(:user) }
|
||
|
|
||
|
let(:pipeline) { build(:ci_empty_pipeline, :created, project: project) }
|
||
|
|
||
|
describe '#predefined_variables' do
|
||
|
subject { described_class.new(pipeline).predefined_variables }
|
||
|
|
||
|
it 'includes all predefined variables in a valid order' do
|
||
|
keys = subject.pluck(:key)
|
||
|
|
||
|
expect(keys).to contain_exactly(*%w[
|
||
|
CI_PIPELINE_IID
|
||
|
CI_PIPELINE_SOURCE
|
||
|
CI_PIPELINE_CREATED_AT
|
||
|
CI_COMMIT_SHA
|
||
|
CI_COMMIT_SHORT_SHA
|
||
|
CI_COMMIT_BEFORE_SHA
|
||
|
CI_COMMIT_REF_NAME
|
||
|
CI_COMMIT_REF_SLUG
|
||
|
CI_COMMIT_BRANCH
|
||
|
CI_COMMIT_MESSAGE
|
||
|
CI_COMMIT_TITLE
|
||
|
CI_COMMIT_DESCRIPTION
|
||
|
CI_COMMIT_REF_PROTECTED
|
||
|
CI_COMMIT_TIMESTAMP
|
||
|
CI_COMMIT_AUTHOR
|
||
|
CI_BUILD_REF
|
||
|
CI_BUILD_BEFORE_SHA
|
||
|
CI_BUILD_REF_NAME
|
||
|
CI_BUILD_REF_SLUG
|
||
|
])
|
||
|
end
|
||
|
|
||
|
context 'when the pipeline is running for a tag' do
|
||
|
let(:pipeline) { build(:ci_empty_pipeline, :created, project: project, ref: 'test', tag: true) }
|
||
|
|
||
|
it 'includes all predefined variables in a valid order' do
|
||
|
keys = subject.pluck(:key)
|
||
|
|
||
|
expect(keys).to contain_exactly(*%w[
|
||
|
CI_PIPELINE_IID
|
||
|
CI_PIPELINE_SOURCE
|
||
|
CI_PIPELINE_CREATED_AT
|
||
|
CI_COMMIT_SHA
|
||
|
CI_COMMIT_SHORT_SHA
|
||
|
CI_COMMIT_BEFORE_SHA
|
||
|
CI_COMMIT_REF_NAME
|
||
|
CI_COMMIT_REF_SLUG
|
||
|
CI_COMMIT_MESSAGE
|
||
|
CI_COMMIT_TITLE
|
||
|
CI_COMMIT_DESCRIPTION
|
||
|
CI_COMMIT_REF_PROTECTED
|
||
|
CI_COMMIT_TIMESTAMP
|
||
|
CI_COMMIT_AUTHOR
|
||
|
CI_BUILD_REF
|
||
|
CI_BUILD_BEFORE_SHA
|
||
|
CI_BUILD_REF_NAME
|
||
|
CI_BUILD_REF_SLUG
|
||
|
CI_COMMIT_TAG
|
||
|
CI_COMMIT_TAG_MESSAGE
|
||
|
CI_BUILD_TAG
|
||
|
])
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when merge request is present' do
|
||
|
let_it_be(:assignees) { create_list(:user, 2) }
|
||
|
let_it_be(:milestone) { create(:milestone, project: project) }
|
||
|
let_it_be(:labels) { create_list(:label, 2) }
|
||
|
|
||
|
let(:merge_request) do
|
||
|
create(:merge_request, :simple,
|
||
|
source_project: project,
|
||
|
target_project: project,
|
||
|
assignees: assignees,
|
||
|
milestone: milestone,
|
||
|
labels: labels)
|
||
|
end
|
||
|
|
||
|
context 'when pipeline for merge request is created' do
|
||
|
let(:pipeline) do
|
||
|
create(:ci_pipeline, :detached_merge_request_pipeline,
|
||
|
ci_ref_presence: false,
|
||
|
user: user,
|
||
|
merge_request: merge_request)
|
||
|
end
|
||
|
|
||
|
before do
|
||
|
project.add_developer(user)
|
||
|
end
|
||
|
|
||
|
it 'exposes merge request pipeline variables' do
|
||
|
expect(subject.to_hash)
|
||
|
.to include(
|
||
|
'CI_MERGE_REQUEST_ID' => merge_request.id.to_s,
|
||
|
'CI_MERGE_REQUEST_IID' => merge_request.iid.to_s,
|
||
|
'CI_MERGE_REQUEST_REF_PATH' => merge_request.ref_path.to_s,
|
||
|
'CI_MERGE_REQUEST_PROJECT_ID' => merge_request.project.id.to_s,
|
||
|
'CI_MERGE_REQUEST_PROJECT_PATH' => merge_request.project.full_path,
|
||
|
'CI_MERGE_REQUEST_PROJECT_URL' => merge_request.project.web_url,
|
||
|
'CI_MERGE_REQUEST_TARGET_BRANCH_NAME' => merge_request.target_branch.to_s,
|
||
|
'CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED' => ProtectedBranch.protected?(
|
||
|
merge_request.target_project,
|
||
|
merge_request.target_branch
|
||
|
).to_s,
|
||
|
'CI_MERGE_REQUEST_TARGET_BRANCH_SHA' => '',
|
||
|
'CI_MERGE_REQUEST_SOURCE_PROJECT_ID' => merge_request.source_project.id.to_s,
|
||
|
'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH' => merge_request.source_project.full_path,
|
||
|
'CI_MERGE_REQUEST_SOURCE_PROJECT_URL' => merge_request.source_project.web_url,
|
||
|
'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' => merge_request.source_branch.to_s,
|
||
|
'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA' => '',
|
||
|
'CI_MERGE_REQUEST_TITLE' => merge_request.title,
|
||
|
'CI_MERGE_REQUEST_ASSIGNEES' => merge_request.assignee_username_list,
|
||
|
'CI_MERGE_REQUEST_MILESTONE' => milestone.title,
|
||
|
'CI_MERGE_REQUEST_LABELS' => labels.map(&:title).sort.join(','),
|
||
|
'CI_MERGE_REQUEST_EVENT_TYPE' => 'detached',
|
||
|
'CI_OPEN_MERGE_REQUESTS' => merge_request.to_reference(full: true))
|
||
|
end
|
||
|
|
||
|
it 'exposes diff variables' do
|
||
|
expect(subject.to_hash)
|
||
|
.to include(
|
||
|
'CI_MERGE_REQUEST_DIFF_ID' => merge_request.merge_request_diff.id.to_s,
|
||
|
'CI_MERGE_REQUEST_DIFF_BASE_SHA' => merge_request.merge_request_diff.base_commit_sha)
|
||
|
end
|
||
|
|
||
|
context 'without assignee' do
|
||
|
let(:assignees) { [] }
|
||
|
|
||
|
it 'does not expose assignee variable' do
|
||
|
expect(subject.to_hash.keys).not_to include('CI_MERGE_REQUEST_ASSIGNEES')
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'without milestone' do
|
||
|
let(:milestone) { nil }
|
||
|
|
||
|
it 'does not expose milestone variable' do
|
||
|
expect(subject.to_hash.keys).not_to include('CI_MERGE_REQUEST_MILESTONE')
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'without labels' do
|
||
|
let(:labels) { [] }
|
||
|
|
||
|
it 'does not expose labels variable' do
|
||
|
expect(subject.to_hash.keys).not_to include('CI_MERGE_REQUEST_LABELS')
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when pipeline on branch is created' do
|
||
|
let(:pipeline) do
|
||
|
create(:ci_pipeline, project: project, user: user, ref: 'feature')
|
||
|
end
|
||
|
|
||
|
context 'when a merge request is created' do
|
||
|
before do
|
||
|
merge_request
|
||
|
end
|
||
|
|
||
|
context 'when user has access to project' do
|
||
|
before do
|
||
|
project.add_developer(user)
|
||
|
end
|
||
|
|
||
|
it 'merge request references are returned matching the pipeline' do
|
||
|
expect(subject.to_hash).to include(
|
||
|
'CI_OPEN_MERGE_REQUESTS' => merge_request.to_reference(full: true))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when user does not have access to project' do
|
||
|
it 'CI_OPEN_MERGE_REQUESTS is not returned' do
|
||
|
expect(subject.to_hash).not_to have_key('CI_OPEN_MERGE_REQUESTS')
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when no a merge request is created' do
|
||
|
it 'CI_OPEN_MERGE_REQUESTS is not returned' do
|
||
|
expect(subject.to_hash).not_to have_key('CI_OPEN_MERGE_REQUESTS')
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'with merged results' do
|
||
|
let(:pipeline) do
|
||
|
create(:ci_pipeline, :merged_result_pipeline, merge_request: merge_request)
|
||
|
end
|
||
|
|
||
|
it 'exposes merge request pipeline variables' do
|
||
|
expect(subject.to_hash)
|
||
|
.to include(
|
||
|
'CI_MERGE_REQUEST_ID' => merge_request.id.to_s,
|
||
|
'CI_MERGE_REQUEST_IID' => merge_request.iid.to_s,
|
||
|
'CI_MERGE_REQUEST_REF_PATH' => merge_request.ref_path.to_s,
|
||
|
'CI_MERGE_REQUEST_PROJECT_ID' => merge_request.project.id.to_s,
|
||
|
'CI_MERGE_REQUEST_PROJECT_PATH' => merge_request.project.full_path,
|
||
|
'CI_MERGE_REQUEST_PROJECT_URL' => merge_request.project.web_url,
|
||
|
'CI_MERGE_REQUEST_TARGET_BRANCH_NAME' => merge_request.target_branch.to_s,
|
||
|
'CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED' => ProtectedBranch.protected?(
|
||
|
merge_request.target_project,
|
||
|
merge_request.target_branch
|
||
|
).to_s,
|
||
|
'CI_MERGE_REQUEST_TARGET_BRANCH_SHA' => merge_request.target_branch_sha,
|
||
|
'CI_MERGE_REQUEST_SOURCE_PROJECT_ID' => merge_request.source_project.id.to_s,
|
||
|
'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH' => merge_request.source_project.full_path,
|
||
|
'CI_MERGE_REQUEST_SOURCE_PROJECT_URL' => merge_request.source_project.web_url,
|
||
|
'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' => merge_request.source_branch.to_s,
|
||
|
'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA' => merge_request.source_branch_sha,
|
||
|
'CI_MERGE_REQUEST_TITLE' => merge_request.title,
|
||
|
'CI_MERGE_REQUEST_ASSIGNEES' => merge_request.assignee_username_list,
|
||
|
'CI_MERGE_REQUEST_MILESTONE' => milestone.title,
|
||
|
'CI_MERGE_REQUEST_LABELS' => labels.map(&:title).sort.join(','),
|
||
|
'CI_MERGE_REQUEST_EVENT_TYPE' => 'merged_result')
|
||
|
end
|
||
|
|
||
|
it 'exposes diff variables' do
|
||
|
expect(subject.to_hash)
|
||
|
.to include(
|
||
|
'CI_MERGE_REQUEST_DIFF_ID' => merge_request.merge_request_diff.id.to_s,
|
||
|
'CI_MERGE_REQUEST_DIFF_BASE_SHA' => merge_request.merge_request_diff.base_commit_sha)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when source is external pull request' do
|
||
|
let(:pipeline) do
|
||
|
create(:ci_pipeline, source: :external_pull_request_event, external_pull_request: pull_request)
|
||
|
end
|
||
|
|
||
|
let(:pull_request) { create(:external_pull_request, project: project) }
|
||
|
|
||
|
it 'exposes external pull request pipeline variables' do
|
||
|
expect(subject.to_hash)
|
||
|
.to include(
|
||
|
'CI_EXTERNAL_PULL_REQUEST_IID' => pull_request.pull_request_iid.to_s,
|
||
|
'CI_EXTERNAL_PULL_REQUEST_SOURCE_REPOSITORY' => pull_request.source_repository,
|
||
|
'CI_EXTERNAL_PULL_REQUEST_TARGET_REPOSITORY' => pull_request.target_repository,
|
||
|
'CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_SHA' => pull_request.source_sha,
|
||
|
'CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_SHA' => pull_request.target_sha,
|
||
|
'CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_NAME' => pull_request.source_branch,
|
||
|
'CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME' => pull_request.target_branch
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe 'variable CI_KUBERNETES_ACTIVE' do
|
||
|
context 'when pipeline.has_kubernetes_active? is true' do
|
||
|
before do
|
||
|
allow(pipeline).to receive(:has_kubernetes_active?).and_return(true)
|
||
|
end
|
||
|
|
||
|
it "is included with value 'true'" do
|
||
|
expect(subject.to_hash).to include('CI_KUBERNETES_ACTIVE' => 'true')
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when pipeline.has_kubernetes_active? is false' do
|
||
|
before do
|
||
|
allow(pipeline).to receive(:has_kubernetes_active?).and_return(false)
|
||
|
end
|
||
|
|
||
|
it 'is not included' do
|
||
|
expect(subject.to_hash).not_to have_key('CI_KUBERNETES_ACTIVE')
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe 'variable CI_GITLAB_FIPS_MODE' do
|
||
|
context 'when FIPS flag is enabled' do
|
||
|
before do
|
||
|
allow(Gitlab::FIPS).to receive(:enabled?).and_return(true)
|
||
|
end
|
||
|
|
||
|
it "is included with value 'true'" do
|
||
|
expect(subject.to_hash).to include('CI_GITLAB_FIPS_MODE' => 'true')
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when FIPS flag is disabled' do
|
||
|
before do
|
||
|
allow(Gitlab::FIPS).to receive(:enabled?).and_return(false)
|
||
|
end
|
||
|
|
||
|
it 'is not included' do
|
||
|
expect(subject.to_hash).not_to have_key('CI_GITLAB_FIPS_MODE')
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'when tag is not found' do
|
||
|
let(:pipeline) do
|
||
|
create(:ci_pipeline, project: project, ref: 'not_found_tag', tag: true)
|
||
|
end
|
||
|
|
||
|
it 'does not expose tag variables' do
|
||
|
expect(subject.to_hash.keys)
|
||
|
.not_to include(
|
||
|
'CI_COMMIT_TAG',
|
||
|
'CI_COMMIT_TAG_MESSAGE',
|
||
|
'CI_BUILD_TAG'
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
context 'without a commit' do
|
||
|
let(:pipeline) { build(:ci_empty_pipeline, :created, sha: nil) }
|
||
|
|
||
|
it 'does not expose commit variables' do
|
||
|
expect(subject.to_hash.keys)
|
||
|
.not_to include(
|
||
|
'CI_COMMIT_SHA',
|
||
|
'CI_COMMIT_SHORT_SHA',
|
||
|
'CI_COMMIT_BEFORE_SHA',
|
||
|
'CI_COMMIT_REF_NAME',
|
||
|
'CI_COMMIT_REF_SLUG',
|
||
|
'CI_COMMIT_BRANCH',
|
||
|
'CI_COMMIT_TAG',
|
||
|
'CI_COMMIT_MESSAGE',
|
||
|
'CI_COMMIT_TITLE',
|
||
|
'CI_COMMIT_DESCRIPTION',
|
||
|
'CI_COMMIT_REF_PROTECTED',
|
||
|
'CI_COMMIT_TIMESTAMP',
|
||
|
'CI_COMMIT_AUTHOR')
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|