AzureCli#2 Task, multiline arguments? - azure-devops

I have a pipeline task as such
I want to pass in a multiline string to arguments, but it is not working.
I see in the docs, both InlineScript and Arguments are both type 'string'... and I can use this multiline syntax on InlineScript?
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-cli-v2?view=azure-pipelines
I don't want to fit all my arguments on 1 line because it expands to a total of 250 characters and is hard for readability.
- task: AzureCLI#2
displayName: 'do thing'
inputs:
azureSubscription: $(myServiceConnection)
scriptType: 'pscore'
scriptLocation: 'scriptPath'
scriptPath: 'myscript.ps1'
arguments: |
-arg1switch
-arg2 aString
-arg3 aString
...
-argN aString

Maybe there can be used something similar to PowerShell#2 syntax?
arguments: > # Use this to avoid newline characters in multiline string
-input1 "Hello"
-input2 "World"
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/powershell-v2?view=azure-pipelines#call-powershell-script-with-multiple-arguments

Related

How to loop through array parameter via Powershell task in Azure DevOps

I have a parameter that consists of two executable paths and I want to loop through it to sign each executable. For this, I use a PowerShell#2 task that is passed via a template in Azure DevOps.
I don't seem to loop correctly through the executable array via any of the methods I've tried in my template code.
What is the best way to loop through the array parameter? Thanks for your help.
Here is my latest code:
parameters:
- name: executableList
type: object
default: []
steps:
- task: PowerShell#2
displayName: 'Sign executables'
inputs:
targetType: 'inline'
script: |
#...more code here
${{ foreach (executable in parameters.executableList) }} {
& $signingExecutable sign /sm /s My /n "Sign Text" /tr http://rfc3161timestamp.globalsign.com/advanced /td sha256 /fd sha256 "$(Pipeline.Workspace)$executable"
          }
Error: While scanning a simple key, could not find expected ':'.
You can try convertToJson function. Small example:
parameters:
- name: myArray
type: object
default:
- "1"
- "2"
- "4"
- "8"
- "16"
steps:
- task: PowerShell#2
displayName: 'Sign executables'
inputs:
targetType: 'inline'
script: |
$mayarrstr= #"
${{ convertToJson(parameters.myArray) }}
"#
$myarr = ConvertFrom-Json $mayarrstr
foreach ($myvalue in $myarr)
{
Write-Host "Value: " $myvalue
}

Get value of pipeline "name" into PowerShell command in Azure pipeline

My azure-pipeline.yml sets a special magical variable called name that causes the pipeline name to be set.
I want to use this value inside a PowerShell script to put this value into a text file as a setting.
variables:
System.Debug: true
versionNumber: '0.0.0'
namePrefix: 'yml_$(versionNumber).'
buildConfiguration: 'Release'
tag: '-yml-$(versionNumber)'
publishBuildArtifactsSubfolder: 'yml\$(Build.Repository.Name)_yml_$(versionNumber).'
name: ${{ variables['namePrefix']}}$(Build.BuildId)
steps:
# Find and replace in files. PowerShell because bash isn't available.
- task: PowerShell#2
displayName: Set version number in environment.*.ts
inputs:
targetType: 'inline'
script: |
Write-Host "Build.DefinitionName is $(Build.DefinitionName)"
Write-Host "env-name is $($env:name)"
Write-Host "name is $($name)"
#Get-ChildItem 'environment.*.ts' -Recurse | ForEach {
# (Get-Content $_ | ForEach { $_ -replace '[[name]]', '${Build.DefinitionName}' }) | Set-Content $_
#}
Is it possible to get the value of name inside the PowerShell script? How? (Is this documented anywhere?)
Workaround
It appears to be impossible to get the special name thing, therefore set a variable with the same value.
variables:
System.Debug: true
versionNumber: '0.0.0'
namePrefix: 'yml_$(versionNumber).'
buildConfiguration: 'Release'
tag: '-yml-$(versionNumber)'
publishBuildArtifactsSubfolder: 'yml\$(Build.Repository.Name)_yml_$(versionNumber).'
name: ${{ variables['namePrefix']}}$(Build.BuildId)
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Write-Host "name is $($name)"
Yes, the name it's a pre-defined variable Build.BuildNumber, so just use $(Build.BuildNumber).

What is the correct way to access ADO yaml parameters in bash script?

I have a template that is called and passed a set of parameters. I would like to use these in a bash script. When I define an inline bash script I can easily print the parameters out with ${{ parameter.foo }}. However if I define a bash script as a file and call it I'm unable to access the parameters.
Here is a sample template, 'Inline Test' will spit out the parameters where as 'File Test' wont. So far two possible solutions I can see are, defining the parameter value as a 'task variable' and accessing it as $foo (example Inline Test), or potentially pass the parameter in as an argument to the 'File Test' task (example File Test 2). Is there an option to access yaml template parameters in an existing bash script from file and not one that is defined inline?
parameters:
- name: webappName #webappName
type: string
default: webappName #set default for testing
- name: resourceGroup #resourceGroup
type: string
default: resourceGroupName #set default for testing
- name: subscription #subscription
type: string
default: s #set default for testing
- name: preprod
type: boolean
default: false #default to false
- name: env
type: string
default: test
- name: role
type: string
default: s
steps:
- checkout: 'x' #the repo that test.sh lives in
- task: Bash#3
inputs:
displayName: 'Inline test'
targetType: 'inline'
script: |
echo "-----"
echo ${{ parameters.webappName }}
echo "-----"
echo ${{ parameters.resourceGroup }}
echo "-----"
echo ${{ parameters.subscription }}
echo "-----"
echo ${{ parameters.preprod }}
echo "-----"
echo ${{ parameters.env }}
echo "-----"
echo ${{ parameters.role }}
echo "-----"
echo "##vso[task.setvariable variable=TESTROLE]${{ parameters.role }}"
echo "-----"
- task: Bash#3
displayName: 'File test'
inputs:
filePath: './test.sh'
- task: Bash#3
displayName: 'File test 2'
inputs:
arguments: ${{ parameters.role }}
filePath: './test.sh'
AzDev just substitute values in the inline scripts, so the ${{ name }} is some kind of placeholder. And AzDev doesn't read script files, so doesn't substitute values there.
You can use environment variables for bash task:
- task: Bash#3
displayName: 'File test 2'
inputs:
filePath: './test.sh'
env:
APP_ROLE: ${{ parameters.role }}
And then you could use this env variable in your script file:
echo $APP_ROLE

How to pass object to overrideParameters for ARM deployment from yaml pipeline

I have a yaml pipeline that executes an inline script and needs to pass the output object from that script to an ARM template but I cannot find any examples around which pass an object, only individual strings.
The yaml script:
- task: AzurePowerShell#4
displayName: 'Get CosmosDB Consistency'
inputs:
azureSubscription: 'ado-test'
scriptType: 'inlineScript'
azurePowerShellVersion: LatestVersion
inline: |
Install-Module -Name Az.CosmosDB -RequiredVersion 0.1.6 -AllowClobber -Force
Import-Module Az.CosmosDB
$cosmosConsistency = (Get-AzCosmosDBAccount -ResourceGroupName $(domain)-${{ parameters.environment }} -Name $(domain)-${{ parameters.environment }}).ConsistencyPolicy
Write-Host "##vso[task.setvariable variable=cosmosConsistency;isOutput=true]$cosmosConsistency"
name: 'cosmosConsistency'
The output object looks like this: {"DefaultConsistencyLevel":"Session","MaxStalenessPrefix":100,"MaxIntervalInSeconds":5}
The ARM deployment with param override:
- task: AzureResourceGroupDeployment#2
displayName: 'Deploy: Main resources'
inputs:
azureSubscription: 'ado-test'
resourceGroupName: '$(domain)-${{ lower(parameters.environment) }}'
location: 'West Europe'
csmFile: '$(Build.SourcesDirectory)/src/resources.json'
csmParametersFile: '$(Build.SourcesDirectory)/src/resources.parameters.json'
overrideParameters: '-cosmosConsistency $(cosmosConsistency))'
Param definition in ARM template:
cosmosConsistency": {
"type": "object",
"metadata": {
"description": "The Cosmos DB consistency parameters object"
}
},
The error I am getting is that param is string but object was expected so there is either something wrong with my overrideParameters definition or the param definition in the ARM template.
Can someone pls assist with the correct syntax?
If I pass all 3 values separately as 3 different string params it works but is messy and I rather pass the whole object instead.
To override object type parameters use stringified JSON objects.
For example, -options ["option1"] -map {"key1":"value1" }.
If there is a gap between "key1" and "value1" like "key": "value1", it will give an error "mapping values are not allowed in this context". So correct syntax would be {"key1":"value1"}
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-resource-group-deployment?view=azure-devops

Azure DevOps - Pass Powershell list variable to yml template array

I want to generate a list in a Powershell task as an output variable and use it in a yml template as a list to perform a loop for a task.
#Main
- task: PowerShell#2
condition: succeeded()
displayName: "Create a list"
inputs:
targetType: 'inline'
script: |
$myList = New-Object System.Collections.ArrayList
$myList.Add("wow")
Write-Output ("##vso[task.setvariable variable=MyList;]$myList")
- template: myRandomListTaskTemplate.yml
parameters:
MyList: $(MyList)
#Template
parameters:
MyList: []
steps:
- ${{ each myList in parameters.MyList }}:
- task: PowerShell#2
condition: succeeded()
displayName: "WOW a list"
inputs:
targetType: 'inline'
script: |
Write-Host("A list string: ${{ myList }}")
I am getting the error
Expected a sequence or mapping. Actual value '$(MyList)'
Note: The Powershell Task in the Template is just an example, it can be other Tasks that are not Powershell related (example: DotNetCoreCLI#2)
It will not work as you expect.
$myList = New-Object System.Collections.ArrayList
$myList.Add("wow")
Write-Output ("##vso[task.setvariable variable=MyList;]$myList")
You are not going here to have an array. Once you assign this to variable it will be a plain string. This is why you are getting this error.
If you run this:
- template: myRandomListTaskTemplate2.yml
parameters:
MyList:
- item1
- item2
all went fine. However, it is not possible to do what you at the moment.
Please check this developer community topic.