Reputation: 21
I have written a powershell script task under a job in same stage to find the $initialFile from my below script and perfrom few operations.I would like to set a output variable of my powershell script. so that I can use it as a condition in my following copy & publish task. In summary I would like to perform ProcessTestResults only when powershell task finds $initialFile Here is my yaml file:
Stage: Azure
-jobs:
-job: A
- task: PowerShell@2
displayName: 'find failed tests and copy them'
name: passOutput
inputs:
workingDirectory: $(Pipeline.Workspace)/$(Build.BuildId)/Tests/E2EAutomationTests/Logs
targetType: 'inline'
script: |
Write-Host "Current Working Directory:"
Write-Host (Get-Location)
Write-Host "Contents of the Current Directory:"
Get-ChildItem
$currentDirectory = Get-Location
$initialFileName = "failedTests.txt"
$targetFolder = ".\FailedTestCopy"
$folders = Get-ChildItem -Path $currentDirectory -Directory
$script= foreach ($folder in $folders) {
$folderPath = $folder.FullName
$aTxtFile = Get-ChildItem -Path $folderPath -Filter $initialFileName -File | Select-Object -First 1
if (-not $aTxtFile) {
throw "No '$initialFileName' found in the folder '$($folder.Name)'."
} else {
$destination = Join-Path -Path $targetFolder -ChildPath Write-Host "Destination directory created: $destination"
}
}
- job: ProcessTestResults
displayName: 'Process Test Results'
dependsOn: A
condition: and(succeeded(), eq(dependencies.E2E_test.outputs['passOutput.script'], 'true'))
steps:
- task: CopyFiles@2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/${{ parameters.targetfolder }}/TestArtifacts'
inputs:
sourceFolder: '$(Pipeline.Workspace)\$(Build.BuildId)\Tests\E2EAutomationTests\Logs\FailedTestCopy'
contents: |
**/failedTests.txt
**/*.txt
**/*.etl
TargetFolder: '$(Build.ArtifactStagingDirectory)/${{ parameters.targetfolder }}/TestResults'
OverWrite: true
continueOnError: true
I have tried using the following conditions in copy task condition: failed() condition: and(succeeded(), eq(dependencies.E2E_test.outputs['passOutput.script'], 'true')) But the evaluation is coming as null
Output of ProcessTestResults Job : Expanded: and(True, eq(Null, 'true')) Result: False
Upvotes: 0
Views: 1357
Reputation: 8082
I would like to set a output variable of my powershell script. so that I can use it as a condition in my following copy & publish task.
Step1:
You need to using logging command to set variable (with isOutput=true
) in your powershell script in your first job. For example, use $initialFileFound
value to indicate if the file is found or not.
Write-Host "##vso[task.setvariable variable=initialFileFound;isoutput=true]yes"
You can use it in if else in your powershell task(for example)
- task: PowerShell@2
displayName: 'find failed tests and copy them'
name: passOutput
inputs:
workingDirectory: $(Pipeline.Workspace)/$(Build.BuildId)/Tests/E2EAutomationTests/Logs
targetType: 'inline'
script: |
......
if (-not $aTxtFile) {
Write-Host "No '$initialFileName' found in the folder '$($folder.Name)'."
Write-Host "##vso[task.setvariable variable=initialFileFound;isoutput=true]no"
} else {
$destination = Join-Path -Path $targetFolder -ChildPath
Write-Host "Destination directory created: $destination"
Write-Host "##vso[task.setvariable variable=initialFileFound;isoutput=true]yes"
}
}
Step2:
In next job, invoke the output variable in condition expression.
- job: ProcessTestResults
displayName: 'Process Test Results'
dependsOn: A
condition: eq(dependencies.A.outputs['passOutput.initialFileFound'], 'yes') #map initialFileFound and check the value
steps:
.....
If file is NOT found, the next job is skipped:
You can find more details in official doc Use the output variable from a job in a condition in a subsequent job.
Edit:
Fix the stage, job syntax error.
The default working directory is $(Pipeline.Workspace)/s
(with s), also $(Build.BuildId)
points to build id which will be changed
for every build. Do you generate the directory dynamically in the build? If not, please double confirm if the working directory on your yaml is expected. For test, I have folder structure as below in repo:
You use foreach
to check the file in every folder, it will override the variable value if you define variable in if&else expression. I add break
to jump out once the file is found. Please consider your real situation about this.
I add a step to check the variable value, to confirm it has value.
The full yaml:
trigger: none
pool:
vmImage: Windows-latest
stages:
- stage: Azure
jobs:
- job: A
steps:
- task: PowerShell@2
displayName: 'find failed tests and copy them'
name: passOutput
inputs:
workingDirectory: '$(Pipeline.Workspace)/s/TestFolder1'
targetType: 'inline'
script: |
Write-Host "Current Working Directory:"
Write-Host (Get-Location)
Write-Host "Contents of the Current Directory:"
Get-ChildItem
$currentDirectory = Get-Location
$initialFileName = "failedTests.txt"
$targetFolder = ".\FailedTestCopy"
$folders = Get-ChildItem -Path $currentDirectory -Directory
foreach ($folder in $folders) {
$folderPath = $folder.FullName
$aTxtFile = Get-ChildItem -Path $folderPath -Filter $initialFileName -File -Recurse
if (-not $aTxtFile) {
Write-Host "No '$initialFileName' found in the folder '$($folder.Name)'."
Write-Host "##vso[task.setvariable variable=initialFileFound;isoutput=true]no"
} else {
$destination = Join-Path -Path $targetFolder -ChildPath $folder.Name
New-Item -ItemType Directory -Path $destination | Out-Null
Write-Host "Destination directory created: $destination"
Write-Host "##vso[task.setvariable variable=initialFileFound;isoutput=true]yes"
break # add break here if the file is found, otherwise it will check for all folders if the file exists, and overwrite the variable.
}
}
- script: |
echo $(passOutput.initialFileFound)
displayName: Checkthevalue
- job: ProcessTestResults
displayName: 'Process Test Results'
dependsOn: A
condition: eq(dependencies.A.outputs['passOutput.initialFileFound'], 'yes')
steps:
- script: echo test
File found:
File Not found:
Upvotes: 0