Modules/businessdev.ALbuild.Apps/Public/Publish-BcTestinyResult.ps1
|
function Publish-BcTestinyResult { <# .SYNOPSIS Publishes a JUnit test result file to Testiny via the Testiny importer CLI. .DESCRIPTION Uploads AL test results (a JUnit XML file, e.g. the one produced by Invoke-BcContainerTest) to Testiny using the official Testiny importer command-line tool. The importer is taken from -ImporterPath if supplied, otherwise downloaded and extracted from -ImporterUrl. Native replacement for the V1 PublishTestResultsTestiny task. For standard pipeline reporting use the built-in Azure DevOps PublishTestResults task instead; this is for teams that mirror results into Testiny. .PARAMETER ResultsFile Path to the JUnit results file to upload. .PARAMETER ApiKey Testiny API key. .PARAMETER ProjectId Testiny project id. .PARAMETER RunId Optional Testiny test-run id to attach the results to. .PARAMETER Format Result format passed to the importer. Default 'junit'. .PARAMETER ImporterUrl URL of the importer download (a .zip). Used when -ImporterPath is not supplied. .PARAMETER ImporterPath Path to an already-available Testiny importer executable (skips the download). .EXAMPLE Publish-BcTestinyResult -ResultsFile .\TestResults.xml -ApiKey $key -ProjectId '42' .OUTPUTS PSCustomObject: ResultsFile, ProjectId, RunId. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ResultsFile, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ApiKey, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ProjectId, [string] $RunId, [ValidateSet('junit', 'xunit')] [string] $Format = 'junit', [string] $ImporterUrl = 'https://app.testiny.io/download/latest/importer/testiny-importer-win.exe.zip', [string] $ImporterPath ) if (-not (Test-Path -LiteralPath $ResultsFile)) { throw "Test results file not found: '$ResultsFile'." } if (-not $PSCmdlet.ShouldProcess($ResultsFile, "Publish to Testiny project $ProjectId")) { return [PSCustomObject]@{ ResultsFile = $ResultsFile; ProjectId = $ProjectId; RunId = $RunId } } $cli = $null if ($ImporterPath) { if (-not (Test-Path -LiteralPath $ImporterPath)) { throw "Testiny importer not found at '$ImporterPath'." } $cli = (Get-Item -LiteralPath $ImporterPath).FullName } else { $tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("testiny-importer-" + [guid]::NewGuid()) $zip = "$tempRoot.zip" Write-ALbuildLog -Level Information "Downloading Testiny importer from '$ImporterUrl'..." Invoke-WebRequest -Uri $ImporterUrl -OutFile $zip -UseBasicParsing -TimeoutSec 120 -ErrorAction Stop Expand-Archive -LiteralPath $zip -DestinationPath $tempRoot -Force $found = Get-ChildItem -LiteralPath $tempRoot -Filter 'testiny-importer-win.exe' -Recurse -File | Select-Object -First 1 if (-not $found) { throw 'Could not locate the Testiny importer executable after extraction.' } $cli = $found.FullName } $arguments = @('--api-key', $ApiKey, '--project', $ProjectId, '--format', $Format, $ResultsFile) if ($RunId) { $arguments += @('--run-id', $RunId) } Invoke-ALbuildProcess -FilePath $cli -Arguments $arguments | Out-Null Write-ALbuildLog -Level Success "Published test results to Testiny project $ProjectId." return [PSCustomObject]@{ ResultsFile = $ResultsFile; ProjectId = $ProjectId; RunId = $RunId } } |