From 2f0e358d61b7052336c4e35b9df99f7057b64bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hern=C3=A1ndez=20Remedios?= <6065567-renehernandez@users.noreply.gitlab.com> Date: Fri, 1 Dec 2023 16:40:06 +0000 Subject: [PATCH] Full dotenv vars support in downstream pipelines Changelog: added --- doc/ci/pipelines/downstream_pipelines.md | 4 +-- .../ci/variables/downstream/generator.rb | 8 ++++++ .../ci/variables/downstream/generator_spec.rb | 28 +++++++++++++++++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/doc/ci/pipelines/downstream_pipelines.md b/doc/ci/pipelines/downstream_pipelines.md index 21ed66ef939cf..ec1b6a4dba308 100644 --- a/doc/ci/pipelines/downstream_pipelines.md +++ b/doc/ci/pipelines/downstream_pipelines.md @@ -671,9 +671,7 @@ the ones defined in the upstream project take precedence. ### Pass dotenv variables created in a job **(PREMIUM ALL)** -You can pass variables to a downstream job with [`dotenv` variable inheritance](../variables/index.md#pass-an-environment-variable-to-another-job) -and [`needs:project`](../yaml/index.md#needsproject). These variables are only available in -the script of the job and can't be used to configure it, for example with `rules` or `artifact:paths`. +You can pass variables to a downstream pipeline with [`dotenv` variable inheritance](../variables/index.md#pass-an-environment-variable-to-another-job). For example, in a [multi-project pipeline](#multi-project-pipelines): diff --git a/lib/gitlab/ci/variables/downstream/generator.rb b/lib/gitlab/ci/variables/downstream/generator.rb index 350d29958cfc1..b0e45ac0413cc 100644 --- a/lib/gitlab/ci/variables/downstream/generator.rb +++ b/lib/gitlab/ci/variables/downstream/generator.rb @@ -33,6 +33,7 @@ def calculate_downstream_variables # The order of this list refers to the priority of the variables # The variables added later takes priority. downstream_yaml_variables + + downstream_pipeline_dotenv_variables + downstream_pipeline_variables + downstream_pipeline_schedule_variables end @@ -57,6 +58,13 @@ def downstream_pipeline_schedule_variables build_downstream_variables_from(pipeline_schedule_variables) end + def downstream_pipeline_dotenv_variables + return [] unless bridge.forward_pipeline_variables? + + pipeline_dotenv_variables = bridge.dependency_variables.to_a + build_downstream_variables_from(pipeline_dotenv_variables) + end + def build_downstream_variables_from(variables) Gitlab::Ci::Variables::Collection.fabricate(variables).flat_map do |item| if item.raw? diff --git a/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb b/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb index cd68b0cdf2bb7..f5845e492bcdf 100644 --- a/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb +++ b/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb @@ -39,6 +39,15 @@ ] end + let(:pipeline_dotenv_variables) do + [ + { key: 'PIPELINE_DOTENV_VAR1', value: 'variable 1' }, + { key: 'PIPELINE_DOTENV_VAR2', value: 'variable 2' }, + { key: 'PIPELINE_DOTENV_RAW_VAR3', value: '$REF1', raw: true }, + { key: 'PIPELINE_DOTENV_INTERPOLATION_VAR4', value: 'interpolate $REF1 $REF2' } + ] + end + let(:bridge) do instance_double( 'Ci::Bridge', @@ -48,7 +57,8 @@ expand_file_refs?: false, yaml_variables: yaml_variables, pipeline_variables: pipeline_variables, - pipeline_schedule_variables: pipeline_schedule_variables + pipeline_schedule_variables: pipeline_schedule_variables, + dependency_variables: pipeline_dotenv_variables ) end @@ -69,7 +79,12 @@ { key: 'PIPELINE_SCHEDULE_VAR1', value: 'variable 1' }, { key: 'PIPELINE_SCHEDULE_VAR2', value: 'variable 2' }, { key: 'PIPELINE_SCHEDULE_RAW_VAR3', value: '$REF1', raw: true }, - { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR4', value: 'interpolate ref 1 ref 2' } + { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR4', value: 'interpolate ref 1 ref 2' }, + { key: 'PIPELINE_DOTENV_VAR1', value: 'variable 1' }, + { key: 'PIPELINE_DOTENV_VAR2', value: 'variable 2' }, + { key: 'PIPELINE_DOTENV_RAW_VAR3', value: '$REF1', raw: true }, + { key: 'PIPELINE_DOTENV_INTERPOLATION_VAR4', value: 'interpolate ref 1 ref 2' } + ] expect(generator.calculate).to contain_exactly(*expected) @@ -79,6 +94,7 @@ allow(bridge).to receive(:yaml_variables).and_return([]) allow(bridge).to receive(:pipeline_variables).and_return([]) allow(bridge).to receive(:pipeline_schedule_variables).and_return([]) + allow(bridge).to receive(:dependency_variables).and_return([]) expect(generator.calculate).to be_empty end @@ -105,6 +121,10 @@ [{ key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR', value: 'interpolate $REF1 $REF2 $FILE_REF3 $FILE_REF4' }] end + let(:pipeline_dotenv_variables) do + [{ key: 'PIPELINE_DOTENV_INTERPOLATION_VAR', value: 'interpolate $REF1 $REF2 $FILE_REF3 $FILE_REF4' }] + end + context 'when expand_file_refs is true' do before do allow(bridge).to receive(:expand_file_refs?).and_return(true) @@ -114,7 +134,8 @@ expected = [ { key: 'INTERPOLATION_VAR', value: 'interpolate ref 1 ref 3 ' }, { key: 'PIPELINE_INTERPOLATION_VAR', value: 'interpolate ref 1 ref 3 ' }, - { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR', value: 'interpolate ref 1 ref 3 ' } + { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR', value: 'interpolate ref 1 ref 3 ' }, + { key: 'PIPELINE_DOTENV_INTERPOLATION_VAR', value: 'interpolate ref 1 ref 3 ' } ] expect(generator.calculate).to contain_exactly(*expected) @@ -131,6 +152,7 @@ { key: 'INTERPOLATION_VAR', value: 'interpolate ref 1 $FILE_REF3 ' }, { key: 'PIPELINE_INTERPOLATION_VAR', value: 'interpolate ref 1 $FILE_REF3 ' }, { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR', value: 'interpolate ref 1 $FILE_REF3 ' }, + { key: 'PIPELINE_DOTENV_INTERPOLATION_VAR', value: 'interpolate ref 1 $FILE_REF3 ' }, { key: 'FILE_REF3', value: 'ref 3', variable_type: :file } ] -- GitLab