If a process starts a child process and this child process sets environment variables, these variables are only visible in the child process and within children of the child process, they never propagate to the parent process, nor has the parent process an easy way to access the environment of its child process.
In case of a GitLab CI Runner, the runner will start a child process to run your script instructions, a shell (/bin/sh
by default). When you change the environment in that shell, this change is only visible to the shell and to all child processes of the shell (e.g. commands you are executing).
Yet the shell running your before_script
instructions doesn't have to be the same shell that later on runs your script
instructions, usually these are two separate shells; especially as your before_script
is global, so it runs once for all jobs, whereas all the jobs can run in parallel and thus all require own shells. The changes to the environment you made in one shell won't be visible to your code running in other shells later on.
As a work-around, you can use a file:
variables:
var_A: 'Hello'
before_script:
- echo 'export var_B="World"' > somefile.env
step1:
stage: build
script:
- source somefile.env
- chmod u+x run.sh && source run.sh
By the way, if you source
a script file, it doen't need to be executable, so the chmod
is not required. It would be required if you want to run the script as ./run.sh
. The difference is that source
executes the script code in your current shell whereas ./run.sh
would create a child-shell and execute the code there. When running in a sub-shell, run.sh
will see all your environment but changes to it will be private to run.sh
and any process it calls, whereas these changes will propagate to your main shell if you do a source run.sh
.