Commit 4f3a7d7b authored by Furkan Ayhan's avatar Furkan Ayhan

Implement variables for pipeline workflow rules

With this, workflow variables can be defined according to the conditions
It is behind a feature flag ci_workflow_rules_variables
parent b6a7cdaa
---
name: ci_workflow_rules_variables
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52085
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/300997
milestone: '13.11'
type: development
group: group::pipeline authoring
default_enabled: false
...@@ -172,6 +172,7 @@ a preconfigured `workflow: rules` entry. ...@@ -172,6 +172,7 @@ a preconfigured `workflow: rules` entry.
- [`when`](#when): Specify what to do when the `if` rule evaluates to true. - [`when`](#when): Specify what to do when the `if` rule evaluates to true.
- To run a pipeline, set to `always`. - To run a pipeline, set to `always`.
- To prevent pipelines from running, set to `never`. - To prevent pipelines from running, set to `never`.
- [`variables`](#workflowrulesvariables): If not defined, uses the [variables defined elsewhere](#variables).
When no rules evaluate to true, the pipeline does not run. When no rules evaluate to true, the pipeline does not run.
...@@ -222,6 +223,54 @@ request pipelines. ...@@ -222,6 +223,54 @@ request pipelines.
If your rules match both branch pipelines and merge request pipelines, If your rules match both branch pipelines and merge request pipelines,
[duplicate pipelines](#avoid-duplicate-pipelines) can occur. [duplicate pipelines](#avoid-duplicate-pipelines) can occur.
#### `workflow:rules:variables`
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294232) in GitLab 13.11.
> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
> - It's disabled on GitLab.com.
> - It's not recommended for production use.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-workflowrulesvariables). **(CORE ONLY)**
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
You can use [`variables`](#variables) in `workflow:rules:` to define variables for specific pipeline conditions.
For example:
```yaml
variables:
DEPLOY_VARIABLE: "default-deploy"
workflow:
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
variables:
DEPLOY_VARIABLE: "deploy-production" # Override globally-defined DEPLOY_VARIABLE
- if: $CI_COMMIT_REF_NAME =~ /feature/
variables:
IS_A_FEATURE: "true" # Define a new variable.
```
##### Enable or disable workflow:rules:variables **(CORE ONLY)**
rules:variables is under development and not ready for production use.
It is deployed behind a feature flag that is **disabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
can enable it.
To enable it:
```ruby
Feature.enable(:ci_workflow_rules_variables)
```
To disable it:
```ruby
Feature.disable(:ci_workflow_rules_variables)
```
#### `workflow:rules` templates #### `workflow:rules` templates
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217732) in GitLab 13.0. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217732) in GitLab 13.0.
......
...@@ -48,6 +48,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do ...@@ -48,6 +48,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
stage: 'test', stage: 'test',
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage) scheduling_type: :stage)
end end
end end
...@@ -69,6 +71,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do ...@@ -69,6 +71,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
stage: 'test', stage: 'test',
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :dag) scheduling_type: :dag)
end end
end end
......
...@@ -29,6 +29,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do ...@@ -29,6 +29,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do
when: "on_success", when: "on_success",
allow_failure: false, allow_failure: false,
yaml_variables: [], yaml_variables: [],
job_variables: [],
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
) )
expect(subject.builds[1]).to eq( expect(subject.builds[1]).to eq(
...@@ -42,6 +44,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do ...@@ -42,6 +44,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do
when: "on_success", when: "on_success",
allow_failure: false, allow_failure: false,
yaml_variables: [], yaml_variables: [],
job_variables: [],
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
) )
end end
...@@ -63,6 +67,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do ...@@ -63,6 +67,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do
when: "on_success", when: "on_success",
allow_failure: false, allow_failure: false,
yaml_variables: [], yaml_variables: [],
job_variables: [],
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
) )
expect(subject.builds[1]).to eq( expect(subject.builds[1]).to eq(
...@@ -79,6 +85,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do ...@@ -79,6 +85,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do
when: "on_success", when: "on_success",
allow_failure: false, allow_failure: false,
yaml_variables: [], yaml_variables: [],
job_variables: [],
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
) )
end end
...@@ -153,6 +161,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do ...@@ -153,6 +161,8 @@ RSpec.describe Gitlab::Ci::YamlProcessor do
when: 'on_success', when: 'on_success',
allow_failure: false, allow_failure: false,
yaml_variables: [], yaml_variables: [],
job_variables: [],
root_variables_inheritance: true,
scheduling_type: :dag scheduling_type: :dag
) )
end end
......
...@@ -124,7 +124,9 @@ module Gitlab ...@@ -124,7 +124,9 @@ module Gitlab
stage: stage_value, stage: stage_value,
extends: extends, extends: extends,
rules: rules_value, rules: rules_value,
variables: root_and_job_variables_value, variables: root_and_job_variables_value, # https://gitlab.com/gitlab-org/gitlab/-/issues/300581
job_variables: job_variables,
root_variables_inheritance: root_variables_inheritance,
only: only_value, only: only_value,
except: except_value, except: except_value,
resource_group: resource_group }.compact resource_group: resource_group }.compact
...@@ -139,6 +141,18 @@ module Gitlab ...@@ -139,6 +141,18 @@ module Gitlab
root_variables.merge(variables_value.to_h) root_variables.merge(variables_value.to_h)
end end
def job_variables
return unless ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
variables_value.to_h
end
def root_variables_inheritance
return unless ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
inherit_entry&.variables_entry&.value
end
def manual_action? def manual_action?
self.when == 'manual' self.when == 'manual'
end end
......
...@@ -43,9 +43,10 @@ module Gitlab ...@@ -43,9 +43,10 @@ module Gitlab
{ {
name: name, name: name,
instance: instance, instance: instance,
variables: variables, variables: variables, # https://gitlab.com/gitlab-org/gitlab/-/issues/300581
job_variables: job_variables,
parallel: { total: total } parallel: { total: total }
} }.compact
end end
def name def name
...@@ -60,6 +61,12 @@ module Gitlab ...@@ -60,6 +61,12 @@ module Gitlab
private private
attr_reader :job_name, :instance, :variables, :total attr_reader :job_name, :instance, :variables, :total
def job_variables
return unless ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
variables
end
end end
end end
end end
......
...@@ -11,6 +11,10 @@ module Gitlab ...@@ -11,6 +11,10 @@ module Gitlab
def perform! def perform!
raise ArgumentError, 'missing YAML processor result' unless @command.yaml_processor_result raise ArgumentError, 'missing YAML processor result' unless @command.yaml_processor_result
if ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
raise ArgumentError, 'missing workflow rules result' unless @command.workflow_rules_result
end
# Allocate next IID. This operation must be outside of transactions of pipeline creations. # Allocate next IID. This operation must be outside of transactions of pipeline creations.
pipeline.ensure_project_iid! pipeline.ensure_project_iid!
pipeline.ensure_ci_ref! pipeline.ensure_ci_ref!
...@@ -47,7 +51,13 @@ module Gitlab ...@@ -47,7 +51,13 @@ module Gitlab
end end
def root_variables def root_variables
@command.yaml_processor_result.root_variables if ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
::Gitlab::Ci::Variables::Helpers.merge_variables(
@command.yaml_processor_result.root_variables, @command.workflow_rules_result.variables
)
else
@command.yaml_processor_result.root_variables
end
end end
end end
end end
......
...@@ -18,6 +18,8 @@ module Gitlab ...@@ -18,6 +18,8 @@ module Gitlab
@previous_stages = previous_stages @previous_stages = previous_stages
@needs_attributes = dig(:needs_attributes) @needs_attributes = dig(:needs_attributes)
@resource_group_key = attributes.delete(:resource_group_key) @resource_group_key = attributes.delete(:resource_group_key)
@job_variables = @seed_attributes.delete(:job_variables)
@root_variables_inheritance = @seed_attributes.delete(:root_variables_inheritance) { true }
@using_rules = attributes.key?(:rules) @using_rules = attributes.key?(:rules)
@using_only = attributes.key?(:only) @using_only = attributes.key?(:only)
...@@ -31,6 +33,8 @@ module Gitlab ...@@ -31,6 +33,8 @@ module Gitlab
.new(attributes.delete(:rules), default_when: 'on_success') .new(attributes.delete(:rules), default_when: 'on_success')
@cache = Gitlab::Ci::Build::Cache @cache = Gitlab::Ci::Build::Cache
.new(attributes.delete(:cache), @pipeline) .new(attributes.delete(:cache), @pipeline)
recalculate_yaml_variables!
end end
def name def name
...@@ -207,6 +211,14 @@ module Gitlab ...@@ -207,6 +211,14 @@ module Gitlab
{ options: { allow_failure_criteria: nil } } { options: { allow_failure_criteria: nil } }
end end
def recalculate_yaml_variables!
return unless ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
@seed_attributes[:yaml_variables] = Gitlab::Ci::Variables::Helpers.inherit_yaml_variables(
from: @context.root_variables, to: @job_variables, inheritance: @root_variables_inheritance
)
end
end end
end end
end end
......
...@@ -25,6 +25,20 @@ module Gitlab ...@@ -25,6 +25,20 @@ module Gitlab
vars.to_a.map { |var| [var[:key].to_s, var[:value]] }.to_h vars.to_a.map { |var| [var[:key].to_s, var[:value]] }.to_h
end end
def inherit_yaml_variables(from:, to:, inheritance:)
merge_variables(apply_inheritance(from, inheritance), to)
end
private
def apply_inheritance(variables, inheritance)
case inheritance
when true then variables
when false then {}
when Array then variables.select { |var| inheritance.include?(var[:key]) }
end
end
end end
end end
end end
......
...@@ -69,7 +69,9 @@ module Gitlab ...@@ -69,7 +69,9 @@ module Gitlab
when: job[:when] || 'on_success', when: job[:when] || 'on_success',
environment: job[:environment_name], environment: job[:environment_name],
coverage_regex: job[:coverage], coverage_regex: job[:coverage],
yaml_variables: transform_to_yaml_variables(job[:variables]), yaml_variables: transform_to_yaml_variables(job[:variables]), # https://gitlab.com/gitlab-org/gitlab/-/issues/300581
job_variables: transform_to_yaml_variables(job[:job_variables]),
root_variables_inheritance: job[:root_variables_inheritance],
needs_attributes: job.dig(:needs, :job), needs_attributes: job.dig(:needs, :job),
interruptible: job[:interruptible], interruptible: job[:interruptible],
only: job[:only], only: job[:only],
......
...@@ -10,6 +10,7 @@ module Gitlab ...@@ -10,6 +10,7 @@ module Gitlab
class Terminal < ::Gitlab::Config::Entry::Node class Terminal < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable include ::Gitlab::Config::Entry::Configurable
include ::Gitlab::Config::Entry::Attributable include ::Gitlab::Config::Entry::Attributable
include Gitlab::Utils::StrongMemoize
# By default the build will finish in a few seconds, not giving the webide # By default the build will finish in a few seconds, not giving the webide
# enough time to connect to the terminal. This default script provides # enough time to connect to the terminal. This default script provides
...@@ -51,23 +52,34 @@ module Gitlab ...@@ -51,23 +52,34 @@ module Gitlab
private private
def to_hash def to_hash
{ tag_list: tags || [], {
yaml_variables: yaml_variables, tag_list: tags || [],
yaml_variables: yaml_variables, # https://gitlab.com/gitlab-org/gitlab/-/issues/300581
job_variables: job_variables,
options: { options: {
image: image_value, image: image_value,
services: services_value, services: services_value,
before_script: before_script_value, before_script: before_script_value,
script: script_value || DEFAULT_SCRIPT script: script_value || DEFAULT_SCRIPT
}.compact } }.compact
}.compact
end end
def yaml_variables def yaml_variables
return unless variables_value strong_memoize(:yaml_variables) do
next unless variables_value
variables_value.map do |key, value| variables_value.map do |key, value|
{ key: key.to_s, value: value, public: true } { key: key.to_s, value: value, public: true }
end
end end
end end
def job_variables
return unless ::Feature.enabled?(:ci_workflow_rules_variables, default_enabled: :yaml)
yaml_variables
end
end end
end end
end end
......
...@@ -107,6 +107,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do ...@@ -107,6 +107,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
stage: 'test', stage: 'test',
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage) scheduling_type: :stage)
end end
end end
...@@ -130,6 +132,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do ...@@ -130,6 +132,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
stage: 'test', stage: 'test',
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage) scheduling_type: :stage)
end end
end end
...@@ -284,6 +288,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do ...@@ -284,6 +288,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
parallel: { matrix: [{ 'PROVIDER' => ['aws'], 'STACK' => %w(monitoring app1) }, parallel: { matrix: [{ 'PROVIDER' => ['aws'], 'STACK' => %w(monitoring app1) },
{ 'PROVIDER' => ['gcp'], 'STACK' => %w(data) }] }, { 'PROVIDER' => ['gcp'], 'STACK' => %w(data) }] },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
) )
end end
......
...@@ -663,6 +663,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do ...@@ -663,6 +663,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
after_script: %w[cleanup], after_script: %w[cleanup],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage) scheduling_type: :stage)
end end
end end
......
...@@ -100,6 +100,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Jobs do ...@@ -100,6 +100,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Jobs do
stage: 'test', stage: 'test',
trigger: { project: 'my/project' }, trigger: { project: 'my/project' },
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
}, },
regular_job: { regular_job: {
...@@ -109,6 +111,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Jobs do ...@@ -109,6 +111,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Jobs do
script: ['something'], script: ['something'],
stage: 'test', stage: 'test',
variables: {}, variables: {},
job_variables: {},
root_variables_inheritance: true,
scheduling_type: :stage scheduling_type: :stage
}) })
end end
......
...@@ -381,9 +381,25 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do ...@@ -381,9 +381,25 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
context 'with only job variables' do context 'with only job variables' do
it 'does return defined variables' do it 'does return defined variables' do
expect(entry.value).to include(
variables: { 'A' => 'job', 'B' => 'job' },
job_variables: { 'A' => 'job', 'B' => 'job' },
root_variables_inheritance: true
)
end
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 return job_variables and root_variables_inheritance' do
expect(entry.value).to include( expect(entry.value).to include(
variables: { 'A' => 'job', 'B' => 'job' } variables: { 'A' => 'job', 'B' => 'job' }
) )
expect(entry.value).not_to have_key(:job_variables)
expect(entry.value).not_to have_key(:root_variables_inheritance)
end end
end end
...@@ -394,9 +410,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do ...@@ -394,9 +410,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
).value ).value
end end
it 'does return all variables and overwrite them' do it 'does return job and root variables' do
expect(entry.value).to include( expect(entry.value).to include(
variables: { 'A' => 'job', 'B' => 'job', 'C' => 'root', 'D' => 'root' } variables: { 'A' => 'job', 'B' => 'job', 'C' => 'root', 'D' => 'root' },
job_variables: { 'A' => 'job', 'B' => 'job' },
root_variables_inheritance: true
) )
end end
...@@ -408,9 +426,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do ...@@ -408,9 +426,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
} }
end end
it 'does return only job variables' do it 'does return job and root variables' do
expect(entry.value).to include( expect(entry.value).to include(
variables: { 'A' => 'job', 'B' => 'job' } variables: { 'A' => 'job', 'B' => 'job' },
job_variables: { 'A' => 'job', 'B' => 'job' },
root_variables_inheritance: false
) )
end end
end end
...@@ -423,9 +443,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do ...@@ -423,9 +443,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
} }
end end
it 'does return only job variables' do it 'does return job and root variables' do
expect(entry.value).to include( expect(entry.value).to include(
variables: { 'A' => 'job', 'B' => 'job', 'D' => 'root' } variables: { 'A' => 'job', 'B' => 'job', 'D' => 'root' },
job_variables: { 'A' => 'job', 'B' => 'job' },
root_variables_inheritance: ['D']
) )
end end
end end
...@@ -493,9 +515,26 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do ...@@ -493,9 +515,26 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
name: :rspec, name: :rspec,
stage: 'test', stage: 'test',
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
variables: {} variables: {},
job_variables: {},
root_variables_inheritance: true
) )
end 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 return job_variables and root_variables_inheritance' do
expect(entry.value).to eq(
name: :rspec,
stage: 'test',
only: { refs: %w[branches tags] },
variables: {}
)
end
end
end end
end end
end end
......
...@@ -133,6 +133,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -133,6 +133,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }], cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }],
variables: { 'VAR' => 'root', 'VAR2' => 'val 2' }, variables: { 'VAR' => 'root', 'VAR2' => 'val 2' },
job_variables: {},
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -147,6 +149,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -147,6 +149,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }], cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }],
variables: { 'VAR' => 'root', 'VAR2' => 'val 2' }, variables: { 'VAR' => 'root', 'VAR2' => 'val 2' },
job_variables: {},
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -163,6 +167,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -163,6 +167,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
cache: [{ key: "k", untracked: true, paths: ["public/"], policy: "pull-push", when: 'on_success' }], cache: [{ key: "k", untracked: true, paths: ["public/"], policy: "pull-push", when: 'on_success' }],
only: { refs: %w(branches tags) }, only: { refs: %w(branches tags) },
variables: { 'VAR' => 'job', 'VAR2' => 'val 2' }, variables: { 'VAR' => 'job', 'VAR2' => 'val 2' },
job_variables: { 'VAR' => 'job' },
root_variables_inheritance: true,
after_script: [], after_script: [],
ignore: false, ignore: false,
scheduling_type: :stage } scheduling_type: :stage }
...@@ -188,6 +194,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -188,6 +194,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }, cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' },
variables: { 'VAR' => 'root', 'VAR2' => 'val 2' }, variables: { 'VAR' => 'root', 'VAR2' => 'val 2' },
job_variables: {},
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -202,6 +210,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -202,6 +210,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }, cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' },
variables: { 'VAR' => 'root', 'VAR2' => 'val 2' }, variables: { 'VAR' => 'root', 'VAR2' => 'val 2' },
job_variables: {},
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -218,6 +228,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -218,6 +228,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
cache: { key: "k", untracked: true, paths: ["public/"], policy: "pull-push", when: 'on_success' }, cache: { key: "k", untracked: true, paths: ["public/"], policy: "pull-push", when: 'on_success' },
only: { refs: %w(branches tags) }, only: { refs: %w(branches tags) },
variables: { 'VAR' => 'job', 'VAR2' => 'val 2' }, variables: { 'VAR' => 'job', 'VAR2' => 'val 2' },
job_variables: { 'VAR' => 'job' },
root_variables_inheritance: true,
after_script: [], after_script: [],
ignore: false, ignore: false,
scheduling_type: :stage } scheduling_type: :stage }
...@@ -267,6 +279,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -267,6 +279,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }, cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' },
variables: { 'VAR' => 'root' }, variables: { 'VAR' => 'root' },
job_variables: {},
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -279,6 +293,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -279,6 +293,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }, cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' },
variables: { 'VAR' => 'job' }, variables: { 'VAR' => 'job' },
job_variables: { 'VAR' => 'job' },
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -311,6 +327,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -311,6 +327,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }], cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }],
variables: { 'VAR' => 'root' }, variables: { 'VAR' => 'root' },
job_variables: {},
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
...@@ -323,6 +341,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do ...@@ -323,6 +341,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do
stage: 'test', stage: 'test',
cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }], cache: [{ key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push', when: 'on_success' }],
variables: { 'VAR' => 'job' }, variables: { 'VAR' => 'job' },
job_variables: { 'VAR' => 'job' },
root_variables_inheritance: true,
ignore: false, ignore: false,
after_script: ['make clean'], after_script: ['make clean'],
only: { refs: %w[branches tags] }, only: { refs: %w[branches tags] },
......
# frozen_string_literal: true # frozen_string_literal: true
require 'fast_spec_helper' require 'fast_spec_helper'
require 'support/helpers/stubbed_feature'
require 'support/helpers/stub_feature_flags'
RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do
include StubFeatureFlags
describe '.applies_to?' do describe '.applies_to?' do
subject { described_class.applies_to?(config) } subject { described_class.applies_to?(config) }
...@@ -49,6 +53,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do ...@@ -49,6 +53,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do
variables: { variables: {
'PROVIDER' => 'aws', 'PROVIDER' => 'aws',
'STACK' => 'app1' 'STACK' => 'app1'
},
job_variables: {
'PROVIDER' => 'aws',
'STACK' => 'app1'
} }
}, },
{ {
...@@ -58,6 +66,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do ...@@ -58,6 +66,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do
variables: { variables: {
'PROVIDER' => 'aws', 'PROVIDER' => 'aws',
'STACK' => 'app2' 'STACK' => 'app2'
},
job_variables: {
'PROVIDER' => 'aws',
'STACK' => 'app2'
} }
}, },
{ {
...@@ -67,6 +79,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do ...@@ -67,6 +79,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do
variables: { variables: {
'PROVIDER' => 'ovh', 'PROVIDER' => 'ovh',
'STACK' => 'app' 'STACK' => 'app'
},
job_variables: {
'PROVIDER' => 'ovh',
'STACK' => 'app'
} }
}, },
{ {
...@@ -76,6 +92,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do ...@@ -76,6 +92,10 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do
variables: { variables: {
'PROVIDER' => 'gcp', 'PROVIDER' => 'gcp',
'STACK' => 'app' 'STACK' => 'app'
},
job_variables: {
'PROVIDER' => 'gcp',
'STACK' => 'app'
} }
} }
] ]
...@@ -87,5 +107,54 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do ...@@ -87,5 +107,54 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do
['test: [aws, app1]', 'test: [aws, app2]', 'test: [gcp, app]', 'test: [ovh, app]'] ['test: [aws, app1]', 'test: [aws, app2]', 'test: [gcp, app]', 'test: [ovh, app]']
) )
end end
context 'when the FF ci_workflow_rules_variables is disabled' do
before do
stub_feature_flags(ci_workflow_rules_variables: false)
end
it 'excludes job_variables' do
expect(subject.map(&:attributes)).to match_array(
[
{
name: 'test: [aws, app1]',
instance: 1,
parallel: { total: 4 },
variables: {
'PROVIDER' => 'aws',
'STACK' => 'app1'
}
},
{
name: 'test: [aws, app2]',
instance: 2,
parallel: { total: 4 },
variables: {
'PROVIDER' => 'aws',
'STACK' => 'app2'
}
},
{
name: 'test: [ovh, app]',
instance: 3,
parallel: { total: 4 },
variables: {
'PROVIDER' => 'ovh',
'STACK' => 'app'
}
},
{
name: 'test: [gcp, app]',
instance: 4,
parallel: { total: 4 },
variables: {
'PROVIDER' => 'gcp',
'STACK' => 'app'
}
}
]
)
end
end
end end
end end
...@@ -194,5 +194,39 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do ...@@ -194,5 +194,39 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
expect(pipeline.variables.size).to eq(0) expect(pipeline.variables.size).to eq(0)
end end
end end
describe '#root_variables' do
let(:config) do
{
variables: { VAR1: 'var 1' },
workflow: {
rules: [{ if: '$CI_PIPELINE_SOURCE',
variables: { VAR1: 'overridden var 1' } },
{ when: 'always' }]
},
rspec: { script: 'rake' }
}
end
let(:rspec_variables) { command.pipeline_seed.stages[0].statuses[0].variables.to_hash }
it 'sends root variable with overridden by rules' do
run_chain
expect(rspec_variables['VAR1']).to eq('overridden var 1')
end
context 'when the FF ci_workflow_rules_variables is disabled' do
before do
stub_feature_flags(ci_workflow_rules_variables: false)
end
it 'sends root variable' do
run_chain
expect(rspec_variables['VAR1']).to eq('var 1')
end
end
end
end end
end end
...@@ -77,8 +77,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do ...@@ -77,8 +77,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
let(:attributes) do let(:attributes) do
{ name: 'rspec', { name: 'rspec',
ref: 'master', ref: 'master',
yaml_variables: [{ key: 'VAR1', value: 'var 1', public: true }, job_variables: [{ key: 'VAR1', value: 'var 1', public: true },
{ key: 'VAR2', value: 'var 2', public: true }], { key: 'VAR2', value: 'var 2', public: true }],
rules: [{ if: '$VAR == null', variables: { VAR1: 'new var 1', VAR3: 'var 3' } }] } rules: [{ if: '$VAR == null', variables: { VAR1: 'new var 1', VAR3: 'var 3' } }] }
end end
...@@ -304,14 +304,98 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do ...@@ -304,14 +304,98 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
end end
end end
context 'with workflow:rules:[variables:]' do
let(:attributes) do
{ name: 'rspec',
ref: 'master',
yaml_variables: [{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true }],
job_variables: [{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true }],
root_variables_inheritance: root_variables_inheritance }
end
context 'when the pipeline has variables' do
let(:root_variables) do
[{ key: 'VAR1', value: 'var overridden pipeline 1', public: true },
{ key: 'VAR2', value: 'var pipeline 2', public: true },
{ key: 'VAR3', value: 'var pipeline 3', public: true },
{ key: 'VAR4', value: 'new var pipeline 4', public: true }]
end
context 'when root_variables_inheritance is true' do
let(:root_variables_inheritance) { true }
it 'returns calculated yaml variables' do
expect(subject[:yaml_variables]).to match_array(
[{ key: 'VAR1', value: 'var overridden pipeline 1', public: true },
{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true },
{ key: 'VAR4', value: 'new var pipeline 4', public: true }]
)
end
context 'when FF ci_workflow_rules_variables is disabled' do
before do
stub_feature_flags(ci_workflow_rules_variables: false)
end
it 'returns existing yaml variables' do
expect(subject[:yaml_variables]).to match_array(
[{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true }]
)
end
end
end
context 'when root_variables_inheritance is false' do
let(:root_variables_inheritance) { false }
it 'returns job variables' do
expect(subject[:yaml_variables]).to match_array(
[{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true }]
)
end
end
context 'when root_variables_inheritance is an array' do
let(:root_variables_inheritance) { %w(VAR1 VAR2 VAR3) }
it 'returns calculated yaml variables' do
expect(subject[:yaml_variables]).to match_array(
[{ key: 'VAR1', value: 'var overridden pipeline 1', public: true },
{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true }]
)
end
end
end
context 'when the pipeline has not a variable' do
let(:root_variables_inheritance) { true }
it 'returns seed yaml variables' do
expect(subject[:yaml_variables]).to match_array(
[{ key: 'VAR2', value: 'var 2', public: true },
{ key: 'VAR3', value: 'var 3', public: true }])
end
end
end
context 'when the job rule depends on variables' do context 'when the job rule depends on variables' do
let(:attributes) do let(:attributes) do
{ name: 'rspec', { name: 'rspec',
ref: 'master', ref: 'master',
yaml_variables: [{ key: 'VAR1', value: 'var 1', public: true }], yaml_variables: [{ key: 'VAR1', value: 'var 1', public: true }],
job_variables: [{ key: 'VAR1', value: 'var 1', public: true }],
root_variables_inheritance: root_variables_inheritance,
rules: rules } rules: rules }
end end
let(:root_variables_inheritance) { true }
context 'when the rules use job variables' do context 'when the rules use job variables' do
let(:rules) do let(:rules) do
[{ if: '$VAR1 == "var 1"', variables: { VAR1: 'overridden var 1', VAR2: 'new var 2' } }] [{ if: '$VAR1 == "var 1"', variables: { VAR1: 'overridden var 1', VAR2: 'new var 2' } }]
...@@ -322,6 +406,29 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do ...@@ -322,6 +406,29 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
{ key: 'VAR2', value: 'new var 2', public: true }) { key: 'VAR2', value: 'new var 2', public: true })
end end
end end
context 'when the rules use root variables' do
let(:root_variables) do
[{ key: 'VAR2', value: 'var pipeline 2', public: true }]
end
let(:rules) do
[{ if: '$VAR2 == "var pipeline 2"', variables: { VAR1: 'overridden var 1', VAR2: 'overridden var 2' } }]
end
it 'recalculates the variables' do
expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'overridden var 1', public: true },
{ key: 'VAR2', value: 'overridden var 2', public: true })
end
context 'when the root_variables_inheritance is false' do
let(:root_variables_inheritance) { false }
it 'does not recalculate the variables' do
expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'var 1', public: true })
end
end
end
end end
end end
......
...@@ -100,4 +100,50 @@ RSpec.describe Gitlab::Ci::Variables::Helpers do ...@@ -100,4 +100,50 @@ RSpec.describe Gitlab::Ci::Variables::Helpers do
it { is_expected.to eq(result) } it { is_expected.to eq(result) }
end end
end end
describe '.inherit_yaml_variables' do
let(:from) do
[{ key: 'key1', value: 'value1' },
{ key: 'key2', value: 'value2' }]
end
let(:to) do
[{ key: 'key2', value: 'value22' },
{ key: 'key3', value: 'value3' }]
end
let(:inheritance) { true }
let(:result) do
[{ key: 'key1', value: 'value1', public: true },
{ key: 'key2', value: 'value22', public: true },
{ key: 'key3', value: 'value3', public: true }]
end
subject { described_class.inherit_yaml_variables(from: from, to: to, inheritance: inheritance) }
it { is_expected.to eq(result) }
context 'when inheritance is false' do
let(:inheritance) { false }
let(:result) do
[{ key: 'key2', value: 'value22', public: true },
{ key: 'key3', value: 'value3', public: true }]
end
it { is_expected.to eq(result) }
end
context 'when inheritance is array' do
let(:inheritance) { ['key2'] }
let(:result) do
[{ key: 'key2', value: 'value22', public: true },
{ key: 'key3', value: 'value3', public: true }]
end
it { is_expected.to eq(result) }
end
end
end end
This diff is collapsed.
...@@ -83,6 +83,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Global do ...@@ -83,6 +83,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Global do
expect(global.terminal_value).to eq({ expect(global.terminal_value).to eq({
tag_list: [], tag_list: [],
yaml_variables: [], yaml_variables: [],
job_variables: [],
options: { options: {
before_script: ['ls'], before_script: ['ls'],
script: ['sleep 10s'], script: ['sleep 10s'],
......
...@@ -142,6 +142,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do ...@@ -142,6 +142,7 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do
.to eq( .to eq(
tag_list: ['webide'], tag_list: ['webide'],
yaml_variables: [{ key: 'KEY', value: 'value', public: true }], yaml_variables: [{ key: 'KEY', value: 'value', public: true }],
job_variables: [{ key: 'KEY', value: 'value', public: true }],
options: { options: {
image: { name: "ruby:2.5" }, image: { name: "ruby:2.5" },
services: [{ name: "mysql" }], services: [{ name: "mysql" }],
...@@ -150,6 +151,26 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do ...@@ -150,6 +151,26 @@ RSpec.describe Gitlab::WebIde::Config::Entry::Terminal do
} }
) )
end end
context 'when FF ci_workflow_rules_variables is disabled' do
before do
stub_feature_flags(ci_workflow_rules_variables: false)
end
it 'returns correct value without job_variables' do
expect(entry.value)
.to eq(
tag_list: ['webide'],
yaml_variables: [{ key: 'KEY', value: 'value', public: true }],
options: {
image: { name: "ruby:2.5" },
services: [{ name: "mysql" }],
before_script: %w[ls pwd],
script: ['sleep 100']
}
)
end
end
end end
end end
end end
......
...@@ -151,11 +151,29 @@ RSpec.describe Ci::CreatePipelineService do ...@@ -151,11 +151,29 @@ RSpec.describe Ci::CreatePipelineService do
context 'variables:' do context 'variables:' do
let(:config) do let(:config) do
<<-EOY <<-EOY
job: variables:
VAR4: workflow var 4
VAR5: workflow var 5
VAR7: workflow var 7
workflow:
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
variables:
VAR4: overridden workflow var 4
- if: $CI_COMMIT_REF_NAME =~ /feature/
variables:
VAR5: overridden workflow var 5
VAR6: new workflow var 6
VAR7: overridden workflow var 7
- when: always
job1:
script: "echo job1" script: "echo job1"
variables: variables:
VAR1: my var 1 VAR1: job var 1
VAR2: my var 2 VAR2: job var 2
VAR5: job var 5
rules: rules:
- if: $CI_COMMIT_REF_NAME =~ /master/ - if: $CI_COMMIT_REF_NAME =~ /master/
variables: variables:
...@@ -164,45 +182,117 @@ RSpec.describe Ci::CreatePipelineService do ...@@ -164,45 +182,117 @@ RSpec.describe Ci::CreatePipelineService do
variables: variables:
VAR2: overridden var 2 VAR2: overridden var 2
VAR3: new var 3 VAR3: new var 3
VAR7: overridden var 7
- when: on_success
job2:
script: "echo job2"
inherit:
variables: [VAR4, VAR6, VAR7]
variables:
VAR4: job var 4
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
variables:
VAR7: overridden var 7
- when: on_success - when: on_success
EOY EOY
end end
let(:job) { pipeline.builds.find_by(name: 'job') } let(:job1) { pipeline.builds.find_by(name: 'job1') }
let(:job2) { pipeline.builds.find_by(name: 'job2') }
let(:variable_keys) { %w(VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 VAR7) }
context 'when no match' do
let(:ref) { 'refs/heads/wip' }
it 'does not affect vars' do
expect(job1.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
['job 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, 'workflow var 7']
)
end
end
context 'when matching to the first rule' do context 'when matching to the first rule' do
let(:ref) { 'refs/heads/master' } let(:ref) { 'refs/heads/master' }
it 'overrides VAR1' do it 'overrides variables' do
variables = job.scoped_variables.to_hash expect(job1.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
['overridden var 1', 'job var 2', nil, 'overridden workflow var 4', 'job var 5', nil, 'workflow var 7']
)
expect(variables['VAR1']).to eq('overridden var 1') expect(job2.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
expect(variables['VAR2']).to eq('my var 2') [nil, nil, nil, 'job var 4', nil, nil, 'overridden var 7']
expect(variables['VAR3']).to be_nil )
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
end end
context 'when matching to the second rule' do context 'when matching to the second rule' do
let(:ref) { 'refs/heads/feature' } let(:ref) { 'refs/heads/feature' }
it 'overrides VAR2 and adds VAR3' do it 'overrides variables' do
variables = job.scoped_variables.to_hash expect(job1.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
['job var 1', 'overridden var 2', 'new var 3', 'workflow var 4', 'job var 5', 'new workflow var 6', 'overridden var 7']
)
expect(variables['VAR1']).to eq('my var 1') expect(job2.scoped_variables.to_hash.values_at(*variable_keys)).to eq(
expect(variables['VAR2']).to eq('overridden var 2') [nil, nil, nil, 'job var 4', nil, 'new workflow var 6', 'overridden workflow var 7']
expect(variables['VAR3']).to eq('new var 3') )
end end
end end
context 'when no match' do context 'using calculated workflow var in job rules' do
let(:ref) { 'refs/heads/wip' } let(:config) do
<<-EOY
variables:
VAR1: workflow var 4
workflow:
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
variables:
VAR1: overridden workflow var 4
- when: always
job:
script: "echo job1"
rules:
- if: $VAR1 =~ "overridden workflow var 4"
variables:
VAR1: overridden var 1
- when: on_success
EOY
end
it 'does not affect vars' do let(:job) { pipeline.builds.find_by(name: 'job') }
variables = job.scoped_variables.to_hash
context 'when matching the first workflow condition' do
let(:ref) { 'refs/heads/master' }
expect(variables['VAR1']).to eq('my var 1') it 'uses VAR1 of job rules result' do
expect(variables['VAR2']).to eq('my var 2') expect(job.scoped_variables.to_hash['VAR1']).to eq('overridden var 1')
expect(variables['VAR3']).to be_nil end
end end
end end
end end
......
...@@ -47,6 +47,7 @@ RSpec.describe Ide::TerminalConfigService do ...@@ -47,6 +47,7 @@ RSpec.describe Ide::TerminalConfigService do
terminal: { terminal: {
tag_list: [], tag_list: [],
yaml_variables: [], yaml_variables: [],
job_variables: [],
options: { script: ["sleep 60"] } options: { script: ["sleep 60"] }
}) })
end end
...@@ -61,6 +62,7 @@ RSpec.describe Ide::TerminalConfigService do ...@@ -61,6 +62,7 @@ RSpec.describe Ide::TerminalConfigService do
terminal: { terminal: {
tag_list: [], tag_list: [],
yaml_variables: [], yaml_variables: [],
job_variables: [],
options: { before_script: ["ls"], script: ["sleep 60"] } options: { before_script: ["ls"], script: ["sleep 60"] }
}) })
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment