Check HasLiveTests and HasUnitTests against '-eq $true' (#3333)

* Check HasLiveTests and HasUnitTests against '-eq True'

* Fix spelling

* Switch to clearer [bool]::Parse

* Use TryParse for saefty

* Fix TryParse usage

* Doc cleanup
This commit is contained in:
Alan Zimmer authored and GitHub committed 2026-08-21 17:00:44 -04:00
1 parent 5b3b3395ff
commit 557fca1435
2 files changed
+132 -122

No files matched your search

+128 -120
View File
@@ -45,20 +45,20 @@ $additionalPlatforms = @(
# and Docker builds should use the standard platform definitions.
# https://github.com/microsoft/mcp/issues/1764
@{
name = 'linux-musl-x64-docker'
name = 'linux-musl-x64-docker'
operatingSystem = 'linux'
architecture = 'musl-x64'
native = $false
trimmed = $true
specialPurpose = 'docker'
architecture = 'musl-x64'
native = $false
trimmed = $true
specialPurpose = 'docker'
}
@{
name = 'linux-musl-arm64-docker'
name = 'linux-musl-arm64-docker'
operatingSystem = 'linux'
architecture = 'musl-arm64'
native = $false
trimmed = $true
specialPurpose = 'docker'
architecture = 'musl-arm64'
native = $false
trimmed = $true
specialPurpose = 'docker'
}
)
@@ -67,12 +67,12 @@ if ($IncludeNative) {
# When native builds are shipped, we still may want to build only linux-x64 native in pull requests for pipeline performance
$additionalPlatforms += @{
name = 'linux-x64-native'
name = 'linux-x64-native'
operatingSystem = 'linux'
architecture = 'x64'
native = $true
trimmed = $false
specialPurpose = 'native'
architecture = 'x64'
native = $true
trimmed = $false
specialPurpose = 'native'
}
}
@@ -80,7 +80,8 @@ if ($BuildId -eq 0) {
if ($isPipelineRun) {
LogError 'A non-zero BuildId is required when running in a pipeline.'
$exitCode = 1
} else {
}
else {
$BuildId = 99999
}
}
@@ -90,7 +91,7 @@ if ($isPipelineRun -and !$PublishTarget) {
$exitCode = 1
}
if(!$OutputPath) {
if (!$OutputPath) {
$OutputPath = "$RepoRoot/.work/build_info.json"
}
@@ -123,7 +124,7 @@ function Get-LatestMarketplaceVersion {
)
# flags 914 = IncludeVersions | IncludeFiles | IncludeAssetUri | IncludeStatistics
# This requests version information needed to determine the latest published version
flags = 914
flags = 914
} | ConvertTo-Json -Depth 10
$response = Invoke-RestMethod -Uri $marketplaceUrl -Method Post -Body $body -ContentType "application/json" -ErrorAction SilentlyContinue
@@ -138,7 +139,7 @@ function Get-LatestMarketplaceVersion {
} | ForEach-Object {
[PSCustomObject]@{
Version = $_
Patch = [int]$Matches[1]
Patch = [int]$Matches[1]
}
}
@@ -146,8 +147,8 @@ function Get-LatestMarketplaceVersion {
$maxPatch = ($matchingVersions | Measure-Object -Property Patch -Maximum).Maximum
return [PSCustomObject]@{
LatestVersion = "$MajorVersion.0.$maxPatch"
MaxPatch = $maxPatch
NextPatch = $maxPatch + 1
MaxPatch = $maxPatch
NextPatch = $maxPatch + 1
}
}
}
@@ -167,7 +168,8 @@ function CheckVariable($name) {
LogError "Environment variable $name is not set."
$script:exitCode = 1
return ""
} else {
}
else {
return "Missing-$name"
}
}
@@ -226,7 +228,8 @@ function Get-PathsToTest {
# We can put full paths here because they'll be reduced to relative project directory paths in the "reduce down" step below
@() + $serverProject + $projectReferences
} else {
}
else {
@() + $coreDirectories + $serverDirectories + $toolDirectories
}
@@ -237,12 +240,12 @@ function Get-PathsToTest {
$projectDirectoryPattern = '^(tools|servers|core)/[^/]+'
$normalizedPaths = $paths
| Get-RepoRelativePath -NormalizeSeparators
| Where-Object { $_ -match $projectDirectoryPattern }
| ForEach-Object { $Matches[0] }
| Sort-Object -Unique
| Get-RepoRelativePath -NormalizeSeparators
| Where-Object { $_ -match $projectDirectoryPattern }
| ForEach-Object { $Matches[0] }
| Sort-Object -Unique
if($isPullRequestBuild) {
if ($isPullRequestBuild) {
# Set of files that don't require build or test when changed
$skipFiles = @(
'CHANGELOG.md',
@@ -265,7 +268,8 @@ function Get-PathsToTest {
if ($coreChanged -or $engChanged -or $sharedBuildChanged) {
Write-Host "Core, engineering, or shared build changes detected. Building everything." -ForegroundColor Yellow
$pathsToTest = @()
} else {
}
else {
# Assuming $changedFiles = [
# tools/Azure.Mcp.Tools.Storage/src/someFile.cs <- "Azure.Mcp.Tools.Storage"
# tools/Azure.Mcp.Tools.Monitoring/README.md <- "Azure.Mcp.Tools.Monitoring"
@@ -278,9 +282,9 @@ function Get-PathsToTest {
# For example, updating a markdown file in a service path will still trigger tests for that path.
# Updating a file outside of the defined paths will be seen as a change to the core path.
$changedPaths = @($changedFiles
| Where-Object { $skipFiles -notcontains (Split-Path $_ -Leaf) }
| ForEach-Object { $_ -match $projectDirectoryPattern -and $normalizedPaths -contains $Matches[0] ? $Matches[0] : 'core/Microsoft.Mcp.Core' }
| Sort-Object -Unique)
| Where-Object { $skipFiles -notcontains (Split-Path $_ -Leaf) }
| ForEach-Object { $_ -match $projectDirectoryPattern -and $normalizedPaths -contains $Matches[0] ? $Matches[0] : 'core/Microsoft.Mcp.Core' }
| Sort-Object -Unique)
<# This makes $changedPaths = @(
'tools/Azure.Mcp.Tools.Storage',
@@ -288,10 +292,11 @@ function Get-PathsToTest {
'core/Microsoft.Mcp.Core'
) #>
if($changedPaths.Count -eq 0) {
if ($changedPaths.Count -eq 0) {
Write-Host "No changed, testable paths detected. Defaulting to core." -ForegroundColor Yellow
$changedPaths = @('core/Microsoft.Mcp.Core')
} else {
}
else {
Write-Host "Changed paths detected: $($changedPaths -join ', ')"
}
@@ -328,9 +333,11 @@ function Get-PathsToTest {
$hasTestResources = Test-Path "$rootedTestResourcesPath/test-resources.bicep"
$hasTestsProject = Test-Path "$rootedTestResourcesPath/$projectName.Tests/$projectName.Tests.csproj"
$testProjectDetails = $hasTestsProject ? (& "$($using:PSScriptRoot)/Get-ProjectProperties.ps1" -Path "$rootedTestResourcesPath/$projectName.Tests/$projectName.Tests.csproj") : $null
$hasLiveTests = $hasTestsProject -and $testProjectDetails.HasLiveTests
$result = $false
# Need to parse $testProjectDetails.HasLiveTests and HasUnitTests as they're based on JSON values, therefore will not be a PowerShell boolean
$hasUnitTests = $hasTestsProject -and [bool]::TryParse($testProjectDetails.HasUnitTests, [ref]$result) -and $result
$hasLiveTests = $hasTestsProject -and [bool]::TryParse($testProjectDetails.HasLiveTests, [ref]$result) -and $result
$hasRecordedTests = $hasLiveTests -and (Get-ChildItem $rootedTestResourcesPath -Filter 'assets.json' -Recurse).Count -gt 0
$hasUnitTests = $hasTestsProject -and $testProjectDetails.HasUnitTests
$sourcePath = Join-Path $using:RepoRoot $path "src"
@@ -344,7 +351,7 @@ function Get-PathsToTest {
$resolvedClouds = $sourceProjectDetails.AzureSupportedClouds `
? @($sourceProjectDetails.AzureSupportedClouds -split '[;,] *' | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' })
: $azureSupportedClouds
: $azureSupportedClouds
if ($sourceProjectDetails.AzureSupportedClouds -and ($resolvedClouds | Where-Object { $azureSupportedClouds -notcontains $_ })) {
Write-Error "Project $($sourceProject.FullName) specifies supported Azure clouds that are not in the global supported list: $($sourceProjectDetails.AzureSupportedClouds). Supported clouds must be a subset of $($azureSupportedClouds -join ', ')."
@@ -427,7 +434,7 @@ function Get-ServerDetails {
$serverProperties = @()
foreach($serverProject in $serverProjects) {
foreach ($serverProject in $serverProjects) {
$props = & "$PSScriptRoot/Get-ProjectProperties.ps1" -Path $serverProject
$serverName = $serverProject.BaseName
@@ -539,15 +546,15 @@ function Get-ServerDetails {
if ($excludedPlatforms -notcontains $name) {
$platforms += [ordered]@{
name = $name
artifactPath = "$serverName/$name"
name = $name
artifactPath = "$serverName/$name"
operatingSystem = $os.name
nodeOs = $os.nodeName
dotnetOs = $os.dotnetName
architecture = $arch
extension = $os.extension
native = $false
trimmed = $true
nodeOs = $os.nodeName
dotnetOs = $os.dotnetName
architecture = $arch
extension = $os.extension
native = $false
trimmed = $true
}
}
}
@@ -564,49 +571,49 @@ function Get-ServerDetails {
}
$platforms += [ordered]@{
name = $name
artifactPath = "$serverName/$name"
name = $name
artifactPath = "$serverName/$name"
operatingSystem = $os.name
nodeOs = $os.nodeName
dotnetOs = $os.dotnetName
architecture = $additionalPlatform.architecture
extension = $os.extension
native = $additionalPlatform.native
trimmed = $additionalPlatform.trimmed
specialPurpose = $additionalPlatform.specialPurpose
nodeOs = $os.nodeName
dotnetOs = $os.dotnetName
architecture = $additionalPlatform.architecture
extension = $os.extension
native = $additionalPlatform.native
trimmed = $additionalPlatform.trimmed
specialPurpose = $additionalPlatform.specialPurpose
}
}
$serverProperties += [ordered]@{
name = $serverProject.BaseName
path = $serverProject | Get-RepoRelativePath -NormalizeSeparators
artifactPath = $serverName
version = $version.ToString()
vsixVersion = $vsixVersion
vsixIsPrerelease = $vsixIsPrerelease
releaseTag = "$serverName-$version"
cliName = $props.CliName
assemblyTitle = $props.AssemblyTitle
description = $props.Description
readmeUrl = $props.ReadmeUrl
readmePath = $props.ReadmePath | Get-RepoRelativePath -NormalizeSeparators
packageIcon = $props.PackageIcon | Get-RepoRelativePath -NormalizeSeparators
npmPackageName = $props.NpmPackageName
npmDescription = $props.NpmDescription
npmPackageKeywords = Split-PropertyGroup $props.NpmPackageKeywords
dockerImageName = $props.DockerImageName
dockerDescription = $props.DockerDescription
dnxPackageId = $props.DnxPackageId
dnxDescription = $props.DnxDescription
dnxToolCommandName = $props.DnxToolCommandName
dnxPackageTags = Split-PropertyGroup $props.DnxPackageTags
pypiPackageName = $props.PypiPackageName
pypiDescription = $props.PypiDescription
name = $serverProject.BaseName
path = $serverProject | Get-RepoRelativePath -NormalizeSeparators
artifactPath = $serverName
version = $version.ToString()
vsixVersion = $vsixVersion
vsixIsPrerelease = $vsixIsPrerelease
releaseTag = "$serverName-$version"
cliName = $props.CliName
assemblyTitle = $props.AssemblyTitle
description = $props.Description
readmeUrl = $props.ReadmeUrl
readmePath = $props.ReadmePath | Get-RepoRelativePath -NormalizeSeparators
packageIcon = $props.PackageIcon | Get-RepoRelativePath -NormalizeSeparators
npmPackageName = $props.NpmPackageName
npmDescription = $props.NpmDescription
npmPackageKeywords = Split-PropertyGroup $props.NpmPackageKeywords
dockerImageName = $props.DockerImageName
dockerDescription = $props.DockerDescription
dnxPackageId = $props.DnxPackageId
dnxDescription = $props.DnxDescription
dnxToolCommandName = $props.DnxToolCommandName
dnxPackageTags = Split-PropertyGroup $props.DnxPackageTags
pypiPackageName = $props.PypiPackageName
pypiDescription = $props.PypiDescription
pypiPackageKeywords = Split-PropertyGroup $props.PypiPackageKeywords
platforms = $platforms
mcpRepositoryName = $props.McpRepositoryName
mcpbPlatforms = Split-PropertyGroup $props.McpbPlatforms
serverJsonPath = $props.ServerJsonPath | Get-RepoRelativePath -NormalizeSeparators
platforms = $platforms
mcpRepositoryName = $props.McpRepositoryName
mcpbPlatforms = Split-PropertyGroup $props.McpbPlatforms
serverJsonPath = $props.ServerJsonPath | Get-RepoRelativePath -NormalizeSeparators
}
}
@@ -629,7 +636,7 @@ function Get-BuildMatrices {
# Select-Object -Unique doesn't work here because we're working with hashtable
| Sort-Object { "$($_.architecture)-$(!$_.native)-$($_.specialPurpose)" } -Descending -Unique # x64 before arm64, non-native before native, non-special before special purpose
foreach($platform in $supportedPlatforms) {
foreach ($platform in $supportedPlatforms) {
$arch = $platform.architecture
$legName = $platform.name -replace '\W', '_' # e.g. linux-arm64 or windows-x64-native
@@ -642,13 +649,13 @@ function Get-BuildMatrices {
# All other arm64 targets (windows-arm64, macos-arm64, linux-musl-arm64-docker) cross-compile on x64.
$needsArm64Hardware = $os -eq 'linux' -and $arch -like '*arm64*' -and !$platform.specialPurpose
$pool = switch($os) {
$pool = switch ($os) {
'windows' { $windowsPool }
'linux' { if ($needsArm64Hardware) { $linuxArm64Pool } else { $linuxPool } }
'macos' { $macPool }
}
$vmImage = switch($os) {
$vmImage = switch ($os) {
'windows' { $windowsVmImage }
'linux' { if ($needsArm64Hardware) { $linuxArm64VmImage } else { $linuxVmImage } }
'macos' { $macVmImage }
@@ -673,19 +680,19 @@ function Get-BuildMatrices {
$buildMatricesByArch[$architectureKey][$legName] = [ordered]@{
BuildPlatformName = $platform.name
Pool = $pool
OSVmImage = $vmImage
HostArchitecture = $hostArchitecture
RunUnitTests = $runUnitTests
PublishCoverage = $publishCoverage
Pool = $pool
OSVmImage = $vmImage
HostArchitecture = $hostArchitecture
RunUnitTests = $runUnitTests
PublishCoverage = $publishCoverage
}
if($runUnitTests) {
if ($runUnitTests) {
$smokeTestMatrix[$legName] = [ordered]@{
Pool = $pool
OSVmImage = $vmImage
Pool = $pool
OSVmImage = $vmImage
HostArchitecture = $hostArchitecture
Architecture = $arch
Architecture = $arch
}
}
}
@@ -717,14 +724,14 @@ function Get-ServerMatrix {
@{
Architecture = 'amd64'
PlatformName = 'linux-musl-x64-docker'
Pool = $linuxPool
VMImage = $linuxVmImage
Pool = $linuxPool
VMImage = $linuxVmImage
}
@{
Architecture = 'arm64'
PlatformName = 'linux-musl-arm64-docker'
Pool = $linuxArm64Pool
VMImage = $linuxArm64VmImage
Pool = $linuxArm64Pool
VMImage = $linuxArm64VmImage
}
)
@@ -739,18 +746,18 @@ function Get-ServerMatrix {
$matrixKey = "$($server.name)_$($archConfig.Architecture)"
$serverMatrix[$matrixKey] = [ordered]@{
ServerName = $server.name
CliName = $server.cliName
ArtifactPath = $server.artifactPath
Version = $server.version
ImageName = $imageName
ServerName = $server.name
CliName = $server.cliName
ArtifactPath = $server.artifactPath
Version = $server.version
ImageName = $imageName
ExecutableName = $server.cliName + $executableExtension
DockerLocalTag = $imageName + ":" + $BuildId
# Docker build configuration
Platform = $archConfig.PlatformName
Architecture = $archConfig.Architecture
Pool = $archConfig.Pool
VMImage = $archConfig.VMImage
Platform = $archConfig.PlatformName
Architecture = $archConfig.Architecture
Pool = $archConfig.Pool
VMImage = $archConfig.VMImage
}
}
}
@@ -771,22 +778,23 @@ try {
$commitSha = $isPipelineRun ? (CheckVariable 'BUILD_SOURCEVERSION') : (git rev-parse HEAD)
if ($isPipelineRun) {
foreach($key in $matrices.Keys) {
foreach ($key in $matrices.Keys) {
if ($isPullRequestBuild -and $pathsToTest.Count -eq 0) {
if ($key -match 'BuildMatrices$') {
$emptyByArch = [ordered]@{}
foreach($archKey in @('x64', 'arm64')) {
foreach ($archKey in @('x64', 'arm64')) {
$emptyByArch[$archKey] = @{}
}
$matrices[$key] = $emptyByArch
} else {
}
else {
$matrices[$key] = @{}
}
}
$value = $matrices[$key]
if ($key -match 'BuildMatrices$' -and $value -is [System.Collections.IDictionary]) {
foreach($subKey in $value.Keys) {
foreach ($subKey in $value.Keys) {
$subJson = $value[$subKey] | ConvertTo-Json -Compress
Write-Host "##vso[task.setvariable variable=${key}.${subKey};isOutput=true]$subJson"
}
@@ -798,15 +806,15 @@ try {
}
$buildInfo = [ordered]@{
buildId = $BuildId
publishTarget = $PublishTarget
buildId = $BuildId
publishTarget = $PublishTarget
dynamicPrereleaseVersion = $dynamicPrereleaseVersion
repositoryUrl = 'https://github.com/microsoft/mcp'
branch = $branch
commitSha = $commitSha
servers = $serverDetails
pathsToTest = $pathsToTest
matrices = $matrices
repositoryUrl = 'https://github.com/microsoft/mcp'
branch = $branch
commitSha = $commitSha
servers = $serverDetails
pathsToTest = $pathsToTest
matrices = $matrices
}
Write-Host "Writing build info to $OutputPath"
+4 -2
View File
@@ -45,8 +45,10 @@ function FilterTestProjects {
$testProjects = Get-ChildItem -Path "$RepoRoot" -Recurse -Filter "*Tests.csproj" -File
| Where-Object {
$testProjectDetails = & "$($PSScriptRoot)/Get-ProjectProperties.ps1" -Path $_.FullName
return ($testProjectDetails.HasLiveTests -and $TestType -in @('Live', 'Recorded', 'All')) -or
($testProjectDetails.HasUnitTests -and $TestType -in @('Unit', 'All'))
# Need to parse $testProjectDetails.HasLiveTests and HasUnitTests as they're based on JSON values, therefore will not be a PowerShell boolean
$result = $false
return ([bool]::TryParse($testProjectDetails.HasLiveTests, [ref]$result) -and $result -and $TestType -in @('Live', 'Recorded', 'All')) -or
([bool]::TryParse($testProjectDetails.HasUnitTests, [ref]$result) -and $result -and $TestType -in @('Unit', 'All'))
}
| ForEach-Object { @{
FullName = $_.FullName