Azure / azure-devops-cli-extension

Azure DevOps Extension for Azure CLI
https://docs.microsoft.com/en-us/cli/azure/ext/azure-devops/?view=azure-cli-latest
MIT License
632 stars 242 forks source link

[Bug] "Failed to load python executable" when setting variable-group variable when value contains certain patterns #1020

Open cmielke opened 4 years ago

cmielke commented 4 years ago

Describe the bug When I use Azure CLI from PowerShell, I am receiving a "Failed to load python executable" error when I attempt to create or update a variable group variable when the value of the variable contains a "-" (dash) character and ends with ")" (closing paren).

Note that this only happens when I run from PowerShell. When I run from CMD it works without error.

To Reproduce Azure Cli Version: 2.7.0

Azure-Devops extension version: 0.18.0

Steps to reproduce the behavior:

  1. login using az login
  2. setup defaults.
  3. Run command:
    az pipelines variable-group variable create --group-id <your group id> --name my.variable.name --value '$(some-text)'

    OR

    az pipelines variable-group variable create --group-id <your group id> --name my.variable.name --value "`$(some-text)"
  4. Notice how the variable actually gets added, but the closing paren is removed. You will also see the error "Failed to load python executable." The same thing happens for the variable-group variable update command.

Expected behavior The variable is added or updated with the specified value including the closing paren and I do not receive an error.

Screenshots image

Debug logs debug.txt

Additional context Note that if I remove the dash from the variable value, then the following command works as expected;

az pipelines variable-group variable create --group-id <your group id> --name my.variable.name --value '$(some text)'
ntammadge commented 4 years ago

I have also encountered this issue, but my use case is queuing a pipeline while updating a variable with a ) in the value.

To Reproduce azure-cli 2.11.1 azure-devops 0.18.0

Open PowerShell Run:

Get-Content AzureAuth.txt | az devops login $pipeline = Invoke-Expression "az pipelines build queue --organization https://dev.azure.com/myOrg/ --project 'My Project' --definition-id $id --branch master --variables ""A_VAR_NAME=some(value)""" | ConvertFrom-Json

Produced error:

ConvertFrom-Json : Invalid JSON primitive: :\dev\bat>echo Failed to load python executable. Failed to load python executable. C:\dev\bat>exit /b 1

Expected behavior The variable value should get parsed correctly with a ) and an error should not get output to the console.

Debug logs From running the command with --debug I found the following entry in the debug log

Command arguments: ['pipelines', 'build', 'queue', '--debug', '--organization', 'https://dev.azure.com/myOrg/', '--project', 'My Project', '--definition-id', 'id', '--branch', 'master', '--variables', 'A_VAR_NAME=some(value']

If needed I can acquire a full debug log and upload it here. After skimming it, this looked like the relevant piece given that this is the first line out of the debug log output and the variable value was incorrect.

Additional context Inspecting the raw output of the Invoke-Expression call shows what appears to be sane JSON, aside from the missing ) on the variable value. Calling the Invoke-Expression kicks off the pipeline, so it appears to just be a parsing error rather than a whole operation failure.

I can confirm that simply removing the ) character causes the command to execute successfully, but obviously not the pipeline because the variable value is incorrect. Interestingly, the command arguments line from the debug log is the same regardless of if the ) is included.

EntityAdam commented 3 years ago

Stumbled here looking for a solution.

After a few hours of research I found a fix, which explained in depth here: https://github.com/Azure/azure-cli/blob/dev/doc/quoting-issues-with-powershell.md

In short, if you have

--value '$(some text)'

You are quoting it once for PowerShell, but it is then interpreted again by the Windows Command Line.

The fix is to apply additional quotes;

--value '"$(some text)"'
steven-hyland commented 2 years ago

I also stumbled here looking for a solution. In my case I was trying to run the command az devops security group list --organization $($Organization) --project '$($ProjectName)' | convertfrom-json in a PowerShell script, where the value of $ProjectName happened to be "Prosight(GWP)". I would get an error back from the ADO API that project "Prosight(GWP" did not exist.

Using @EntityAdam's fix resolved the problem - thanks for leaving the workaround! New working command is az devops security group list --organization $($Organization) --project '"$($ProjectName)"' | convertfrom-json

zemien commented 2 years ago

I encountered this issue too, while trying to set Function app settings that use a @KeyVault reference (it has closing parantheses).

The additional quotes workaround works, but it does not make sense to code reviewers and I have to explain myself over and over again.

anstein-msft commented 2 months ago

The suggest solution (surrounding the double quotes with single quotes) does work, but does not work for scenarios where you need to substitute a variable to the command with string interpolation.

e.g., assuming the variables referenced are defined:

az functionapp config appsettings set --name ${functionAppName} --resource-group ${resourceGroup} --settings '"whateverKeyName=@Microsoft.KeyVault(SecretUri=https://${keyvaultName}.vault.azure.net/secrets/whateverKeyName/)"'

This command does create or update the specified keyvault, but the value becomes a literal value without substitution, i.e. it becomes :

@Microsoft.KeyVault(SecretUri=https://${keyvaultName}.vault.azure.net/secrets/whateverKeyName/)

In cases like this, I would suggest switching to the Powershell version of the Azure CLI which doesn't have this issue:

Update-AzFunctionAppSetting -Name ${functionAppName} -ResourceGroupName ${resourceGroup} -AppSetting @{"whateverKeyName" = "@Microsoft.KeyVault(SecretUri=https://${keyvaultName}.vault.azure.net/secrets/whateverKeyName/)"}