How to add secret variable as task environment variable in VSTS - azure-devops

This documentation states that secret variables are
Not decrypted into environment variables. So scripts and programs run by your build steps are not given access by default.
One of my build tasks require that an environment variable be set that is stored in a secret variable. Does this mean it's impossible to do this using secret varaibles in VSTS? If not, how do I do this?
For further background, I'm trying to code sign my electron app using electron-builder. It requires that two environment variables be set: CSC_LINK and CSC_KEY_PASSWORD. One of these is the password to a code signing certificate so needs to be kept secure.

Set Environment Variable
Use a Command Line task, like this:
target_environment_variable now contains the value of secret_variable.
Verify
Add a subsequent Command Line task that writes all environment variables to a disk file, like this: (note: in the Arguments text box, write to a folder that both you and build agent can access):
Queue the build definition, then view the file containing the environment variables:

When using the YAML-syntax this can be achieved too:
steps:
- script: |
echo %MYSECRET%
env:
MySecret: $(Secret_Variable)

You can supply variables to pass to tasks in the Variables page of the build definition:
Then they can be passed in to a task as an input like so:

Related

There does not seem to be a good substitute for core.exportVariable in github-script right now

Every time we use core.exportVariable which, as far as I know, is the canonical way to export a variable in #action/core and, consequently, in github-script, you get an error such as this one:
Warning: The set-env command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
That link leads to an explanation of environment files, which, well, are files. Problem is files do not seem to have such a great support in github-script. There's the #actions/io package, but there's no way to create a file with that.
So is there something I'm missing, or there is effectively no way to create an environment file form inside a github-script step?
You no longer need the actions/github-script nor any other special API to export an environment variable. According to the Environment Files documentation, you can simply write to the $GITHUB_ENV file directly from the workflow step like this:
steps:
- name: Set environment variable
run: echo "{name}={value}" >> $GITHUB_ENV
The step will expose given environment variable to subsequent steps in the currently executing workflow job.

How to use AzureDevOps predefined variables in Bash/Powershell scripts

In an AzureDevOps pipeline, I have tasks written in Bash/Powershell script.
If I choose to use Inline scrpit, I can use predefined variables directly, such as
cd $(Build.SourcesDirectory)
However, if I choose to use a file path to call a script, I can't use predefined variable directly in the script file. I have to pass the predefined variable to an environment variable in the task definition, like in the example below, so I can use $SourceDirectoy in script.sh,
Is there a better way to call predefined variable direclty in the script?
I believe the variables are also made available to scripts, but the formatting to reference them in the script might depend on script type. Reference the documentation.
Notice that variables are also made available to scripts through
environment variables. The syntax for using these environment
variables depends on the scripting language.
The name is upper-cased, and the . is replaced with the _. This is
automatically inserted into the process environment. Here are some
examples:
Batch script: %VARIABLE_NAME%
PowerShell script: $env:VARIABLE_NAME
Bash script: $VARIABLE_NAME
Predefined variables that contain file paths are translated to the
appropriate styling (Windows style C:\foo\ versus Unix style /foo/)
based on agent host type and shell type. If you are running bash
script tasks on Windows, you should use the environment variable
method for accessing these variables rather than the pipeline variable
method to ensure you have the correct file path styling.

How to pass / store secrets in Azure DevOps Services that can be accessed from unit test

I need to use secret passwords in unit tests execution that are retrieved from Environmental Variables.
Tests are executed by Visual Studio Test task in version 2.*
_networkCredential = new NetworkCredential(Environment.GetEnvironmentVariable("DomainAccountUsername"), Environment.GetEnvironmentVariable("DomainAccountPassword"));
If I set DomainAccountPassword directly from Powershell everything works fine, test ends successfully, but I don't want to show password to other users in my team.
Write-Host "##vso[task.setvariable variable=DomainAccountPassword;]MyExamplePassword"
Passing secret defined in Library Group does not work, causing authentication error.
Write-Host "##vso[task.setvariable variable=DomainAccountPassword;]$(secretPassword)"
How can I pass secret to VSTS task so it can authenticate in external API?
Thank You!
As per Documentation
Secret variables are encrypted at rest with a 2048-bit RSA key. Secrets are available on the agent for tasks and scripts to use (so be careful about who has access to alter your pipeline).
...
Unlike a normal variable, they are not automatically decrypted into environment variables for scripts. You can explicitly map them in, though.
To pass a secret to a script, use the Environment section of the scripting task's input variables.
To use secrets in scripts
Set the variable to secret:
Pass the variable to the script explicitly
And use the new env var in your script by name $env:topshelfPassword
If your pipeline is YAML and not in the Classic Editor
You should not set secret variables in your YAML file. Instead, you should set them in the pipeline editor using the web interface. These variables are scoped to the pipeline in which you set them.
The following example shows how to pass a secret variable called mySecret set in the web interface to a script.
YAML
steps:
- powershell: |
# Using an input-macro:
Write-Host "This works: $(mySecret)"
# Using the env var directly:
Write-Host "This does not work: $env:MYSECRET"
# Using the mapped env var:
Write-Host "This works: $env:MY_MAPPED_ENV_VAR" # Recommended
env:
MY_MAPPED_ENV_VAR: $(mySecret)
Notice how the variable is declared in the web ui as mySecret and what would work for a typical non-secret variable ($env:mySecret) doesn't b/c it's a secret. However, what works in YAML that doesn't work in the Classic experience (I believe I'm correct) is the use of "input-macro" syntax ($(mySecret)).
It seems that Visual Studio Test task cannot get secret in runtime as environmental variable but it can accept secret set as parameter from TestContext
_networkCredential = new NetworkCredential(Environment.GetEnvironmentVariable("DomainAccountUsername"), TestContext.Parameters["DomainAccountPassword"]);
I have added .runsettings file to test project
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<TestRunParameters>
<Parameter name="DomainAccountPassword" value="" />
</TestRunParameters>
</RunSettings>
And in Visual Studio Test task options I have set path to settings file and overrided DomainAccountPassword parameter with my secret.
Visual Studio Test task options

How to set secret environment variable with logging commands in TFS Release

I'm passing a secret Release Task Variable to a PowerShell script and trying to set that value as an environment variable using logging commands so I can use it in other tasks in the same Release. I'm able to do this with a non-secret variable, but not with a secret one.
So, the following is working (I can see it using ls env: and also use it to connect to a tfs instance as a Personal Access Token) when PAT is a non-secret variable:
Inline Script Arguments: -token "$(PAT)"
Param(
[string]$token
)
Write-Host "##vso[task.setvariable variable=API_TOKEN;]$token"
I can only use the environment variable set above if I use it in a subsequent powershell task - it's not available within the task where PAT is passed.
But the following does not seem to be working when PAT is a secret variable:
Inline Script Arguments: -token "$(PAT)"
Param(
[string]$token
)
Write-Host "##vso[task.setvariable variable=API_TOKEN;issecret=true]$token"
(Note: I also tried changing API_TOKEN to something else like MYTOKEN, in case API_TOKEN is reserved, but still don't see MYTOKEN var at all if I do ls env: in a subsequent PowerShell task.)
How can I set an environment variable to a secret value passed from a Release Task, for use by that task or by other tasks in the Release? In other words, when or how can I access the environment variable set by the above-referenced logging commands with issecret=true? (I'm not actually sure I'm setting it properly, since I can't see it, but I assume I am since the non-secret version works.)
Not sure if it matters, but I have ticked the box in the release definition that says "Allow scripts to access OAuth token".
Update
There is more information here, but it's very confusing. I couldn't figure out how to set and access a secret environment variable - I suspect they are not actually environment variables, but in that case I don't understand why the logging commands are needed at all, since we can already pass secret variables to scripts. I was able to workaround by passing the secret variable from the Release Task directly to the PowerShell script, and then from there to other scripts, instead of trying to set/access the value as an environment variable.
Actually the logging command also works for secret variables (what you tried should work). As the logging command usage mentions:
When issecret is set to true, the value of the variable will be saved
as secret and masked out from log. Secret variables are not passed
into tasks as environment variables and must be passed as inputs.
You can use the script echo $(API_TOKEN) instead of ls env: (since secret variables are not showing by the command ls env:), then you will get ********.
And for the use of the secret variable $(API_TOKEN) in your following release tasks, the value should be passed as inputs (as the usage mentions).
There is no way to set a secret environment variable using the mentioned logging commands.

Can Bamboo variables be overridden by a Script task?

I'm interested in using a script task to override one of these Bamboo plan variables for subsequent tasks but I'm not sure if it's possible or how to go about doing so. It appears that Bamboo allows for various levels of variable overrides for Build Plans all the way down to particular branches however they all seem to require defining the values within the Bamboo UI. The problem with this is that it requires admin privileges to modify these variables whereas some of them need to be modified by developers that do not have this level of access. As a solution I want to be able to specify some variable overrides in files that exist in the source repository itself.
Attempt 1: Overriding environment variables
I've attempted to set the environment variables exposed by Bamboo using a Powershell script and specifying something like $env:bamboo_xyz = 'ABC' but it doesn't seem to have an effect past the task context in which it was specified in. Presumably Bamboo must be re-setting the environment variables individually for each task or executing them within their own contexts but it's not clear to me exactly from the documentation.
UPDATE: It appears from some testing that environment variables set in one Script task are not available in subsequent Script tasks in the same Job. This leaves me with no apparent way to override variables based on anything other than hard coded values in Bamboo.
Attempt 2: Using the Bamboo Inject Variables Plugin task
I've tried using the Bamboo Inject Variables Plugin task to override variables but because what appears to be a required namespace parameter it only seems to be able to define new variables and not override existing ones.
Enviroment variables are only valid in the current session. So if bamboo starts one script ( one powershell session ) completes that and then start a new powershell script ( New Session ) the enviroment variable will not be kept.
So then there are a few options, set the variable in each script.
Or set it using registry at the start of the process. And if ncessary set it back to default value in the last step/script.