summaryrefslogtreecommitdiff
path: root/spec/services/ci/create_pipeline_service
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/ci/create_pipeline_service')
-rw-r--r--spec/services/ci/create_pipeline_service/cache_spec.rb42
-rw-r--r--spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb4
-rw-r--r--spec/services/ci/create_pipeline_service/dry_run_spec.rb4
-rw-r--r--spec/services/ci/create_pipeline_service/evaluate_runner_tags_spec.rb144
-rw-r--r--spec/services/ci/create_pipeline_service/needs_spec.rb4
-rw-r--r--spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb40
-rw-r--r--spec/services/ci/create_pipeline_service/rules_spec.rb16
8 files changed, 192 insertions, 64 deletions
diff --git a/spec/services/ci/create_pipeline_service/cache_spec.rb b/spec/services/ci/create_pipeline_service/cache_spec.rb
index 5f74c2f1cef..f9767a794db 100644
--- a/spec/services/ci/create_pipeline_service/cache_spec.rb
+++ b/spec/services/ci/create_pipeline_service/cache_spec.rb
@@ -33,11 +33,11 @@ RSpec.describe Ci::CreatePipelineService do
it 'uses the provided key' do
expected = {
- 'key' => 'a-key',
- 'paths' => ['logs/', 'binaries/'],
- 'policy' => 'pull-push',
- 'untracked' => true,
- 'when' => 'on_success'
+ key: 'a-key',
+ paths: ['logs/', 'binaries/'],
+ policy: 'pull-push',
+ untracked: true,
+ when: 'on_success'
}
expect(pipeline).to be_persisted
@@ -66,10 +66,10 @@ RSpec.describe Ci::CreatePipelineService do
it 'builds a cache key' do
expected = {
- 'key' => /[a-f0-9]{40}/,
- 'paths' => ['logs/'],
- 'policy' => 'pull-push',
- 'when' => 'on_success'
+ key: /[a-f0-9]{40}/,
+ paths: ['logs/'],
+ policy: 'pull-push',
+ when: 'on_success'
}
expect(pipeline).to be_persisted
@@ -82,10 +82,10 @@ RSpec.describe Ci::CreatePipelineService do
it 'uses default cache key' do
expected = {
- 'key' => /default/,
- 'paths' => ['logs/'],
- 'policy' => 'pull-push',
- 'when' => 'on_success'
+ key: /default/,
+ paths: ['logs/'],
+ policy: 'pull-push',
+ when: 'on_success'
}
expect(pipeline).to be_persisted
@@ -115,10 +115,10 @@ RSpec.describe Ci::CreatePipelineService do
it 'builds a cache key' do
expected = {
- 'key' => /\$ENV_VAR-[a-f0-9]{40}/,
- 'paths' => ['logs/'],
- 'policy' => 'pull-push',
- 'when' => 'on_success'
+ key: /\$ENV_VAR-[a-f0-9]{40}/,
+ paths: ['logs/'],
+ policy: 'pull-push',
+ when: 'on_success'
}
expect(pipeline).to be_persisted
@@ -131,10 +131,10 @@ RSpec.describe Ci::CreatePipelineService do
it 'uses default cache key' do
expected = {
- 'key' => /\$ENV_VAR-default/,
- 'paths' => ['logs/'],
- 'policy' => 'pull-push',
- 'when' => 'on_success'
+ key: /\$ENV_VAR-default/,
+ paths: ['logs/'],
+ policy: 'pull-push',
+ when: 'on_success'
}
expect(pipeline).to be_persisted
diff --git a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
index 7193e5bd7d4..a42770aae20 100644
--- a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
+++ b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
@@ -69,7 +69,7 @@ RSpec.describe Ci::CreatePipelineService do
end
it 'contains both errors and warnings' do
- error_message = 'build job: need test is not defined in prior stages'
+ error_message = 'build job: need test is not defined in current or prior stages'
warning_message = /jobs:test may allow multiple pipelines to run/
expect(pipeline.yaml_errors).to eq(error_message)
diff --git a/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb b/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb
index 4cf52223e38..5dceb9f57f0 100644
--- a/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb
+++ b/spec/services/ci/create_pipeline_service/custom_yaml_tags_spec.rb
@@ -39,8 +39,8 @@ RSpec.describe Ci::CreatePipelineService do
it 'creates a pipeline' do
expect(pipeline).to be_persisted
expect(pipeline.builds.first.options).to match(a_hash_including({
- 'before_script' => ['ls'],
- 'script' => [
+ before_script: ['ls'],
+ script: [
'echo doing my first step',
'echo doing step 1 of job 1',
'echo doing my last step'
diff --git a/spec/services/ci/create_pipeline_service/dry_run_spec.rb b/spec/services/ci/create_pipeline_service/dry_run_spec.rb
index 0fb500f5729..01df7772eef 100644
--- a/spec/services/ci/create_pipeline_service/dry_run_spec.rb
+++ b/spec/services/ci/create_pipeline_service/dry_run_spec.rb
@@ -84,7 +84,7 @@ RSpec.describe Ci::CreatePipelineService do
it_behaves_like 'returns a non persisted pipeline'
it 'returns a pipeline with errors', :aggregate_failures do
- error_message = 'build job: need test is not defined in prior stages'
+ error_message = 'build job: need test is not defined in current or prior stages'
expect(subject.error_messages.map(&:content)).to eq([error_message])
expect(subject.errors).not_to be_empty
@@ -109,7 +109,7 @@ RSpec.describe Ci::CreatePipelineService do
it_behaves_like 'returns a non persisted pipeline'
it 'returns a pipeline with errors', :aggregate_failures do
- error_message = "'test' job needs 'build' job, but it was not added to the pipeline"
+ error_message = "'test' job needs 'build' job, but 'build' is not in any previous stage"
expect(subject.error_messages.map(&:content)).to eq([error_message])
expect(subject.errors).not_to be_empty
diff --git a/spec/services/ci/create_pipeline_service/evaluate_runner_tags_spec.rb b/spec/services/ci/create_pipeline_service/evaluate_runner_tags_spec.rb
new file mode 100644
index 00000000000..df881c1ac8f
--- /dev/null
+++ b/spec/services/ci/create_pipeline_service/evaluate_runner_tags_spec.rb
@@ -0,0 +1,144 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::CreatePipelineService do
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:group_variable) { create(:ci_group_variable, group: group, key: 'RUNNER_TAG', value: 'group')}
+ let_it_be(:project) { create(:project, :repository, group: group) }
+ let_it_be(:user) { create(:user) }
+
+ let(:service) { described_class.new(project, user, ref: 'master') }
+ let(:pipeline) { service.execute(:push) }
+ let(:job) { pipeline.builds.find_by(name: 'job') }
+
+ before do
+ project.add_developer(user)
+ stub_ci_pipeline_yaml_file config
+ end
+
+ context 'when the variable is set' do
+ let(:config) do
+ <<~EOS
+ variables:
+ KUBERNETES_RUNNER: kubernetes
+
+ job:
+ tags:
+ - docker
+ - $KUBERNETES_RUNNER
+ script:
+ - echo "Hello runner selector feature"
+ EOS
+ end
+
+ it 'uses the evaluated variable' do
+ expect(pipeline).to be_created_successfully
+ expect(job.tags.pluck(:name)).to match_array(%w[docker kubernetes])
+ end
+ end
+
+ context 'when the tag is composed by two variables' do
+ let(:config) do
+ <<~EOS
+ variables:
+ CLOUD_PROVIDER: aws
+ KUBERNETES_RUNNER: kubernetes
+ ENVIRONMENT_NAME: prod
+
+ job:
+ tags:
+ - docker
+ - $CLOUD_PROVIDER-$KUBERNETES_RUNNER-$ENVIRONMENT_NAME
+ script:
+ - echo "Hello runner selector feature"
+ EOS
+ end
+
+ it 'uses the evaluated variables' do
+ expect(pipeline).to be_created_successfully
+ expect(job.tags.pluck(:name)).to match_array(%w[docker aws-kubernetes-prod])
+ end
+ end
+
+ context 'when the variable is not set' do
+ let(:config) do
+ <<~EOS
+ job:
+ tags:
+ - docker
+ - $KUBERNETES_RUNNER
+ script:
+ - echo "Hello runner selector feature"
+ EOS
+ end
+
+ it 'uses the variable as a regular string' do
+ expect(pipeline).to be_created_successfully
+ expect(job.tags.pluck(:name)).to match_array(%w[docker $KUBERNETES_RUNNER])
+ end
+ end
+
+ context 'when the tag uses group variables' do
+ let(:config) do
+ <<~EOS
+ job:
+ tags:
+ - docker
+ - $RUNNER_TAG
+ script:
+ - echo "Hello runner selector feature"
+ EOS
+ end
+
+ it 'uses the evaluated variables' do
+ expect(pipeline).to be_created_successfully
+ expect(job.tags.pluck(:name)).to match_array(%w[docker group])
+ end
+ end
+
+ context 'when the tag has the same variable name defined for both group and project' do
+ let_it_be(:project_variable) { create(:ci_variable, project: project, key: 'RUNNER_TAG', value: 'project') }
+
+ let(:config) do
+ <<~EOS
+ variables:
+ RUNNER_TAG: pipeline
+ job:
+ tags:
+ - docker
+ - $RUNNER_TAG
+ script:
+ - echo "Hello runner selector feature"
+ EOS
+ end
+
+ it 'uses the project variable instead of group due to variable precedence' do
+ expect(pipeline).to be_created_successfully
+ expect(job.tags.pluck(:name)).to match_array(%w[docker project])
+ end
+ end
+
+ context 'with parallel:matrix config' do
+ let(:tags) { pipeline.builds.map(&:tags).flatten.pluck(:name) }
+
+ let(:config) do
+ <<~EOS
+ job:
+ parallel:
+ matrix:
+ - PROVIDER: [aws, gcp]
+ STACK: [monitoring, backup, app]
+ tags:
+ - ${PROVIDER}-${STACK}
+ script:
+ - echo "Hello runner selector feature"
+ EOS
+ end
+
+ it 'uses the evaluated variables' do
+ expect(pipeline).to be_created_successfully
+ expect(tags).to match_array(%w[aws-monitoring aws-backup aws-app gcp-monitoring gcp-backup gcp-app])
+ end
+ end
+end
diff --git a/spec/services/ci/create_pipeline_service/needs_spec.rb b/spec/services/ci/create_pipeline_service/needs_spec.rb
index 3b4a6178b8f..d096db10d0b 100644
--- a/spec/services/ci/create_pipeline_service/needs_spec.rb
+++ b/spec/services/ci/create_pipeline_service/needs_spec.rb
@@ -104,7 +104,7 @@ RSpec.describe Ci::CreatePipelineService do
it 'saves dependencies' do
expect(test_a_build.options)
- .to match(a_hash_including('dependencies' => ['build_a']))
+ .to match(a_hash_including(dependencies: ['build_a']))
end
it 'artifacts default to true' do
@@ -257,7 +257,7 @@ RSpec.describe Ci::CreatePipelineService do
it 'returns error' do
expect(pipeline.yaml_errors)
- .to eq("'test' job needs 'build' job, but it was not added to the pipeline")
+ .to eq("'test' job needs 'build' job, but 'build' is not in any previous stage")
end
context 'when need is optional' do
diff --git a/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb b/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
index 512cf546e6a..7a6535ed3fa 100644
--- a/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
+++ b/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
@@ -69,9 +69,9 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
it_behaves_like 'successful creation' do
let(:expected_bridge_options) do
{
- 'trigger' => {
- 'include' => [
- { 'local' => 'path/to/child.yml' }
+ trigger: {
+ include: [
+ { local: 'path/to/child.yml' }
]
}
}
@@ -149,9 +149,9 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
it_behaves_like 'successful creation' do
let(:expected_bridge_options) do
{
- 'trigger' => {
- 'include' => [
- { 'local' => 'path/to/child.yml' }
+ trigger: {
+ include: [
+ { local: 'path/to/child.yml' }
]
}
}
@@ -175,8 +175,8 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
it_behaves_like 'successful creation' do
let(:expected_bridge_options) do
{
- 'trigger' => {
- 'include' => 'path/to/child.yml'
+ trigger: {
+ include: 'path/to/child.yml'
}
}
end
@@ -202,8 +202,8 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
it_behaves_like 'successful creation' do
let(:expected_bridge_options) do
{
- 'trigger' => {
- 'include' => ['path/to/child.yml', 'path/to/child2.yml']
+ trigger: {
+ include: ['path/to/child.yml', 'path/to/child2.yml']
}
}
end
@@ -252,7 +252,7 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
end
it_behaves_like 'creation failure' do
- let(:expected_error) { /test job: dependency generator is not defined in prior stages/ }
+ let(:expected_error) { /test job: dependency generator is not defined in current or prior stages/ }
end
end
@@ -295,12 +295,12 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
it_behaves_like 'successful creation' do
let(:expected_bridge_options) do
{
- 'trigger' => {
- 'include' => [
+ trigger: {
+ include: [
{
- 'file' => 'path/to/child.yml',
- 'project' => 'my-namespace/my-project',
- 'ref' => 'master'
+ file: 'path/to/child.yml',
+ project: 'my-namespace/my-project',
+ ref: 'master'
}
]
}
@@ -353,11 +353,11 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
it_behaves_like 'successful creation' do
let(:expected_bridge_options) do
{
- 'trigger' => {
- 'include' => [
+ trigger: {
+ include: [
{
- 'file' => ["path/to/child1.yml", "path/to/child2.yml"],
- 'project' => 'my-namespace/my-project'
+ file: ["path/to/child1.yml", "path/to/child2.yml"],
+ project: 'my-namespace/my-project'
}
]
}
diff --git a/spec/services/ci/create_pipeline_service/rules_spec.rb b/spec/services/ci/create_pipeline_service/rules_spec.rb
index 33ec6aacc44..acdf38bbc13 100644
--- a/spec/services/ci/create_pipeline_service/rules_spec.rb
+++ b/spec/services/ci/create_pipeline_service/rules_spec.rb
@@ -230,22 +230,6 @@ RSpec.describe Ci::CreatePipelineService do
[nil, nil, nil, 'job var 4', nil, nil, 'overridden var 7']
)
end
-
- context 'when FF ci_workflow_rules_variables is disabled' do
- before do
- stub_feature_flags(ci_workflow_rules_variables: false)
- end
-
- it 'does not affect workflow variables but job variables' do
- expect(job1.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
- ['overridden var 1', 'job var 2', nil, 'workflow var 4', 'job var 5', nil, 'workflow var 7']
- )
-
- expect(job2.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
- [nil, nil, nil, 'job var 4', nil, nil, 'overridden var 7']
- )
- end
- end
end
context 'when matching to the second rule' do