Suppose, I have ADO CI pipeline with UI tests, and suppose thepipeline iterates through a list of devices and tests which can change between pipeline runs like so:
- ${{ each device in parameters.devices }}:
- job: RunUITests_${{ device.uniqueName }}
timeoutInMinutes: 240
variables:
- name: iosDevice
value: ${{ device.deviceType }}
dependsOn: BuildUITests
displayName: 'Run UI Tests - ${{ device.deviceType }} -'
strategy:
matrix:
${{ each testSuite in parameters.testSuites }}:
${{ testSuite }}:
testSuite: ${{ testSuite }}
maxParallel: ${{ parameters.parallelTestSuites }}
steps:
- checkout: self
fetchDepth: 1
- script: |
...
- task: DownloadBuildArtifacts@0
displayName: 'Download Build Artifacts'
inputs:
artifactName: 'BuildTestProducts'
- task: CmdLine@2
...
- task: CmdLine@2
...
- task: Xcode@5
displayName: 'Run UI Tests'
...
useXcpretty: true
xcprettyArgs: '-r junit --output "$(Build.ArtifactStagingDirectory)/$(iosDevice)-$(testSuite)-out.xml"'
- more tasks...
...
These UI tests can and do get parallelized between different agents. One of the jobs will write errors to temp file.
How can I add a final job that will only run once the entire loop - ${{ each device in parameters.devices }}:
with all its nested jobs and tasks gets finished (such that I could send the complete error file to a python script)?
I could normally add dependsOn:
property to the final job, but dependsOn
requires a name that it depends on, and a loop such as - ${{ each device in parameters.devices }}:
doesn't have a static name, and the list of devices and tests can change. Naturally, the jobs within the loop also cannot be depended on to mark a final job because there is no guarantee which of the nested jobs will finish first.
UPD: updated code to include more details
I basically want to do something with the output of the Xcode5
task, so I need my python script to run once after the entire loop is done. I have it working already, but the script gets launched multiple times for each iteration, which is suboptimal. I want to make it better this way.
This did the trick without having to alter anything in the first job's definition:
# Final job
- job: finalJob
dependsOn:
- ${{ each device in parameters.devices }}:
- RunUITests_${{ device.uniqueName }}
condition: always()
steps: