debian-mirror-gitlab/spec/lib/gitlab/ci/variables/builder/pipeline_spec.rb
2023-06-20 00:43:36 +05:30

407 lines
14 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Variables::Builder::Pipeline, feature_category: :secrets_management 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
])
end
context 'when FF `ci_remove_legacy_predefined_variables` is disabled' do
before do
stub_feature_flags(ci_remove_legacy_predefined_variables: false)
end
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
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_COMMIT_TAG
CI_COMMIT_TAG_MESSAGE
])
end
context 'when FF `ci_remove_legacy_predefined_variables` is disabled' do
before do
stub_feature_flags(ci_remove_legacy_predefined_variables: false)
end
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
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'
)
end
context 'when FF `ci_remove_legacy_predefined_variables` is disabled' do
before do
stub_feature_flags(ci_remove_legacy_predefined_variables: false)
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
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