I use a simple CopyTask to copy the unit test build output to the staging folder. The important thing is to set flattenFolders = false
(default) to preserve the folder structure, since the build output contains Nuget packages in different locations that dotnet test will look for when it is run.
The build output in .NET Core+ is a deeply nested folder structure. Therefore, I have create a template that searches for the unit test dll inside the folder structure and returns the containing folder path. I store it in a variable resultfolder
. This approach removes the upper levels of the folder structure so you get a clean artifact to download.
#search bin subfolders to find the content:
- template: ../Tasks/find-containing-folder.yml # Template reference
parameters:
condition: variables['doUnitTest']
folderPathToSearch: '$(Build.SourcesDirectory)\${{ parameters.unitTestProjectName }}\bin\Release'
filename: ${{ parameters.unitTestProjectName }}.dll
- task: CopyFiles@2
displayName: 'Copy unit test project build output to artifact staging folder'
condition: eq(variables['doUnitTest'], true)
inputs:
sourceFolder: '$(resultfolder)'
targetFolder: '$(Build.ArtifactStagingDirectory)/UnitTest'
find-containing-folder.yml template:
# returns the full path of the first folder found containing the file.
# returns the result in a variable called resultfolder.
# condition parameter is a workaround because template references don't allow conditions. Also, string has to be used, booleans don't work.
# (this is used to navigate through the target framework and runtime identifier subfolders to find the output.
# the folders are determined by what the csproj file contains.)
parameters:
- name: condition
type: string
default: true
- name: folderPathToSearch
type: string
- name: filename
type: string
steps:
- task: PowerShell@2
displayName: 'Find containing folder'
condition: eq(${{ parameters.condition }}, true)
inputs:
targetType: 'inline'
script: |
$folderPath = "${{ parameters.folderPathToSearch }}"
Write-Host "Searching folder: " $folderPath
$searchResult = Get-ChildItem -Path $folderPath -Recurse -Filter '${{ parameters.filename }}' -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Directory
Write-Host "searchResult: " $searchResult
if($searchResult -like "*$folderPath*")
{
Write-Host "Found build output folder: " $searchResult
echo "##vso[task.setvariable variable=resultfolder]$searchResult"
}
else
{
Write-Host "Build output not found."
exit 1
}